From c52bfae088a4553878aa09eb402fc8b83b48ba4f Mon Sep 17 00:00:00 2001 From: plumedbot Date: Mon, 10 Jun 2024 08:19:25 +0000 Subject: [PATCH] Update to plumed/plumed2@87ab2b0 --- .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 | 753 + .../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 | 2088 ++ .../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 | 1365 + .../molfile/endianswap.h.func-sort-c.html | 89 + coverage-libs/molfile/endianswap.h.func.html | 89 + coverage-libs/molfile/endianswap.h.gcov.html | 292 + .../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 | 929 + 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 | 109 + coverage/adjmat/ClusterDiameter.cpp.func.html | 109 + coverage/adjmat/ClusterDiameter.cpp.gcov.html | 207 + .../ClusterDistribution.cpp.func-sort-c.html | 105 + .../adjmat/ClusterDistribution.cpp.func.html | 105 + .../adjmat/ClusterDistribution.cpp.gcov.html | 237 + .../ClusterProperties.cpp.func-sort-c.html | 105 + .../adjmat/ClusterProperties.cpp.func.html | 105 + .../adjmat/ClusterProperties.cpp.gcov.html | 198 + .../adjmat/ClusterSize.cpp.func-sort-c.html | 109 + coverage/adjmat/ClusterSize.cpp.func.html | 109 + coverage/adjmat/ClusterSize.cpp.gcov.html | 190 + .../ClusterWithSurface.cpp.func-sort-c.html | 137 + .../adjmat/ClusterWithSurface.cpp.func.html | 137 + .../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 | 105 + .../adjmat/ContactAlignedMatrix.cpp.func.html | 105 + .../adjmat/ContactAlignedMatrix.cpp.gcov.html | 200 + .../adjmat/ContactMatrix.cpp.func-sort-c.html | 109 + coverage/adjmat/ContactMatrix.cpp.func.html | 109 + coverage/adjmat/ContactMatrix.cpp.gcov.html | 227 + .../adjmat/DFSClustering.cpp.func-sort-c.html | 105 + coverage/adjmat/DFSClustering.cpp.func.html | 105 + coverage/adjmat/DFSClustering.cpp.gcov.html | 238 + .../adjmat/DumpGraph.cpp.func-sort-c.html | 109 + coverage/adjmat/DumpGraph.cpp.func.html | 109 + coverage/adjmat/DumpGraph.cpp.gcov.html | 191 + .../adjmat/HbondMatrix.cpp.func-sort-c.html | 113 + coverage/adjmat/HbondMatrix.cpp.func.html | 113 + coverage/adjmat/HbondMatrix.cpp.gcov.html | 309 + .../MatrixColumnSums.cpp.func-sort-c.html | 101 + .../adjmat/MatrixColumnSums.cpp.func.html | 101 + .../adjmat/MatrixColumnSums.cpp.gcov.html | 199 + .../adjmat/MatrixRowSums.cpp.func-sort-c.html | 101 + coverage/adjmat/MatrixRowSums.cpp.func.html | 101 + coverage/adjmat/MatrixRowSums.cpp.gcov.html | 185 + .../adjmat/OutputCluster.cpp.func-sort-c.html | 117 + coverage/adjmat/OutputCluster.cpp.func.html | 117 + coverage/adjmat/OutputCluster.cpp.gcov.html | 310 + .../adjmat/SMACMatrix.cpp.func-sort-c.html | 105 + coverage/adjmat/SMACMatrix.cpp.func.html | 105 + coverage/adjmat/SMACMatrix.cpp.gcov.html | 232 + coverage/adjmat/Sprint.cpp.func-sort-c.html | 105 + coverage/adjmat/Sprint.cpp.func.html | 105 + coverage/adjmat/Sprint.cpp.gcov.html | 318 + .../TopologyMatrix.cpp.func-sort-c.html | 117 + coverage/adjmat/TopologyMatrix.cpp.func.html | 117 + 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 | 125 + coverage/analysis/Average.cpp.func.html | 125 + 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 | 105 + coverage/analysis/Committor.cpp.func.html | 105 + 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 | 117 + ...EuclideanDissimilarityMatrix.cpp.func.html | 117 + ...EuclideanDissimilarityMatrix.cpp.gcov.html | 223 + ...FarthestPointSampling.cpp.func-sort-c.html | 101 + .../FarthestPointSampling.cpp.func.html | 101 + .../FarthestPointSampling.cpp.gcov.html | 168 + .../analysis/Histogram.cpp.func-sort-c.html | 137 + coverage/analysis/Histogram.cpp.func.html | 137 + 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 | 101 + .../analysis/LandmarkStaged.cpp.func.html | 101 + .../analysis/LandmarkStaged.cpp.gcov.html | 212 + .../OutputColvarFile.cpp.func-sort-c.html | 105 + .../analysis/OutputColvarFile.cpp.func.html | 105 + .../analysis/OutputColvarFile.cpp.gcov.html | 203 + .../OutputPDBFile.cpp.func-sort-c.html | 105 + coverage/analysis/OutputPDBFile.cpp.func.html | 105 + coverage/analysis/OutputPDBFile.cpp.gcov.html | 177 + ...ntDissimilarityMatrix.cpp.func-sort-c.html | 105 + .../PrintDissimilarityMatrix.cpp.func.html | 105 + .../PrintDissimilarityMatrix.cpp.gcov.html | 159 + .../ReadAnalysisFrames.cpp.func-sort-c.html | 117 + .../analysis/ReadAnalysisFrames.cpp.func.html | 117 + .../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 | 137 + .../ReadDissimilarityMatrix.cpp.func.html | 137 + .../ReadDissimilarityMatrix.cpp.gcov.html | 242 + .../ReselectLandmarks.cpp.func-sort-c.html | 101 + .../analysis/ReselectLandmarks.cpp.func.html | 101 + .../analysis/ReselectLandmarks.cpp.gcov.html | 151 + .../SelectRandomFrames.cpp.func-sort-c.html | 101 + .../analysis/SelectRandomFrames.cpp.func.html | 101 + .../analysis/SelectRandomFrames.cpp.gcov.html | 157 + .../SelectWithStride.cpp.func-sort-c.html | 101 + .../analysis/SelectWithStride.cpp.func.html | 101 + .../analysis/SelectWithStride.cpp.gcov.html | 139 + .../WhamHistogram.cpp.func-sort-c.html | 97 + coverage/analysis/WhamHistogram.cpp.func.html | 97 + coverage/analysis/WhamHistogram.cpp.gcov.html | 199 + .../analysis/WhamWeights.cpp.func-sort-c.html | 97 + coverage/analysis/WhamWeights.cpp.func.html | 97 + 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 | 109 + coverage/annfunc/ANN.cpp.func.html | 109 + 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 | 101 + coverage/bias/ABMD.cpp.func.html | 101 + 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 | 171 + coverage/bias/Bias.h.func-sort-c.html | 77 + coverage/bias/Bias.h.func.html | 77 + coverage/bias/Bias.h.gcov.html | 158 + coverage/bias/BiasValue.cpp.func-sort-c.html | 101 + coverage/bias/BiasValue.cpp.func.html | 101 + coverage/bias/BiasValue.cpp.gcov.html | 194 + .../ExtendedLagrangian.cpp.func-sort-c.html | 105 + .../bias/ExtendedLagrangian.cpp.func.html | 105 + .../bias/ExtendedLagrangian.cpp.gcov.html | 344 + coverage/bias/External.cpp.func-sort-c.html | 101 + coverage/bias/External.cpp.func.html | 101 + coverage/bias/External.cpp.gcov.html | 257 + coverage/bias/LWalls.cpp.func-sort-c.html | 101 + coverage/bias/LWalls.cpp.func.html | 101 + coverage/bias/LWalls.cpp.gcov.html | 225 + coverage/bias/MaxEnt.cpp.func-sort-c.html | 129 + coverage/bias/MaxEnt.cpp.func.html | 129 + coverage/bias/MaxEnt.cpp.gcov.html | 563 + coverage/bias/MetaD.cpp.func-sort-c.html | 197 + coverage/bias/MetaD.cpp.func.html | 197 + coverage/bias/MetaD.cpp.gcov.html | 2390 ++ .../bias/MovingRestraint.cpp.func-sort-c.html | 101 + coverage/bias/MovingRestraint.cpp.func.html | 101 + coverage/bias/MovingRestraint.cpp.gcov.html | 343 + coverage/bias/PBMetaD.cpp.func-sort-c.html | 145 + coverage/bias/PBMetaD.cpp.func.html | 145 + coverage/bias/PBMetaD.cpp.gcov.html | 1289 + coverage/bias/Restraint.cpp.func-sort-c.html | 101 + coverage/bias/Restraint.cpp.func.html | 101 + 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 | 134 + 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 | 101 + coverage/bias/ReweightBias.cpp.func.html | 101 + coverage/bias/ReweightBias.cpp.gcov.html | 175 + .../bias/ReweightMetad.cpp.func-sort-c.html | 101 + coverage/bias/ReweightMetad.cpp.func.html | 101 + coverage/bias/ReweightMetad.cpp.gcov.html | 172 + ...htTemperaturePressure.cpp.func-sort-c.html | 101 + .../ReweightTemperaturePressure.cpp.func.html | 101 + .../ReweightTemperaturePressure.cpp.gcov.html | 343 + .../bias/ReweightWham.cpp.func-sort-c.html | 117 + coverage/bias/ReweightWham.cpp.func.html | 117 + coverage/bias/ReweightWham.cpp.gcov.html | 254 + coverage/bias/UWalls.cpp.func-sort-c.html | 101 + coverage/bias/UWalls.cpp.func.html | 101 + 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/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 | 113 + coverage/cltools/Driver.cpp.func.html | 113 + coverage/cltools/Driver.cpp.gcov.html | 1172 + .../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 | 427 + .../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 | 198 + 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 | 149 + coverage/cltools/SimpleMD.cpp.func.html | 149 + coverage/cltools/SimpleMD.cpp.gcov.html | 693 + .../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 | 214 + coverage/cltools/index-sort-l.html | 214 + coverage/cltools/index.html | 214 + 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 | 390 + coverage/colvar/Angle.cpp.func-sort-c.html | 101 + coverage/colvar/Angle.cpp.func.html | 101 + coverage/colvar/Angle.cpp.gcov.html | 225 + coverage/colvar/Cell.cpp.func-sort-c.html | 101 + coverage/colvar/Cell.cpp.func.html | 101 + coverage/colvar/Cell.cpp.gcov.html | 186 + coverage/colvar/Constant.cpp.func-sort-c.html | 101 + coverage/colvar/Constant.cpp.func.html | 101 + coverage/colvar/Constant.cpp.gcov.html | 210 + .../colvar/ContactMap.cpp.func-sort-c.html | 105 + coverage/colvar/ContactMap.cpp.func.html | 105 + coverage/colvar/ContactMap.cpp.gcov.html | 403 + .../colvar/Coordination.cpp.func-sort-c.html | 101 + coverage/colvar/Coordination.cpp.func.html | 101 + 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 | 101 + coverage/colvar/DHEnergy.cpp.func.html | 101 + coverage/colvar/DHEnergy.cpp.gcov.html | 221 + coverage/colvar/DRMSD.cpp.func-sort-c.html | 101 + coverage/colvar/DRMSD.cpp.func.html | 101 + coverage/colvar/DRMSD.cpp.gcov.html | 270 + coverage/colvar/Dimer.cpp.func-sort-c.html | 105 + coverage/colvar/Dimer.cpp.func.html | 105 + coverage/colvar/Dimer.cpp.gcov.html | 394 + coverage/colvar/Dipole.cpp.func-sort-c.html | 101 + coverage/colvar/Dipole.cpp.func.html | 101 + coverage/colvar/Dipole.cpp.gcov.html | 235 + coverage/colvar/Distance.cpp.func-sort-c.html | 101 + coverage/colvar/Distance.cpp.func.html | 101 + coverage/colvar/Distance.cpp.gcov.html | 306 + coverage/colvar/EEFSolv.cpp.func-sort-c.html | 117 + coverage/colvar/EEFSolv.cpp.func.html | 117 + coverage/colvar/EEFSolv.cpp.gcov.html | 1317 + coverage/colvar/ERMSD.cpp.func-sort-c.html | 101 + coverage/colvar/ERMSD.cpp.func.html | 101 + coverage/colvar/ERMSD.cpp.gcov.html | 292 + coverage/colvar/Energy.cpp.func-sort-c.html | 109 + coverage/colvar/Energy.cpp.func.html | 109 + coverage/colvar/Energy.cpp.gcov.html | 193 + coverage/colvar/ExtraCV.cpp.func-sort-c.html | 109 + coverage/colvar/ExtraCV.cpp.func.html | 109 + coverage/colvar/ExtraCV.cpp.gcov.html | 181 + coverage/colvar/Fake.cpp.func-sort-c.html | 101 + coverage/colvar/Fake.cpp.func.html | 101 + coverage/colvar/Fake.cpp.gcov.html | 200 + coverage/colvar/GHBFIX.cpp.func-sort-c.html | 101 + coverage/colvar/GHBFIX.cpp.func.html | 101 + coverage/colvar/GHBFIX.cpp.gcov.html | 295 + coverage/colvar/Gyration.cpp.func-sort-c.html | 101 + coverage/colvar/Gyration.cpp.func.html | 101 + coverage/colvar/Gyration.cpp.gcov.html | 449 + .../colvar/MultiRMSD.cpp.func-sort-c.html | 101 + coverage/colvar/MultiRMSD.cpp.func.html | 101 + coverage/colvar/MultiRMSD.cpp.gcov.html | 287 + coverage/colvar/PCARMSD.cpp.func-sort-c.html | 101 + coverage/colvar/PCARMSD.cpp.func.html | 101 + coverage/colvar/PCARMSD.cpp.gcov.html | 340 + coverage/colvar/PathMSD.cpp.func-sort-c.html | 97 + coverage/colvar/PathMSD.cpp.func.html | 97 + coverage/colvar/PathMSD.cpp.gcov.html | 206 + .../colvar/PathMSDBase.cpp.func-sort-c.html | 101 + coverage/colvar/PathMSDBase.cpp.func.html | 101 + coverage/colvar/PathMSDBase.cpp.gcov.html | 409 + .../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 | 101 + coverage/colvar/Position.cpp.func.html | 101 + coverage/colvar/Position.cpp.gcov.html | 254 + .../ProjectionOnAxis.cpp.func-sort-c.html | 101 + .../colvar/ProjectionOnAxis.cpp.func.html | 101 + .../colvar/ProjectionOnAxis.cpp.gcov.html | 246 + .../colvar/PropertyMap.cpp.func-sort-c.html | 97 + coverage/colvar/PropertyMap.cpp.func.html | 97 + coverage/colvar/PropertyMap.cpp.gcov.html | 227 + .../colvar/Puckering.cpp.func-sort-c.html | 109 + coverage/colvar/Puckering.cpp.func.html | 109 + coverage/colvar/Puckering.cpp.gcov.html | 497 + coverage/colvar/RMSD.cpp.func-sort-c.html | 101 + coverage/colvar/RMSD.cpp.func.html | 101 + coverage/colvar/RMSD.cpp.gcov.html | 315 + coverage/colvar/Template.cpp.func-sort-c.html | 101 + coverage/colvar/Template.cpp.func.html | 101 + coverage/colvar/Template.cpp.gcov.html | 191 + coverage/colvar/Torsion.cpp.func-sort-c.html | 101 + coverage/colvar/Torsion.cpp.func.html | 101 + coverage/colvar/Torsion.cpp.gcov.html | 272 + coverage/colvar/Volume.cpp.func-sort-c.html | 101 + coverage/colvar/Volume.cpp.func.html | 101 + 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 | 277 + .../config/ConfigInstall.inc.func-sort-c.html | 173 + coverage/config/ConfigInstall.inc.func.html | 173 + coverage/config/ConfigInstall.inc.gcov.html | 277 + 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 | 197 + coverage/core/Action.cpp.func.html | 197 + coverage/core/Action.cpp.gcov.html | 359 + coverage/core/Action.h.func-sort-c.html | 177 + coverage/core/Action.h.func.html | 177 + coverage/core/Action.h.gcov.html | 507 + .../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 | 161 + coverage/core/ActionAtomistic.cpp.func.html | 161 + coverage/core/ActionAtomistic.cpp.gcov.html | 383 + .../core/ActionAtomistic.h.func-sort-c.html | 89 + coverage/core/ActionAtomistic.h.func.html | 89 + coverage/core/ActionAtomistic.h.gcov.html | 399 + .../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 | 113 + coverage/core/ActionRegister.cpp.func.html | 113 + coverage/core/ActionRegister.cpp.gcov.html | 214 + 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 | 169 + coverage/core/ActionSet.h.func.html | 169 + 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 | 122 + 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 | 81 + coverage/core/ActionShortcut.h.func.html | 81 + coverage/core/ActionShortcut.h.gcov.html | 133 + .../ActionWithArguments.cpp.func-sort-c.html | 121 + .../core/ActionWithArguments.cpp.func.html | 121 + .../core/ActionWithArguments.cpp.gcov.html | 387 + .../ActionWithArguments.h.func-sort-c.html | 93 + coverage/core/ActionWithArguments.h.func.html | 93 + coverage/core/ActionWithArguments.h.gcov.html | 209 + .../core/ActionWithValue.cpp.func-sort-c.html | 193 + coverage/core/ActionWithValue.cpp.func.html | 193 + coverage/core/ActionWithValue.cpp.gcov.html | 309 + .../core/ActionWithValue.h.func-sort-c.html | 101 + coverage/core/ActionWithValue.h.func.html | 101 + coverage/core/ActionWithValue.h.gcov.html | 297 + ...ActionWithVirtualAtom.cpp.func-sort-c.html | 121 + .../core/ActionWithVirtualAtom.cpp.func.html | 121 + .../core/ActionWithVirtualAtom.cpp.gcov.html | 185 + .../ActionWithVirtualAtom.h.func-sort-c.html | 73 + .../core/ActionWithVirtualAtom.h.func.html | 73 + .../core/ActionWithVirtualAtom.h.gcov.html | 197 + coverage/core/Atoms.cpp.func-sort-c.html | 293 + coverage/core/Atoms.cpp.func.html | 293 + coverage/core/Atoms.cpp.gcov.html | 684 + coverage/core/Atoms.h.func-sort-c.html | 81 + coverage/core/Atoms.h.func.html | 81 + coverage/core/Atoms.h.gcov.html | 377 + coverage/core/CLTool.cpp.func-sort-c.html | 113 + coverage/core/CLTool.cpp.func.html | 113 + coverage/core/CLTool.cpp.gcov.html | 290 + coverage/core/CLTool.h.func-sort-c.html | 129 + coverage/core/CLTool.h.func.html | 129 + 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 | 202 + coverage/core/Colvar.h.func-sort-c.html | 101 + coverage/core/Colvar.h.func.html | 101 + coverage/core/Colvar.h.gcov.html | 196 + .../DataFetchingObject.cpp.func-sort-c.html | 137 + .../core/DataFetchingObject.cpp.func.html | 137 + .../core/DataFetchingObject.cpp.gcov.html | 236 + .../DataFetchingObject.h.func-sort-c.html | 81 + coverage/core/DataFetchingObject.h.func.html | 81 + coverage/core/DataFetchingObject.h.gcov.html | 145 + .../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 | 299 + .../core/GenericMolInfo.cpp.func-sort-c.html | 141 + coverage/core/GenericMolInfo.cpp.func.html | 141 + coverage/core/GenericMolInfo.cpp.gcov.html | 409 + .../core/GenericMolInfo.h.func-sort-c.html | 81 + coverage/core/GenericMolInfo.h.func.html | 81 + coverage/core/GenericMolInfo.h.gcov.html | 164 + coverage/core/MDAtoms.cpp.func-sort-c.html | 317 + coverage/core/MDAtoms.cpp.func.html | 317 + coverage/core/MDAtoms.cpp.gcov.html | 464 + coverage/core/PlumedMain.cpp.func-sort-c.html | 217 + coverage/core/PlumedMain.cpp.func.html | 217 + coverage/core/PlumedMain.cpp.gcov.html | 1140 + coverage/core/PlumedMain.h.func-sort-c.html | 73 + coverage/core/PlumedMain.h.func.html | 73 + coverage/core/PlumedMain.h.gcov.html | 580 + ...PlumedMainInitializer.cpp.func-sort-c.html | 117 + .../core/PlumedMainInitializer.cpp.func.html | 117 + .../core/PlumedMainInitializer.cpp.gcov.html | 389 + 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 | 137 + coverage/core/Value.cpp.func.html | 137 + coverage/core/Value.cpp.gcov.html | 277 + coverage/core/Value.h.func-sort-c.html | 93 + coverage/core/Value.h.func.html | 93 + coverage/core/Value.h.gcov.html | 393 + coverage/core/WithCmd.h.func-sort-c.html | 77 + coverage/core/WithCmd.h.func.html | 77 + coverage/core/WithCmd.h.gcov.html | 130 + coverage/core/index-sort-f.html | 524 + coverage/core/index-sort-l.html | 524 + coverage/core/index.html | 524 + .../BondOrientation.cpp.func-sort-c.html | 105 + .../BondOrientation.cpp.func.html | 105 + .../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 | 113 + .../EnvironmentSimilarity.cpp.func.html | 113 + .../EnvironmentSimilarity.cpp.gcov.html | 534 + .../Fccubic.cpp.func-sort-c.html | 101 + .../crystallization/Fccubic.cpp.func.html | 101 + .../crystallization/Fccubic.cpp.gcov.html | 210 + .../Gradient.cpp.func-sort-c.html | 105 + .../crystallization/Gradient.cpp.func.html | 105 + .../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 | 113 + .../InterMolecularTorsions.cpp.func.html | 113 + .../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 | 113 + .../MoleculeOrientation.cpp.func.html | 113 + .../MoleculeOrientation.cpp.gcov.html | 228 + .../MoleculePlane.cpp.func-sort-c.html | 105 + .../MoleculePlane.cpp.func.html | 105 + .../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 | 101 + .../PolymerAngles.cpp.func.html | 101 + .../PolymerAngles.cpp.gcov.html | 179 + .../crystallization/Q3.cpp.func-sort-c.html | 109 + coverage/crystallization/Q3.cpp.func.html | 109 + coverage/crystallization/Q3.cpp.gcov.html | 302 + .../crystallization/Q4.cpp.func-sort-c.html | 109 + coverage/crystallization/Q4.cpp.func.html | 109 + coverage/crystallization/Q4.cpp.gcov.html | 294 + .../crystallization/Q6.cpp.func-sort-c.html | 109 + coverage/crystallization/Q6.cpp.func.html | 109 + coverage/crystallization/Q6.cpp.gcov.html | 297 + .../crystallization/SMAC.cpp.func-sort-c.html | 105 + coverage/crystallization/SMAC.cpp.func.html | 105 + coverage/crystallization/SMAC.cpp.gcov.html | 282 + .../SimpleCubic.cpp.func-sort-c.html | 101 + .../crystallization/SimpleCubic.cpp.func.html | 101 + .../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 | 101 + .../crystallization/Tetrahedral.cpp.func.html | 101 + .../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 | 101 + ...sicalMultiDimensionalScaling.cpp.func.html | 101 + ...sicalMultiDimensionalScaling.cpp.gcov.html | 287 + ...ionalityReductionBase.cpp.func-sort-c.html | 101 + .../DimensionalityReductionBase.cpp.func.html | 101 + .../DimensionalityReductionBase.cpp.gcov.html | 213 + ...nsionalityReductionBase.h.func-sort-c.html | 81 + .../DimensionalityReductionBase.h.func.html | 81 + .../DimensionalityReductionBase.h.gcov.html | 151 + .../OutputPCAProjections.cpp.func-sort-c.html | 105 + .../dimred/OutputPCAProjections.cpp.func.html | 105 + .../dimred/OutputPCAProjections.cpp.gcov.html | 189 + coverage/dimred/PCA.cpp.func-sort-c.html | 109 + coverage/dimred/PCA.cpp.func.html | 109 + 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 | 121 + .../ProjectNonLandmarkPoints.cpp.func.html | 121 + .../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 | 97 + coverage/dimred/SketchMap.cpp.func.html | 97 + 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 | 101 + .../dimred/SketchMapConjGrad.cpp.func.html | 101 + .../dimred/SketchMapConjGrad.cpp.gcov.html | 147 + .../SketchMapPointwise.cpp.func-sort-c.html | 101 + .../dimred/SketchMapPointwise.cpp.func.html | 101 + .../dimred/SketchMapPointwise.cpp.gcov.html | 203 + .../dimred/SketchMapRead.cpp.func-sort-c.html | 125 + coverage/dimred/SketchMapRead.cpp.func.html | 125 + coverage/dimred/SketchMapRead.cpp.gcov.html | 271 + .../SketchMapSmacof.cpp.func-sort-c.html | 105 + coverage/dimred/SketchMapSmacof.cpp.func.html | 105 + coverage/dimred/SketchMapSmacof.cpp.gcov.html | 187 + .../dimred/SmacoffMDS.cpp.func-sort-c.html | 101 + coverage/dimred/SmacoffMDS.cpp.func.html | 101 + 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 | 616 + 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 | 121 + .../DynamicReferenceRestraining.cpp.func.html | 121 + .../DynamicReferenceRestraining.cpp.gcov.html | 971 + .../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 | 342 + 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 | 165 + coverage/eds/EDS.cpp.func.html | 165 + coverage/eds/EDS.cpp.gcov.html | 1257 + 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 | 161 + coverage/fisst/FISST.cpp.func.html | 161 + coverage/fisst/FISST.cpp.gcov.html | 739 + 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 | 101 + coverage/function/Combine.cpp.func.html | 101 + coverage/function/Combine.cpp.gcov.html | 233 + coverage/function/Custom.cpp.func-sort-c.html | 113 + coverage/function/Custom.cpp.func.html | 113 + coverage/function/Custom.cpp.gcov.html | 375 + .../function/Ensemble.cpp.func-sort-c.html | 101 + coverage/function/Ensemble.cpp.func.html | 101 + coverage/function/Ensemble.cpp.gcov.html | 343 + .../FuncPathGeneral.cpp.func-sort-c.html | 109 + .../function/FuncPathGeneral.cpp.func.html | 109 + .../function/FuncPathGeneral.cpp.gcov.html | 416 + .../function/FuncPathMSD.cpp.func-sort-c.html | 105 + coverage/function/FuncPathMSD.cpp.func.html | 105 + coverage/function/FuncPathMSD.cpp.gcov.html | 445 + .../FuncSumHills.cpp.func-sort-c.html | 133 + coverage/function/FuncSumHills.cpp.func.html | 133 + 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 | 179 + coverage/function/Function.h.func-sort-c.html | 85 + coverage/function/Function.h.func.html | 85 + coverage/function/Function.h.gcov.html | 150 + .../LocalEnsemble.cpp.func-sort-c.html | 101 + coverage/function/LocalEnsemble.cpp.func.html | 101 + coverage/function/LocalEnsemble.cpp.gcov.html | 228 + .../function/Piecewise.cpp.func-sort-c.html | 101 + coverage/function/Piecewise.cpp.func.html | 101 + coverage/function/Piecewise.cpp.gcov.html | 235 + coverage/function/Sort.cpp.func-sort-c.html | 101 + coverage/function/Sort.cpp.func.html | 101 + coverage/function/Sort.cpp.gcov.html | 184 + coverage/function/Stats.cpp.func-sort-c.html | 101 + coverage/function/Stats.cpp.func.html | 101 + coverage/function/Stats.cpp.gcov.html | 316 + coverage/function/Target.cpp.func-sort-c.html | 101 + coverage/function/Target.cpp.func.html | 101 + coverage/function/Target.cpp.gcov.html | 238 + 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 | 113 + coverage/funnel/FPS.cpp.func.html | 113 + coverage/funnel/FPS.cpp.gcov.html | 409 + coverage/funnel/Funnel.cpp.func-sort-c.html | 105 + coverage/funnel/Funnel.cpp.func.html | 105 + 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 | 105 + coverage/generic/Debug.cpp.func.html | 105 + coverage/generic/Debug.cpp.gcov.html | 217 + .../generic/DumpAtoms.cpp.func-sort-c.html | 121 + coverage/generic/DumpAtoms.cpp.func.html | 121 + coverage/generic/DumpAtoms.cpp.gcov.html | 389 + .../DumpDerivatives.cpp.func-sort-c.html | 121 + .../generic/DumpDerivatives.cpp.func.html | 121 + .../generic/DumpDerivatives.cpp.gcov.html | 210 + .../generic/DumpForces.cpp.func-sort-c.html | 121 + coverage/generic/DumpForces.cpp.func.html | 121 + coverage/generic/DumpForces.cpp.gcov.html | 196 + .../DumpMassCharge.cpp.func-sort-c.html | 125 + coverage/generic/DumpMassCharge.cpp.func.html | 125 + coverage/generic/DumpMassCharge.cpp.gcov.html | 265 + .../DumpProjections.cpp.func-sort-c.html | 125 + .../generic/DumpProjections.cpp.func.html | 125 + .../generic/DumpProjections.cpp.gcov.html | 197 + .../EffectiveEnergyDrift.cpp.func-sort-c.html | 121 + .../EffectiveEnergyDrift.cpp.func.html | 121 + .../EffectiveEnergyDrift.cpp.gcov.html | 410 + .../generic/EndPlumed.cpp.func-sort-c.html | 101 + coverage/generic/EndPlumed.cpp.func.html | 101 + coverage/generic/EndPlumed.cpp.gcov.html | 157 + .../FitToTemplate.cpp.func-sort-c.html | 109 + coverage/generic/FitToTemplate.cpp.func.html | 109 + coverage/generic/FitToTemplate.cpp.gcov.html | 451 + coverage/generic/Flush.cpp.func-sort-c.html | 105 + coverage/generic/Flush.cpp.func.html | 105 + coverage/generic/Flush.cpp.gcov.html | 168 + coverage/generic/Group.cpp.func-sort-c.html | 117 + coverage/generic/Group.cpp.func.html | 117 + coverage/generic/Group.cpp.gcov.html | 323 + coverage/generic/Include.cpp.func-sort-c.html | 105 + coverage/generic/Include.cpp.func.html | 105 + coverage/generic/Include.cpp.gcov.html | 256 + coverage/generic/MolInfo.cpp.func-sort-c.html | 85 + coverage/generic/MolInfo.cpp.func.html | 85 + coverage/generic/MolInfo.cpp.gcov.html | 346 + coverage/generic/Plumed.cpp.func-sort-c.html | 129 + coverage/generic/Plumed.cpp.func.html | 129 + coverage/generic/Plumed.cpp.gcov.html | 496 + coverage/generic/Print.cpp.func-sort-c.html | 125 + coverage/generic/Print.cpp.func.html | 125 + coverage/generic/Print.cpp.gcov.html | 257 + .../RandomExchanges.cpp.func-sort-c.html | 101 + .../generic/RandomExchanges.cpp.func.html | 101 + .../generic/RandomExchanges.cpp.gcov.html | 179 + coverage/generic/Read.cpp.func-sort-c.html | 129 + coverage/generic/Read.cpp.func.html | 129 + coverage/generic/Read.cpp.gcov.html | 333 + .../generic/ResetCell.cpp.func-sort-c.html | 105 + coverage/generic/ResetCell.cpp.func.html | 105 + coverage/generic/ResetCell.cpp.gcov.html | 275 + coverage/generic/Time.cpp.func-sort-c.html | 109 + coverage/generic/Time.cpp.func.html | 109 + coverage/generic/Time.cpp.gcov.html | 156 + .../generic/UpdateIf.cpp.func-sort-c.html | 125 + coverage/generic/UpdateIf.cpp.func.html | 125 + coverage/generic/UpdateIf.cpp.gcov.html | 235 + .../WholeMolecules.cpp.func-sort-c.html | 105 + coverage/generic/WholeMolecules.cpp.func.html | 105 + coverage/generic/WholeMolecules.cpp.gcov.html | 320 + .../generic/WrapAround.cpp.func-sort-c.html | 105 + coverage/generic/WrapAround.cpp.func.html | 105 + coverage/generic/WrapAround.cpp.gcov.html | 313 + coverage/generic/index-sort-f.html | 304 + coverage/generic/index-sort-l.html | 304 + coverage/generic/index.html | 304 + 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 | 186 + .../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 | 133 + coverage/gridtools/ConvertToFES.cpp.func.html | 133 + coverage/gridtools/ConvertToFES.cpp.gcov.html | 224 + .../gridtools/DumpCube.cpp.func-sort-c.html | 101 + coverage/gridtools/DumpCube.cpp.func.html | 101 + coverage/gridtools/DumpCube.cpp.gcov.html | 202 + .../gridtools/DumpGrid.cpp.func-sort-c.html | 101 + coverage/gridtools/DumpGrid.cpp.func.html | 101 + coverage/gridtools/DumpGrid.cpp.gcov.html | 273 + .../FindContour.cpp.func-sort-c.html | 121 + coverage/gridtools/FindContour.cpp.func.html | 121 + coverage/gridtools/FindContour.cpp.gcov.html | 324 + .../FindContourSurface.cpp.func-sort-c.html | 121 + .../FindContourSurface.cpp.func.html | 121 + .../FindContourSurface.cpp.gcov.html | 340 + .../FindSphericalContour.cpp.func-sort-c.html | 105 + .../FindSphericalContour.cpp.func.html | 105 + .../FindSphericalContour.cpp.gcov.html | 261 + .../FourierTransform.cpp.func-sort-c.html | 113 + .../gridtools/FourierTransform.cpp.func.html | 113 + .../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 | 101 + coverage/gridtools/GridToXYZ.cpp.func.html | 101 + coverage/gridtools/GridToXYZ.cpp.gcov.html | 187 + .../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 | 101 + .../gridtools/IntegrateGrid.cpp.func.html | 101 + .../gridtools/IntegrateGrid.cpp.gcov.html | 139 + .../InterpolateGrid.cpp.func-sort-c.html | 109 + .../gridtools/InterpolateGrid.cpp.func.html | 109 + .../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 | 454 + coverage/index-sort-l.html | 454 + coverage/index.html | 454 + .../isdb/CS2Backbone.cpp.func-sort-c.html | 177 + coverage/isdb/CS2Backbone.cpp.func.html | 177 + coverage/isdb/CS2Backbone.cpp.gcov.html | 1916 + coverage/isdb/Caliber.cpp.func-sort-c.html | 117 + coverage/isdb/Caliber.cpp.func.html | 117 + coverage/isdb/Caliber.cpp.gcov.html | 424 + coverage/isdb/EMMI.cpp.func-sort-c.html | 241 + coverage/isdb/EMMI.cpp.func.html | 241 + coverage/isdb/EMMI.cpp.gcov.html | 1827 + .../isdb/FretEfficiency.cpp.func-sort-c.html | 101 + coverage/isdb/FretEfficiency.cpp.func.html | 101 + coverage/isdb/FretEfficiency.cpp.gcov.html | 232 + coverage/isdb/Jcoupling.cpp.func-sort-c.html | 105 + coverage/isdb/Jcoupling.cpp.func.html | 105 + coverage/isdb/Jcoupling.cpp.gcov.html | 471 + .../isdb/Metainference.cpp.func-sort-c.html | 193 + coverage/isdb/Metainference.cpp.func.html | 193 + coverage/isdb/Metainference.cpp.gcov.html | 1882 + .../MetainferenceBase.cpp.func-sort-c.html | 185 + coverage/isdb/MetainferenceBase.cpp.func.html | 185 + coverage/isdb/MetainferenceBase.cpp.gcov.html | 1640 + .../isdb/MetainferenceBase.h.func-sort-c.html | 113 + coverage/isdb/MetainferenceBase.h.func.html | 113 + coverage/isdb/MetainferenceBase.h.gcov.html | 462 + coverage/isdb/NOE.cpp.func-sort-c.html | 105 + coverage/isdb/NOE.cpp.func.html | 105 + coverage/isdb/NOE.cpp.gcov.html | 351 + coverage/isdb/PRE.cpp.func-sort-c.html | 105 + coverage/isdb/PRE.cpp.func.html | 105 + coverage/isdb/PRE.cpp.gcov.html | 417 + coverage/isdb/RDC.cpp.func-sort-c.html | 121 + coverage/isdb/RDC.cpp.func.html | 121 + coverage/isdb/RDC.cpp.gcov.html | 598 + coverage/isdb/Rescale.cpp.func-sort-c.html | 133 + coverage/isdb/Rescale.cpp.func.html | 133 + coverage/isdb/Rescale.cpp.gcov.html | 593 + coverage/isdb/SAXS.cpp.func-sort-c.html | 121 + coverage/isdb/SAXS.cpp.func.html | 121 + coverage/isdb/SAXS.cpp.gcov.html | 2164 ++ coverage/isdb/Select.cpp.func-sort-c.html | 101 + coverage/isdb/Select.cpp.func.html | 101 + coverage/isdb/Select.cpp.gcov.html | 193 + coverage/isdb/Selector.cpp.func-sort-c.html | 101 + coverage/isdb/Selector.cpp.func.html | 101 + coverage/isdb/Selector.cpp.gcov.html | 169 + coverage/isdb/index-sort-f.html | 234 + coverage/isdb/index-sort-l.html | 234 + coverage/isdb/index.html | 234 + coverage/logmfd/LogMFD.cpp.func-sort-c.html | 133 + coverage/logmfd/LogMFD.cpp.func.html | 133 + coverage/logmfd/LogMFD.cpp.gcov.html | 1221 + 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 | 101 + coverage/manyrestraints/LWalls.cpp.func.html | 101 + 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 | 101 + coverage/manyrestraints/UWalls.cpp.func.html | 101 + 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 | 117 + coverage/mapping/AdaptivePath.cpp.func.html | 117 + coverage/mapping/AdaptivePath.cpp.gcov.html | 336 + coverage/mapping/Mapping.cpp.func-sort-c.html | 117 + coverage/mapping/Mapping.cpp.func.html | 117 + coverage/mapping/Mapping.cpp.gcov.html | 286 + 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 | 121 + coverage/mapping/PCAVars.cpp.func.html | 121 + coverage/mapping/PCAVars.cpp.gcov.html | 536 + coverage/mapping/Path.cpp.func-sort-c.html | 97 + coverage/mapping/Path.cpp.func.html | 97 + 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 | 375 + .../mapping/PropertyMap.cpp.func-sort-c.html | 97 + coverage/mapping/PropertyMap.cpp.func.html | 97 + 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 | 101 + coverage/maze/Loss.cpp.func.html | 101 + coverage/maze/Loss.cpp.gcov.html | 190 + 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 | 113 + coverage/maze/Memetic.cpp.func.html | 113 + coverage/maze/Memetic.cpp.gcov.html | 365 + coverage/maze/Memetic.h.func-sort-c.html | 153 + coverage/maze/Memetic.h.func.html | 153 + coverage/maze/Memetic.h.gcov.html | 888 + coverage/maze/Optimizer.cpp.func-sort-c.html | 113 + coverage/maze/Optimizer.cpp.func.html | 113 + coverage/maze/Optimizer.cpp.gcov.html | 586 + coverage/maze/Optimizer.h.func-sort-c.html | 77 + coverage/maze/Optimizer.h.func.html | 77 + coverage/maze/Optimizer.h.gcov.html | 431 + .../maze/Optimizer_Bias.cpp.func-sort-c.html | 109 + coverage/maze/Optimizer_Bias.cpp.func.html | 109 + coverage/maze/Optimizer_Bias.cpp.gcov.html | 511 + ...andom_Acceleration_MD.cpp.func-sort-c.html | 113 + .../maze/Random_Acceleration_MD.cpp.func.html | 113 + .../maze/Random_Acceleration_MD.cpp.gcov.html | 289 + 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 | 113 + coverage/maze/Random_Walk.cpp.func.html | 113 + coverage/maze/Random_Walk.cpp.gcov.html | 210 + .../Simulated_Annealing.cpp.func-sort-c.html | 117 + .../maze/Simulated_Annealing.cpp.func.html | 117 + .../maze/Simulated_Annealing.cpp.gcov.html | 361 + coverage/maze/Steered_MD.cpp.func-sort-c.html | 113 + coverage/maze/Steered_MD.cpp.func.html | 113 + coverage/maze/Steered_MD.cpp.gcov.html | 262 + 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 + .../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 | 105 + coverage/multicolvar/AlphaBeta.cpp.func.html | 105 + coverage/multicolvar/AlphaBeta.cpp.gcov.html | 281 + .../multicolvar/Angles.cpp.func-sort-c.html | 109 + coverage/multicolvar/Angles.cpp.func.html | 109 + 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 | 105 + coverage/multicolvar/Bridge.cpp.func.html | 105 + coverage/multicolvar/Bridge.cpp.gcov.html | 232 + ...edMultiColvarFunction.cpp.func-sort-c.html | 117 + .../BridgedMultiColvarFunction.cpp.func.html | 117 + .../BridgedMultiColvarFunction.cpp.gcov.html | 201 + ...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 | 101 + .../CenterOfMultiColvar.cpp.func.html | 101 + .../CenterOfMultiColvar.cpp.gcov.html | 298 + .../CoordinationNumbers.cpp.func-sort-c.html | 105 + .../CoordinationNumbers.cpp.func.html | 105 + .../CoordinationNumbers.cpp.gcov.html | 261 + .../multicolvar/Density.cpp.func-sort-c.html | 121 + coverage/multicolvar/Density.cpp.func.html | 121 + coverage/multicolvar/Density.cpp.gcov.html | 182 + .../DihedralCorrelation.cpp.func-sort-c.html | 105 + .../DihedralCorrelation.cpp.func.html | 105 + .../DihedralCorrelation.cpp.gcov.html | 251 + .../DistanceFromContour.cpp.func-sort-c.html | 125 + .../DistanceFromContour.cpp.func.html | 125 + .../DistanceFromContour.cpp.gcov.html | 419 + .../Distances.cpp.func-sort-c.html | 105 + coverage/multicolvar/Distances.cpp.func.html | 105 + coverage/multicolvar/Distances.cpp.gcov.html | 288 + .../DumpMultiColvar.cpp.func-sort-c.html | 125 + .../multicolvar/DumpMultiColvar.cpp.func.html | 125 + .../multicolvar/DumpMultiColvar.cpp.gcov.html | 260 + .../FilterBetween.cpp.func-sort-c.html | 113 + .../multicolvar/FilterBetween.cpp.func.html | 113 + .../multicolvar/FilterBetween.cpp.gcov.html | 272 + .../FilterLessThan.cpp.func-sort-c.html | 113 + .../multicolvar/FilterLessThan.cpp.func.html | 113 + .../multicolvar/FilterLessThan.cpp.gcov.html | 240 + .../FilterMoreThan.cpp.func-sort-c.html | 113 + .../multicolvar/FilterMoreThan.cpp.func.html | 113 + .../multicolvar/FilterMoreThan.cpp.gcov.html | 257 + .../InPlaneDistances.cpp.func-sort-c.html | 105 + .../InPlaneDistances.cpp.func.html | 105 + .../InPlaneDistances.cpp.gcov.html | 224 + .../LocalAverage.cpp.func-sort-c.html | 113 + .../multicolvar/LocalAverage.cpp.func.html | 113 + .../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 | 105 + .../MultiColvarCombine.cpp.func.html | 105 + .../MultiColvarCombine.cpp.gcov.html | 172 + .../MultiColvarDensity.cpp.func-sort-c.html | 121 + .../MultiColvarDensity.cpp.func.html | 121 + .../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 | 105 + .../MultiColvarProduct.cpp.func.html | 105 + .../MultiColvarProduct.cpp.gcov.html | 166 + .../NumberOfLinks.cpp.func-sort-c.html | 109 + .../multicolvar/NumberOfLinks.cpp.func.html | 109 + .../multicolvar/NumberOfLinks.cpp.gcov.html | 252 + .../multicolvar/Torsions.cpp.func-sort-c.html | 109 + coverage/multicolvar/Torsions.cpp.func.html | 109 + coverage/multicolvar/Torsions.cpp.gcov.html | 212 + .../VolumeAround.cpp.func-sort-c.html | 105 + .../multicolvar/VolumeAround.cpp.func.html | 105 + .../multicolvar/VolumeAround.cpp.gcov.html | 231 + ...VolumeBetweenContours.cpp.func-sort-c.html | 105 + .../VolumeBetweenContours.cpp.func.html | 105 + .../VolumeBetweenContours.cpp.gcov.html | 223 + .../VolumeCavity.cpp.func-sort-c.html | 121 + .../multicolvar/VolumeCavity.cpp.func.html | 121 + .../multicolvar/VolumeCavity.cpp.gcov.html | 489 + .../VolumeGradientBase.cpp.func-sort-c.html | 105 + .../VolumeGradientBase.cpp.func.html | 105 + .../VolumeGradientBase.cpp.gcov.html | 226 + .../VolumeGradientBase.h.func-sort-c.html | 77 + .../VolumeGradientBase.h.func.html | 77 + .../VolumeGradientBase.h.gcov.html | 171 + .../VolumeInCylinder.cpp.func-sort-c.html | 105 + .../VolumeInCylinder.cpp.func.html | 105 + .../VolumeInCylinder.cpp.gcov.html | 237 + .../VolumeInSphere.cpp.func-sort-c.html | 105 + .../multicolvar/VolumeInSphere.cpp.func.html | 105 + .../multicolvar/VolumeInSphere.cpp.gcov.html | 200 + .../VolumeTetrapore.cpp.func-sort-c.html | 121 + .../multicolvar/VolumeTetrapore.cpp.func.html | 121 + .../multicolvar/VolumeTetrapore.cpp.gcov.html | 524 + .../multicolvar/XAngle.cpp.func-sort-c.html | 133 + coverage/multicolvar/XAngle.cpp.func.html | 133 + coverage/multicolvar/XAngle.cpp.gcov.html | 254 + .../XDistances.cpp.func-sort-c.html | 129 + coverage/multicolvar/XDistances.cpp.func.html | 129 + coverage/multicolvar/XDistances.cpp.gcov.html | 318 + .../XYDistances.cpp.func-sort-c.html | 129 + .../multicolvar/XYDistances.cpp.func.html | 129 + .../multicolvar/XYDistances.cpp.gcov.html | 246 + .../XYTorsion.cpp.func-sort-c.html | 173 + coverage/multicolvar/XYTorsion.cpp.func.html | 173 + 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 | 129 + coverage/opes/ECVcustom.cpp.func.html | 129 + coverage/opes/ECVcustom.cpp.gcov.html | 315 + coverage/opes/ECVlinear.cpp.func-sort-c.html | 125 + coverage/opes/ECVlinear.cpp.func.html | 125 + coverage/opes/ECVlinear.cpp.gcov.html | 345 + .../opes/ECVmultiThermal.cpp.func-sort-c.html | 125 + coverage/opes/ECVmultiThermal.cpp.func.html | 125 + coverage/opes/ECVmultiThermal.cpp.gcov.html | 347 + .../ECVmultiThermalBaric.cpp.func-sort-c.html | 133 + .../opes/ECVmultiThermalBaric.cpp.func.html | 133 + .../opes/ECVmultiThermalBaric.cpp.gcov.html | 609 + .../ECVumbrellasFile.cpp.func-sort-c.html | 125 + coverage/opes/ECVumbrellasFile.cpp.func.html | 125 + coverage/opes/ECVumbrellasFile.cpp.gcov.html | 372 + .../ECVumbrellasLine.cpp.func-sort-c.html | 125 + coverage/opes/ECVumbrellasLine.cpp.func.html | 125 + coverage/opes/ECVumbrellasLine.cpp.gcov.html | 377 + .../opes/ExpansionCVs.cpp.func-sort-c.html | 113 + coverage/opes/ExpansionCVs.cpp.func.html | 113 + coverage/opes/ExpansionCVs.cpp.gcov.html | 310 + 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 | 137 + coverage/opes/OPESexpanded.cpp.func.html | 137 + coverage/opes/OPESexpanded.cpp.gcov.html | 1015 + coverage/opes/OPESmetad.cpp.func-sort-c.html | 209 + coverage/opes/OPESmetad.cpp.func.html | 209 + 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 | 105 + coverage/pamm/HBPammHydrogens.cpp.func.html | 105 + coverage/pamm/HBPammHydrogens.cpp.gcov.html | 268 + .../pamm/HBPammMatrix.cpp.func-sort-c.html | 105 + coverage/pamm/HBPammMatrix.cpp.func.html | 105 + 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 | 117 + coverage/pamm/PAMM.cpp.func.html | 117 + 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 | 117 + coverage/piv/PIV.cpp.func.html | 117 + coverage/piv/PIV.cpp.gcov.html | 1304 + coverage/piv/index-sort-f.html | 94 + coverage/piv/index-sort-l.html | 94 + coverage/piv/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 | 189 + .../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 | 117 + coverage/s2cm/S2ContactModel.cpp.func.html | 117 + coverage/s2cm/S2ContactModel.cpp.gcov.html | 400 + 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 | 137 + coverage/sasa/sasa_HASEL.cpp.func.html | 137 + coverage/sasa/sasa_HASEL.cpp.gcov.html | 1087 + coverage/sasa/sasa_LCPO.cpp.func-sort-c.html | 137 + coverage/sasa/sasa_LCPO.cpp.func.html | 137 + coverage/sasa/sasa_LCPO.cpp.gcov.html | 1155 + .../AlphaRMSD.cpp.func-sort-c.html | 97 + .../AlphaRMSD.cpp.func.html | 97 + .../AlphaRMSD.cpp.gcov.html | 235 + .../AntibetaRMSD.cpp.func-sort-c.html | 97 + .../AntibetaRMSD.cpp.func.html | 97 + .../AntibetaRMSD.cpp.gcov.html | 287 + .../ParabetaRMSD.cpp.func-sort-c.html | 97 + .../ParabetaRMSD.cpp.func.html | 97 + .../ParabetaRMSD.cpp.gcov.html | 321 + ...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 | 97 + coverage/setup/Load.cpp.func.html | 97 + coverage/setup/Load.cpp.gcov.html | 200 + coverage/setup/Restart.cpp.func-sort-c.html | 97 + coverage/setup/Restart.cpp.func.html | 97 + coverage/setup/Restart.cpp.gcov.html | 202 + coverage/setup/Units.cpp.func-sort-c.html | 97 + coverage/setup/Units.cpp.func.html | 97 + coverage/setup/Units.cpp.gcov.html | 278 + coverage/setup/index-sort-f.html | 114 + coverage/setup/index-sort-l.html | 114 + coverage/setup/index.html | 114 + 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 | 213 + coverage/tools/Communicator.cpp.func.html | 213 + coverage/tools/Communicator.cpp.gcov.html | 387 + .../tools/Communicator.h.func-sort-c.html | 321 + coverage/tools/Communicator.h.func.html | 321 + coverage/tools/Communicator.h.gcov.html | 326 + .../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 | 93 + coverage/tools/DLLoader.cpp.func.html | 93 + coverage/tools/DLLoader.cpp.gcov.html | 156 + 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 | 93 + coverage/tools/Exception.cpp.func.html | 93 + coverage/tools/Exception.cpp.gcov.html | 177 + coverage/tools/Exception.h.func-sort-c.html | 609 + coverage/tools/Exception.h.func.html | 609 + coverage/tools/Exception.h.gcov.html | 446 + coverage/tools/FileBase.cpp.func-sort-c.html | 133 + coverage/tools/FileBase.cpp.func.html | 133 + coverage/tools/FileBase.cpp.gcov.html | 246 + 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 | 125 + coverage/tools/ForwardDecl.h.func.html | 125 + 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 | 1206 + 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 | 165 + coverage/tools/IFile.cpp.func.html | 165 + coverage/tools/IFile.cpp.gcov.html | 358 + coverage/tools/IFile.h.func-sort-c.html | 73 + coverage/tools/IFile.h.func.html | 73 + coverage/tools/IFile.h.gcov.html | 190 + .../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 | 221 + coverage/tools/Keywords.cpp.func.html | 221 + coverage/tools/Keywords.cpp.gcov.html | 778 + coverage/tools/Keywords.h.func-sort-c.html | 81 + coverage/tools/Keywords.h.func.html | 81 + coverage/tools/Keywords.h.gcov.html | 253 + .../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 | 145 + .../MatrixSquareBracketsAccess.h.func.html | 145 + .../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 | 133 + coverage/tools/NeighborList.cpp.func.html | 133 + coverage/tools/NeighborList.cpp.gcov.html | 302 + .../tools/NeighborList.h.func-sort-c.html | 77 + coverage/tools/NeighborList.h.func.html | 77 + coverage/tools/NeighborList.h.gcov.html | 171 + coverage/tools/OFile.cpp.func-sort-c.html | 185 + coverage/tools/OFile.cpp.func.html | 185 + coverage/tools/OFile.cpp.gcov.html | 496 + coverage/tools/OFile.h.func-sort-c.html | 501 + coverage/tools/OFile.h.func.html | 501 + coverage/tools/OFile.h.gcov.html | 361 + coverage/tools/OpenMP.cpp.func-sort-c.html | 93 + coverage/tools/OpenMP.cpp.func.html | 93 + coverage/tools/OpenMP.cpp.gcov.html | 155 + coverage/tools/OpenMP.h.func-sort-c.html | 89 + coverage/tools/OpenMP.h.func.html | 89 + coverage/tools/OpenMP.h.gcov.html | 155 + coverage/tools/PDB.cpp.func-sort-c.html | 245 + coverage/tools/PDB.cpp.func.html | 245 + coverage/tools/PDB.cpp.gcov.html | 698 + coverage/tools/Pbc.cpp.func-sort-c.html | 121 + coverage/tools/Pbc.cpp.func.html | 121 + coverage/tools/Pbc.cpp.gcov.html | 324 + coverage/tools/Pbc.h.func-sort-c.html | 73 + coverage/tools/Pbc.h.func.html | 73 + coverage/tools/Pbc.h.gcov.html | 189 + .../tools/PlumedHandle.cpp.func-sort-c.html | 105 + coverage/tools/PlumedHandle.cpp.func.html | 105 + coverage/tools/PlumedHandle.cpp.gcov.html | 196 + 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 | 451 + 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 | 154 + 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 | 266 + 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 | 630 + 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 | 651 + coverage/tools/Tools.cpp.func-sort-c.html | 237 + coverage/tools/Tools.cpp.func.html | 237 + coverage/tools/Tools.cpp.gcov.html | 519 + coverage/tools/Tools.h.func-sort-c.html | 1761 + coverage/tools/Tools.h.func.html | 1761 + coverage/tools/Tools.h.gcov.html | 424 + 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 | 281 + coverage/tools/TypesafePtr.h.func.html | 281 + coverage/tools/TypesafePtr.h.gcov.html | 476 + 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 | 289 + coverage/tools/Vector.h.func.html | 289 + 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 | 113 + coverage/vatom/Center.cpp.func.html | 113 + coverage/vatom/Center.cpp.gcov.html | 380 + coverage/vatom/FixedAtom.cpp.func-sort-c.html | 101 + coverage/vatom/FixedAtom.cpp.func.html | 101 + coverage/vatom/FixedAtom.cpp.gcov.html | 226 + coverage/vatom/Ghost.cpp.func-sort-c.html | 101 + coverage/vatom/Ghost.cpp.func.html | 101 + coverage/vatom/Ghost.cpp.gcov.html | 261 + 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 | 101 + coverage/ves/BF_Chebyshev.cpp.func.html | 101 + coverage/ves/BF_Chebyshev.cpp.gcov.html | 233 + coverage/ves/BF_Combined.cpp.func-sort-c.html | 105 + coverage/ves/BF_Combined.cpp.func.html | 105 + coverage/ves/BF_Combined.cpp.gcov.html | 279 + coverage/ves/BF_Cosine.cpp.func-sort-c.html | 105 + coverage/ves/BF_Cosine.cpp.func.html | 105 + coverage/ves/BF_Cosine.cpp.gcov.html | 229 + .../ves/BF_CubicBsplines.cpp.func-sort-c.html | 101 + coverage/ves/BF_CubicBsplines.cpp.func.html | 101 + coverage/ves/BF_CubicBsplines.cpp.gcov.html | 278 + coverage/ves/BF_Custom.cpp.func-sort-c.html | 105 + coverage/ves/BF_Custom.cpp.func.html | 105 + coverage/ves/BF_Custom.cpp.gcov.html | 446 + coverage/ves/BF_Fourier.cpp.func-sort-c.html | 105 + coverage/ves/BF_Fourier.cpp.func.html | 105 + coverage/ves/BF_Fourier.cpp.gcov.html | 233 + .../ves/BF_Gaussians.cpp.func-sort-c.html | 101 + coverage/ves/BF_Gaussians.cpp.func.html | 101 + coverage/ves/BF_Gaussians.cpp.gcov.html | 266 + coverage/ves/BF_Legendre.cpp.func-sort-c.html | 101 + coverage/ves/BF_Legendre.cpp.func.html | 101 + coverage/ves/BF_Legendre.cpp.gcov.html | 249 + coverage/ves/BF_Powers.cpp.func-sort-c.html | 101 + coverage/ves/BF_Powers.cpp.func.html | 101 + coverage/ves/BF_Powers.cpp.gcov.html | 222 + coverage/ves/BF_Sine.cpp.func-sort-c.html | 105 + coverage/ves/BF_Sine.cpp.func.html | 105 + coverage/ves/BF_Sine.cpp.gcov.html | 228 + coverage/ves/BF_Wavelets.cpp.func-sort-c.html | 105 + coverage/ves/BF_Wavelets.cpp.func.html | 105 + 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 | 101 + coverage/ves/Opt_Adam.cpp.func.html | 101 + coverage/ves/Opt_Adam.cpp.gcov.html | 273 + .../Opt_BachAveragedSGD.cpp.func-sort-c.html | 101 + .../ves/Opt_BachAveragedSGD.cpp.func.html | 101 + .../ves/Opt_BachAveragedSGD.cpp.gcov.html | 379 + coverage/ves/Opt_Dummy.cpp.func-sort-c.html | 101 + coverage/ves/Opt_Dummy.cpp.func.html | 101 + coverage/ves/Opt_Dummy.cpp.gcov.html | 198 + .../Opt_RobbinsMonroSGD.cpp.func-sort-c.html | 101 + .../ves/Opt_RobbinsMonroSGD.cpp.func.html | 101 + .../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 | 101 + .../ves/OutputBasisFunctions.cpp.func.html | 101 + .../ves/OutputBasisFunctions.cpp.gcov.html | 313 + .../ves/OutputFesBias.cpp.func-sort-c.html | 105 + coverage/ves/OutputFesBias.cpp.func.html | 105 + coverage/ves/OutputFesBias.cpp.gcov.html | 307 + ...putTargetDistribution.cpp.func-sort-c.html | 101 + .../OutputTargetDistribution.cpp.func.html | 101 + .../OutputTargetDistribution.cpp.gcov.html | 303 + coverage/ves/TD_Chi.cpp.func-sort-c.html | 97 + coverage/ves/TD_Chi.cpp.func.html | 97 + coverage/ves/TD_Chi.cpp.gcov.html | 230 + .../ves/TD_ChiSquared.cpp.func-sort-c.html | 97 + coverage/ves/TD_ChiSquared.cpp.func.html | 97 + coverage/ves/TD_ChiSquared.cpp.gcov.html | 229 + coverage/ves/TD_Custom.cpp.func-sort-c.html | 113 + coverage/ves/TD_Custom.cpp.func.html | 113 + coverage/ves/TD_Custom.cpp.gcov.html | 372 + .../ves/TD_Exponential.cpp.func-sort-c.html | 97 + coverage/ves/TD_Exponential.cpp.func.html | 97 + coverage/ves/TD_Exponential.cpp.gcov.html | 206 + ...iallyModifiedGaussian.cpp.func-sort-c.html | 101 + ...xponentiallyModifiedGaussian.cpp.func.html | 101 + ...xponentiallyModifiedGaussian.cpp.gcov.html | 301 + coverage/ves/TD_Gaussian.cpp.func-sort-c.html | 105 + coverage/ves/TD_Gaussian.cpp.func.html | 105 + coverage/ves/TD_Gaussian.cpp.gcov.html | 392 + ...neralizedExtremeValue.cpp.func-sort-c.html | 101 + .../TD_GeneralizedExtremeValue.cpp.func.html | 101 + .../TD_GeneralizedExtremeValue.cpp.gcov.html | 254 + .../TD_GeneralizedNormal.cpp.func-sort-c.html | 101 + .../ves/TD_GeneralizedNormal.cpp.func.html | 101 + .../ves/TD_GeneralizedNormal.cpp.gcov.html | 304 + coverage/ves/TD_Grid.cpp.func-sort-c.html | 97 + coverage/ves/TD_Grid.cpp.func.html | 97 + coverage/ves/TD_Grid.cpp.gcov.html | 295 + .../TD_LinearCombination.cpp.func-sort-c.html | 125 + .../ves/TD_LinearCombination.cpp.func.html | 125 + .../ves/TD_LinearCombination.cpp.gcov.html | 351 + .../TD_Multicanonical.cpp.func-sort-c.html | 109 + coverage/ves/TD_Multicanonical.cpp.func.html | 109 + coverage/ves/TD_Multicanonical.cpp.gcov.html | 552 + ...ultithermalMultibaric.cpp.func-sort-c.html | 109 + .../TD_MultithermalMultibaric.cpp.func.html | 109 + .../TD_MultithermalMultibaric.cpp.gcov.html | 535 + ...TD_ProductCombination.cpp.func-sort-c.html | 125 + .../ves/TD_ProductCombination.cpp.func.html | 125 + .../ves/TD_ProductCombination.cpp.gcov.html | 341 + ...D_ProductDistribution.cpp.func-sort-c.html | 125 + .../ves/TD_ProductDistribution.cpp.func.html | 125 + .../ves/TD_ProductDistribution.cpp.gcov.html | 302 + coverage/ves/TD_Uniform.cpp.func-sort-c.html | 101 + coverage/ves/TD_Uniform.cpp.func.html | 101 + coverage/ves/TD_Uniform.cpp.gcov.html | 382 + coverage/ves/TD_VonMises.cpp.func-sort-c.html | 105 + coverage/ves/TD_VonMises.cpp.func.html | 105 + coverage/ves/TD_VonMises.cpp.gcov.html | 316 + .../ves/TD_WellTempered.cpp.func-sort-c.html | 109 + coverage/ves/TD_WellTempered.cpp.func.html | 109 + 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 | 838 + 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 | 117 + coverage/ves/VesDeltaF.cpp.func.html | 117 + coverage/ves/VesDeltaF.cpp.gcov.html | 796 + .../VesLinearExpansion.cpp.func-sort-c.html | 169 + coverage/ves/VesLinearExpansion.cpp.func.html | 169 + 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 | 277 + .../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 | 73 + coverage/vesselbase/ValueVessel.h.func.html | 73 + 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 | 981 + coverage/wrapper/Plumed.h.func.html | 981 + coverage/wrapper/Plumed.h.gcov.html | 4010 ++ coverage/wrapper/index-sort-f.html | 94 + coverage/wrapper/index-sort-l.html | 94 + coverage/wrapper/index.html | 94 + index.html | 14 + 2171 files changed, 490146 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/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/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/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/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/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/Atoms.cpp.func-sort-c.html create mode 100644 coverage/core/Atoms.cpp.func.html create mode 100644 coverage/core/Atoms.cpp.gcov.html create mode 100644 coverage/core/Atoms.h.func-sort-c.html create mode 100644 coverage/core/Atoms.h.func.html create mode 100644 coverage/core/Atoms.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/DataFetchingObject.cpp.func-sort-c.html create mode 100644 coverage/core/DataFetchingObject.cpp.func.html create mode 100644 coverage/core/DataFetchingObject.cpp.gcov.html create mode 100644 coverage/core/DataFetchingObject.h.func-sort-c.html create mode 100644 coverage/core/DataFetchingObject.h.func.html create mode 100644 coverage/core/DataFetchingObject.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/MDAtoms.cpp.func-sort-c.html create mode 100644 coverage/core/MDAtoms.cpp.func.html create mode 100644 coverage/core/MDAtoms.cpp.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/Group.cpp.func-sort-c.html create mode 100644 coverage/generic/Group.cpp.func.html create mode 100644 coverage/generic/Group.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/MolInfo.cpp.func-sort-c.html create mode 100644 coverage/generic/MolInfo.cpp.func.html create mode 100644 coverage/generic/MolInfo.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/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/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/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/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/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 0000000000..e69de29bb2 diff --git a/README.md b/README.md new file mode 100644 index 0000000000..06832aa2f0 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +Coverage scan for PLUMED v2.8 +----------------------------- + +This repository hosts the coverage scan for [PLUMED](http://www.plumed.org) v2.8, +git revision [87ab2b0](https://github.com/plumed/plumed2/commit/87ab2b0). + +Coverage scan done on [GiHub actions](http://github.com/plumed/plumed2/actions) on Mon Jun 10 08:19:16 UTC 2024. + +To browse the scan you should go [here](http://plumed.github.io/coverage-v2.8). + +You can also download a full copy of the scan for offline access +at [this link](http://github.com/plumed/coverage-v2.8/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-06-10 08:19:15Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj69
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE23740
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/arch.cpp.func.html b/coverage-libs/asmjit/arch.cpp.func.html new file mode 100644 index 0000000000..9da751b085 --- /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-06-10 08:19:15Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj69
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE23740
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/arch.cpp.gcov.html b/coverage-libs/asmjit/arch.cpp.gcov.html new file mode 100644 index 0000000000..fd873ba7f9 --- /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-06-10 08:19:15Functions: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          69 : ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t type, uint32_t subType) noexcept {
+      62          69 :   uint32_t index = type < ASMJIT_ARRAY_SIZE(archInfoTable) ? type : uint32_t(0);
+      63             : 
+      64             :   // Make sure the `archInfoTable` array is correctly indexed.
+      65          69 :   _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          69 :   _type = type;
+      71          69 :   _subType = subType;
+      72          69 : }
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::ArchUtils]
+      76             : // ============================================================================
+      77             : 
+      78       23740 : ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept {
+      79       23740 :   uint32_t typeId = typeIdInOut;
+      80             : 
+      81             :   // Zero the signature so it's clear in case that typeId is not invalid.
+      82       23740 :   regInfo._signature = 0;
+      83             : 
+      84             : #if defined(ASMJIT_BUILD_X86)
+      85       23740 :   if (ArchInfo::isX86Family(archType)) {
+      86             :     // Passed RegType instead of TypeId?
+      87       23740 :     if (typeId <= Reg::kRegMax)
+      88           0 :       typeId = x86OpData.archRegs.regTypeToTypeId[typeId];
+      89             : 
+      90       23740 :     if (ASMJIT_UNLIKELY(!TypeId::isValid(typeId)))
+      91             :       return DebugUtils::errored(kErrorInvalidTypeId);
+      92             : 
+      93             :     // First normalize architecture dependent types.
+      94       23740 :     if (TypeId::isAbstract(typeId)) {
+      95        7248 :       if (typeId == TypeId::kIntPtr)
+      96        7248 :         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       23740 :     if (ASMJIT_UNLIKELY(!size))
+     105             :       return DebugUtils::errored(kErrorInvalidTypeId);
+     106             : 
+     107       23740 :     if (ASMJIT_UNLIKELY(typeId == TypeId::kF80))
+     108             :       return DebugUtils::errored(kErrorInvalidUseOfF80);
+     109             : 
+     110             :     uint32_t regType = 0;
+     111             : 
+     112       23740 :     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        7248 :       case TypeId::kI64:
+     129             :       case TypeId::kU64:
+     130        7248 :         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       16492 :       default:
+     163       16492 :         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       23740 :     typeIdInOut = typeId;
+     173       23740 :     regInfo._signature = x86OpData.archRegs.regInfo[regType].getSignature();
+     174       23740 :     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.15
+
+ + + 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 0000000000..0bcb570118 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/arch.h.func.html b/coverage-libs/asmjit/arch.h.func.html new file mode 100644 index 0000000000..222227eaff --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/arch.h.gcov.html b/coverage-libs/asmjit/arch.h.gcov.html new file mode 100644 index 0000000000..56283fc859 --- /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-06-10 08:19:15Functions: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       31516 :   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        7873 :   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        1944 :   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       31516 :   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        3888 :   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        1944 :   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.15
+
+ + + 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 0000000000..721e250599 --- /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-06-10 08:19:15Functions: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_10CodeHolderE1944
_ZN4PLMD6asmjit9AssemblerC2Ev1944
_ZN4PLMD6asmjit9AssemblerD2Ev1944
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE3888
_ZN4PLMD6asmjit9Assembler4syncEv3888
_ZN4PLMD6asmjit9Assembler12_emitOpArrayEjPKNS0_8Operand_Em48254
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.func.html b/coverage-libs/asmjit/assembler.cpp.func.html new file mode 100644 index 0000000000..195109332d --- /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-06-10 08:19:15Functions: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_Em48254
_ZN4PLMD6asmjit9Assembler13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit9Assembler14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE3888
_ZN4PLMD6asmjit9Assembler4syncEv3888
_ZN4PLMD6asmjit9Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit9Assembler5embedEPKvj0
_ZN4PLMD6asmjit9Assembler7commentEPKcm0
_ZN4PLMD6asmjit9Assembler8_emitLogEjjRKNS0_8Operand_ES4_S4_S4_jjPh0
_ZN4PLMD6asmjit9Assembler8newLabelEv0
_ZN4PLMD6asmjit9Assembler8onAttachEPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit9Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit9Assembler9setOffsetEm0
_ZN4PLMD6asmjit9AssemblerC2Ev1944
_ZN4PLMD6asmjit9AssemblerD0Ev0
_ZN4PLMD6asmjit9AssemblerD2Ev1944
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.gcov.html b/coverage-libs/asmjit/assembler.cpp.gcov.html new file mode 100644 index 0000000000..20d1b9a905 --- /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-06-10 08:19:15Functions: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        1944 : Assembler::Assembler() noexcept
+      49             :   : CodeEmitter(kTypeAssembler),
+      50        1944 :     _section(nullptr),
+      51        1944 :     _bufferData(nullptr),
+      52        1944 :     _bufferEnd(nullptr),
+      53        1944 :     _bufferPtr(nullptr),
+      54        1944 :     _op4(),
+      55        1944 :     _op5() {}
+      56             : 
+      57        1944 : Assembler::~Assembler() noexcept {
+      58        1944 :   if (_code) sync();
+      59        1944 : }
+      60             : 
+      61             : // ============================================================================
+      62             : // [asmjit::Assembler - Events]
+      63             : // ============================================================================
+      64             : 
+      65        1944 : Error Assembler::onAttach(CodeHolder* code) noexcept {
+      66             :   // Attach to the end of the .text section.
+      67        1944 :   _section = code->_sections[0];
+      68        1944 :   uint8_t* p = _section->_buffer._data;
+      69             : 
+      70        1944 :   _bufferData = p;
+      71        1944 :   _bufferEnd  = p + _section->_buffer._capacity;
+      72        1944 :   _bufferPtr  = p + _section->_buffer._length;
+      73             : 
+      74             :   _op4.reset();
+      75             :   _op5.reset();
+      76             : 
+      77        1944 :   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       48254 : Error Assembler::_emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) {
+     104             :   const Operand_* op = opArray;
+     105       48254 :   switch (opCount) {
+     106        1944 :     case 0: return _emit(instId, _none, _none, _none, _none);
+     107        3852 :     case 1: return _emit(instId, op[0], _none, _none, _none);
+     108       42338 :     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        3888 : 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        3888 :   size_t offset = (size_t)(_bufferPtr - _bufferData);
+     140        3888 :   if (_section->getBuffer().getLength() < offset)
+     141        1944 :     _section->_buffer._length = offset;
+     142        3888 : }
+     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        3888 : Error Assembler::bind(const Label& label) {
+     212        3888 :   if (_lastError) return _lastError;
+     213             :   ASMJIT_ASSERT(_code != nullptr);
+     214             : 
+     215        3888 :   LabelEntry* le = _code->getLabelEntry(label);
+     216        3888 :   if (ASMJIT_UNLIKELY(!le))
+     217           0 :     return setLastError(DebugUtils::errored(kErrorInvalidLabel));
+     218             : 
+     219             :   // Label can be bound only once.
+     220        3888 :   if (ASMJIT_UNLIKELY(le->isBound()))
+     221           0 :     return setLastError(DebugUtils::errored(kErrorLabelAlreadyBound));
+     222             : 
+     223             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     224        3888 :   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        3888 :   LabelLink* link = le->_links;
+     244             :   LabelLink* prev = nullptr;
+     245             : 
+     246        3888 :   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        3888 :   le->_sectionId = _section->getId();
+     280        3888 :   le->_offset = pos;
+     281        3888 :   le->_links = nullptr;
+     282             :   resetInlineComment();
+     283             : 
+     284        3888 :   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.15
+
+ + + 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 0000000000..cf5e3bda20 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/assembler.h.func.html b/coverage-libs/asmjit/assembler.h.func.html new file mode 100644 index 0000000000..51c43b85af --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/assembler.h.gcov.html b/coverage-libs/asmjit/assembler.h.gcov.html new file mode 100644 index 0000000000..977a13836e --- /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-06-10 08:19:15Functions: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        5832 :   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.15
+
+ + + 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 0000000000..575cfd5d98 --- /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-06-10 08:19:15Functions: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
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv1944
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE1944
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE1944
_ZN4PLMD6asmjit11CodeBuilderC2Ev1944
_ZN4PLMD6asmjit11CodeBuilderD2Ev1944
_ZN4PLMD6asmjit6CBPassC2EPKc1944
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE3888
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE3888
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE56030
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.func.html b/coverage-libs/asmjit/codebuilder.cpp.func.html new file mode 100644 index 0000000000..da21310cdf --- /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-06-10 08:19:15Functions: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
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv1944
_ZN4PLMD6asmjit11CodeBuilder13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit11CodeBuilder14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit11CodeBuilder14newCommentNodeEPKcm0
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE3888
_ZN4PLMD6asmjit11CodeBuilder4bindERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder5alignEjj0
_ZN4PLMD6asmjit11CodeBuilder5embedEPKvj0
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE56030
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE1944
_ZN4PLMD6asmjit11CodeBuilder7commentEPKcm0
_ZN4PLMD6asmjit11CodeBuilder8addAfterEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder8newLabelEv0
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit11CodeBuilder8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeBuilder9addBeforeEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE1944
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE3888
_ZN4PLMD6asmjit11CodeBuilderC2Ev1944
_ZN4PLMD6asmjit11CodeBuilderD0Ev0
_ZN4PLMD6asmjit11CodeBuilderD2Ev1944
_ZN4PLMD6asmjit6CBPassC2EPKc1944
_ZN4PLMD6asmjit6CBPassD0Ev0
_ZN4PLMD6asmjit6CBPassD2Ev0
_ZNK4PLMD6asmjit11CodeBuilder13getPassByNameEPKc0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.gcov.html b/coverage-libs/asmjit/codebuilder.cpp.gcov.html new file mode 100644 index 0000000000..0420c69d9b --- /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-06-10 08:19:15Functions: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        1944 : CodeBuilder::CodeBuilder() noexcept
+      50             :   : CodeEmitter(kTypeBuilder),
+      51        1944 :     _cbBaseZone(32768 - Zone::kZoneOverhead),
+      52        1944 :     _cbDataZone(16384 - Zone::kZoneOverhead),
+      53        1944 :     _cbPassZone(32768 - Zone::kZoneOverhead),
+      54        1944 :     _cbHeap(&_cbBaseZone),
+      55             :     _cbPasses(),
+      56             :     _cbLabels(),
+      57        1944 :     _firstNode(nullptr),
+      58        1944 :     _lastNode(nullptr),
+      59        1944 :     _cursor(nullptr),
+      60        1944 :     _position(0),
+      61        1944 :     _nodeFlags(0) {}
+      62        1944 : CodeBuilder::~CodeBuilder() noexcept {}
+      63             : 
+      64             : // ============================================================================
+      65             : // [asmjit::CodeBuilder - Events]
+      66             : // ============================================================================
+      67             : 
+      68        1944 : Error CodeBuilder::onAttach(CodeHolder* code) noexcept {
+      69        1944 :   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        3888 : Error CodeBuilder::registerLabelNode(CBLabel* node) noexcept {
+     119        3888 :   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        3888 :   ASMJIT_PROPAGATE(_code->newLabelId(id));
+     126        3888 :   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        3888 :   ASMJIT_PROPAGATE(_cbLabels.resize(&_cbHeap, index + 1));
+     131             : 
+     132        3888 :   _cbLabels[index] = node;
+     133        3888 :   node->_id = id;
+     134        3888 :   return kErrorOk;
+     135             : }
+     136             : 
+     137        1944 : CBLabel* CodeBuilder::newLabelNode() noexcept {
+     138             :   CBLabel* node = newNodeT<CBLabel>();
+     139        1944 :   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       56030 : CBNode* CodeBuilder::addNode(CBNode* node) noexcept {
+     302             :   ASMJIT_ASSERT(node);
+     303             :   ASMJIT_ASSERT(node->_prev == nullptr);
+     304             :   ASMJIT_ASSERT(node->_next == nullptr);
+     305             : 
+     306       56030 :   if (!_cursor) {
+     307        1944 :     if (!_firstNode) {
+     308        1944 :       _firstNode = node;
+     309        1944 :       _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       54086 :     CBNode* next = _cursor->_next;
+     320             : 
+     321       54086 :     node->_prev = prev;
+     322       54086 :     node->_next = next;
+     323             : 
+     324       54086 :     prev->_next = node;
+     325       54086 :     if (next)
+     326       50198 :       next->_prev = node;
+     327             :     else
+     328        3888 :       _lastNode = node;
+     329             :   }
+     330             : 
+     331       56030 :   _cursor = node;
+     332       56030 :   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        3888 : CBNode* CodeBuilder::setCursor(CBNode* node) noexcept {
+     467        3888 :   CBNode* old = _cursor;
+     468        3888 :   _cursor = node;
+     469        3888 :   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        1944 : ASMJIT_FAVOR_SIZE Error CodeBuilder::addPass(CBPass* pass) noexcept {
+     487        1944 :   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        1944 :   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        1944 :   ASMJIT_PROPAGATE(_cbPasses.append(&_cbHeap, pass));
+     500        1944 :   pass->_cb = this;
+     501        1944 :   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        1944 : Error CodeBuilder::serialize(CodeEmitter* dst) {
+     528             :   Error err = kErrorOk;
+     529             :   CBNode* node_ = getFirstNode();
+     530             : 
+     531             :   do {
+     532             :     dst->setInlineComment(node_->getInlineComment());
+     533             : 
+     534       56030 :     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        3888 :       case CBNode::kNodeFunc:
+     548             :       case CBNode::kNodeLabel: {
+     549             :         CBLabel* node = static_cast<CBLabel*>(node_);
+     550        3888 :         err = dst->bind(node->getLabel());
+     551        3888 :         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       48254 :         err = dst->emitOpArray(node->getInstId(), node->getOpArray(), node->getOpCount());
+     572       48254 :         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       56030 :     if (err) break;
+     586             :     node_ = node_->getNext();
+     587       56030 :   } while (node_);
+     588             : 
+     589        1944 :   return err;
+     590             : }
+     591             : 
+     592             : // ============================================================================
+     593             : // [asmjit::CBPass]
+     594             : // ============================================================================
+     595             : 
+     596        1944 : CBPass::CBPass(const char* name) noexcept
+     597        1944 :   : _cb(nullptr),
+     598        1944 :     _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.15
+
+ + + 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 0000000000..81d32248aa --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.h.func.html b/coverage-libs/asmjit/codebuilder.h.func.html new file mode 100644 index 0000000000..b9e8f541ac --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.h.gcov.html b/coverage-libs/asmjit/codebuilder.h.gcov.html new file mode 100644 index 0000000000..42fc51ea18 --- /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-06-10 08:19:15Functions: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        3888 :   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        3888 :   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        1944 :   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        1944 :   ASMJIT_INLINE CBNode* getCursor() const noexcept { return _cursor; }
+     186             :   //! Set the current node without returning the previous node.
+     187        9412 :   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        1944 :   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        1944 :   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        1944 :   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       56030 :   ASMJIT_INLINE CBNode(CodeBuilder* cb, uint32_t type) noexcept {
+     369       56030 :     _prev = nullptr;
+     370       56030 :     _next = nullptr;
+     371       54086 :     _type = static_cast<uint8_t>(type);
+     372        7776 :     _opCount = 0;
+     373       56030 :     _flags = static_cast<uint16_t>(cb->_nodeFlags);
+     374       56030 :     _position = cb->_position;
+     375       56030 :     _inlineComment = nullptr;
+     376       50506 :     _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       73260 :   ASMJIT_INLINE CBNode* getPrev() const noexcept { return _prev; }
+     392             :   //! Get next node in the compiler stream.
+     393      144610 :   ASMJIT_INLINE CBNode* getNext() const noexcept { return _next; }
+     394             : 
+     395             :   //! Get the node type, see \ref Type.
+     396      250920 :   ASMJIT_INLINE uint32_t getType() const noexcept { return _type; }
+     397             :   //! Get the node flags.
+     398       31106 :   ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+     399             : 
+     400             :   //! Get whether the instruction has flag `flag`.
+     401      170672 :   ASMJIT_INLINE bool hasFlag(uint32_t flag) const noexcept { return (static_cast<uint32_t>(_flags) & flag) != 0; }
+     402             :   //! Set node flags to `flags`.
+     403       31106 :   ASMJIT_INLINE void setFlags(uint32_t flags) noexcept { _flags = static_cast<uint16_t>(flags); }
+     404             :   //! Add instruction `flags`.
+     405        1944 :   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       40518 :   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       56030 :   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      111834 :   ASMJIT_INLINE bool hasPassData() const noexcept { return _passData != nullptr; }
+     452             :   //! Get work-data - data used during processing & transformations.
+     453             :   template<typename T>
+     454      329748 :   ASMJIT_INLINE T* getPassData() const noexcept { return (T*)_passData; }
+     455             :   //! Set work-data to `data`.
+     456             :   template<typename T>
+     457       40518 :   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       48254 :     : CBNode(cb, kNodeInst) {
+     495             : 
+     496             :     orFlags(kFlagIsRemovable);
+     497       48254 :     _instDetail.instId = static_cast<uint16_t>(instId);
+     498       48254 :     _instDetail.options = options;
+     499             : 
+     500       48254 :     _opCount = static_cast<uint8_t>(opCount);
+     501       48254 :     _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       79360 :   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       79118 :   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       48254 :   ASMJIT_INLINE uint32_t getOpCount() const noexcept { return _opCount; }
+     550             :   //! Get operands list.
+     551      112102 :   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       40846 :   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       14496 :     return static_cast<T*>(&_opArray[_memOpIndex]);
+     570             :   }
+     571             : 
+     572             :   //! Set memory operand index, `0xFF` means no memory operand.
+     573       54322 :   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      118400 :     for (i = 0; i < opCount; i++)
+     587       84642 :       if (opArray[i].isMem())
+     588       14496 :         goto Update;
+     589             :     i = 0xFF;
+     590             : 
+     591       48254 : 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        3888 :     : CBNode(cb, kNodeLabel),
+     767        3888 :       _id(id),
+     768        3888 :       _numRefs(0),
+     769        3888 :       _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        3888 :   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.15
+
+ + + 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 0000000000..d27356312b --- /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-06-10 08:19:15Functions: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_E1636
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1636
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1636
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E1850
_ZN4PLMD6asmjit12CodeCompiler6addRetERKNS0_8Operand_ES4_1944
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_1944
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE1944
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE1944
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv1944
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE1944
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit12CodeCompilerC2Ev1944
_ZN4PLMD6asmjit12CodeCompilerD2Ev1944
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc23740
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc23740
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.func.html b/coverage-libs/asmjit/codecompiler.cpp.func.html new file mode 100644 index 0000000000..5c9630c646 --- /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-06-10 08:19:15Functions:153641.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E1850
_ZN4PLMD6asmjit10CCFuncCall7_setRetEjRKNS0_8Operand_E1636
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc23740
_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_1944
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_1944
_ZN4PLMD6asmjit12CodeCompiler6renameERNS0_3RegEPKcz0
_ZN4PLMD6asmjit12CodeCompiler6setArgEjRKNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKc0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc23740
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1636
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE1944
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE1944
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv1944
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1636
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE1944
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit12CodeCompiler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12CodeCompiler9_newConstERNS0_3MemEjPKvm0
_ZN4PLMD6asmjit12CodeCompiler9_newStackERNS0_3MemEjjPKc0
_ZN4PLMD6asmjit12CodeCompilerC2Ev1944
_ZN4PLMD6asmjit12CodeCompilerD0Ev0
_ZN4PLMD6asmjit12CodeCompilerD2Ev1944
_ZNK4PLMD6asmjit12CodeCompiler11getPriorityERNS0_3RegE0
_ZNK4PLMD6asmjit12CodeCompiler14getSaveOnUnuseERNS0_3RegE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.gcov.html b/coverage-libs/asmjit/codecompiler.cpp.gcov.html new file mode 100644 index 0000000000..8d10c77423 --- /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-06-10 08:19:15Functions: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        1850 : bool CCFuncCall::_setArg(uint32_t i, const Operand_& op) noexcept {
+      62        1850 :   if ((i & ~kFuncArgHi) >= _funcDetail.getArgCount())
+      63             :     return false;
+      64             : 
+      65        1850 :   _args[i] = op;
+      66        1850 :   return true;
+      67             : }
+      68             : 
+      69        1636 : bool CCFuncCall::_setRet(uint32_t i, const Operand_& op) noexcept {
+      70        1636 :   if (i >= 2)
+      71             :     return false;
+      72             : 
+      73        1636 :   _ret[i] = op;
+      74        1636 :   return true;
+      75             : }
+      76             : 
+      77             : // ============================================================================
+      78             : // [asmjit::CodeCompiler - Construction / Destruction]
+      79             : // ============================================================================
+      80             : 
+      81        1944 : CodeCompiler::CodeCompiler() noexcept
+      82             :   : CodeBuilder(),
+      83        1944 :     _func(nullptr),
+      84        1944 :     _vRegZone(4096 - Zone::kZoneOverhead),
+      85             :     _vRegArray(),
+      86        1944 :     _localConstPool(nullptr),
+      87        1944 :     _globalConstPool(nullptr) {
+      88             : 
+      89        1944 :   _type = kTypeCompiler;
+      90        1944 : }
+      91        1944 : CodeCompiler::~CodeCompiler() noexcept {}
+      92             : 
+      93             : // ============================================================================
+      94             : // [asmjit::CodeCompiler - Events]
+      95             : // ============================================================================
+      96             : 
+      97        1944 : Error CodeCompiler::onAttach(CodeHolder* code) noexcept {
+      98        1944 :   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        1944 : CCFunc* CodeCompiler::newFunc(const FuncSignature& sign) noexcept {
+     129             :   Error err;
+     130             : 
+     131             :   CCFunc* func = newNodeT<CCFunc>();
+     132        1944 :   if (!func) goto _NoMemory;
+     133             : 
+     134        1944 :   err = registerLabelNode(func);
+     135        1944 :   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        1944 :   func->_exitNode = newLabelNode();
+     143        1944 :   func->_end = newNodeT<CBSentinel>();
+     144             : 
+     145        1944 :   if (!func->_exitNode || !func->_end)
+     146           0 :     goto _NoMemory;
+     147             : 
+     148             :   // Function prototype.
+     149        1944 :   err = func->getDetail().init(sign);
+     150        1944 :   if (err != kErrorOk) {
+     151           0 :     setLastError(err);
+     152           0 :     return nullptr;
+     153             :   }
+     154             : 
+     155             :   // If the CodeInfo guarantees higher alignment honor it.
+     156        1944 :   if (_codeInfo.getStackAlignment() > func->_funcDetail._callConv.getNaturalStackAlignment())
+     157             :     func->_funcDetail._callConv.setNaturalStackAlignment(_codeInfo.getStackAlignment());
+     158             : 
+     159             :   // Allocate space for function arguments.
+     160        1944 :   func->_args = nullptr;
+     161        1944 :   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        1944 : CCFunc* CodeCompiler::addFunc(CCFunc* func) {
+     176             :   ASMJIT_ASSERT(_func == nullptr);
+     177        1944 :   _func = func;
+     178             : 
+     179        1944 :   addNode(func);                 // Function node.
+     180             :   CBNode* cursor = getCursor();  // {CURSOR}.
+     181        1944 :   addNode(func->getExitNode());  // Function exit label.
+     182        1944 :   addNode(func->getEnd());       // Function end marker.
+     183             : 
+     184             :   _setCursor(cursor);
+     185        1944 :   return func;
+     186             : }
+     187             : 
+     188        1944 : CCFunc* CodeCompiler::addFunc(const FuncSignature& sign) {
+     189        1944 :   CCFunc* func = newFunc(sign);
+     190             : 
+     191        1944 :   if (!func) {
+     192           0 :     setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     193           0 :     return nullptr;
+     194             :   }
+     195             : 
+     196        1944 :   return addFunc(func);
+     197             : }
+     198             : 
+     199        1944 : CBSentinel* CodeCompiler::endFunc() {
+     200             :   CCFunc* func = getFunc();
+     201        1944 :   if (!func) {
+     202             :     // TODO:
+     203             :     return nullptr;
+     204             :   }
+     205             : 
+     206             :   // Add the local constant pool at the end of the function (if exists).
+     207        1944 :   if (_localConstPool) {
+     208           0 :     setCursor(func->getEnd()->getPrev());
+     209           0 :     addNode(_localConstPool);
+     210           0 :     _localConstPool = nullptr;
+     211             :   }
+     212             : 
+     213             :   // Mark as finished.
+     214        1944 :   func->_isFinished = true;
+     215        1944 :   _func = nullptr;
+     216             : 
+     217             :   CBSentinel* end = func->getEnd();
+     218        1944 :   setCursor(end);
+     219        1944 :   return end;
+     220             : }
+     221             : 
+     222             : // ============================================================================
+     223             : // [asmjit::CodeCompiler - Ret]
+     224             : // ============================================================================
+     225             : 
+     226        1944 : CCFuncRet* CodeCompiler::newRet(const Operand_& o0, const Operand_& o1) noexcept {
+     227        1944 :   CCFuncRet* node = newNodeT<CCFuncRet>(o0, o1);
+     228        1944 :   if (!node) {
+     229           0 :     setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     230           0 :     return nullptr;
+     231             :   }
+     232             :   return node;
+     233             : }
+     234             : 
+     235        1944 : CCFuncRet* CodeCompiler::addRet(const Operand_& o0, const Operand_& o1) noexcept {
+     236        1944 :   CCFuncRet* node = newRet(o0, o1);
+     237        1944 :   if (!node) return nullptr;
+     238        1944 :   return static_cast<CCFuncRet*>(addNode(node));
+     239             : }
+     240             : 
+     241             : // ============================================================================
+     242             : // [asmjit::CodeCompiler - Call]
+     243             : // ============================================================================
+     244             : 
+     245        1636 : CCFuncCall* CodeCompiler::newCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
+     246             :   Error err;
+     247             :   uint32_t nArgs;
+     248             : 
+     249        1636 :   CCFuncCall* node = _cbHeap.allocT<CCFuncCall>(sizeof(CCFuncCall) + sizeof(Operand));
+     250        1636 :   Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CCFuncCall));
+     251             : 
+     252        1636 :   if (ASMJIT_UNLIKELY(!node))
+     253           0 :     goto _NoMemory;
+     254             : 
+     255        1636 :   opArray[0].copyFrom(o0);
+     256             :   new (node) CCFuncCall(this, instId, 0, opArray, 1);
+     257             : 
+     258        1636 :   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        1636 :   if ((nArgs = sign.getArgCount()) == 0)
+     265             :     return node;
+     266             : 
+     267        1636 :   node->_args = static_cast<Operand*>(_cbHeap.alloc(nArgs * sizeof(Operand)));
+     268        1636 :   if (!node->_args) goto _NoMemory;
+     269             : 
+     270             :   ::memset(node->_args, 0, nArgs * sizeof(Operand));
+     271        1636 :   return node;
+     272             : 
+     273           0 : _NoMemory:
+     274           0 :   setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     275           0 :   return nullptr;
+     276             : }
+     277             : 
+     278        1636 : CCFuncCall* CodeCompiler::addCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
+     279        1636 :   CCFuncCall* node = newCall(instId, o0, sign);
+     280        1636 :   if (!node) return nullptr;
+     281        1636 :   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       23740 : VirtReg* CodeCompiler::newVirtReg(uint32_t typeId, uint32_t signature, const char* name) noexcept {
+     322             :   size_t index = _vRegArray.getLength();
+     323       23740 :   if (ASMJIT_UNLIKELY(index > Operand::kPackedIdCount))
+     324             :     return nullptr;
+     325             : 
+     326             :   VirtReg* vreg;
+     327       28978 :   if (_vRegArray.willGrow(&_cbHeap, 1) != kErrorOk || !(vreg = _vRegZone.allocZeroedT<VirtReg>()))
+     328           0 :     return nullptr;
+     329             : 
+     330       23740 :   vreg->_id = Operand::packId(static_cast<uint32_t>(index));
+     331       23740 :   vreg->_regInfo._signature = signature;
+     332       23740 :   vreg->_name = noName;
+     333             : 
+     334             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     335       23740 :   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       23740 :   vreg->_size = TypeId::sizeOf(typeId);
+     340       23740 :   vreg->_typeId = typeId;
+     341       23740 :   vreg->_alignment = static_cast<uint8_t>(std::min<uint32_t>(vreg->_size, 64));
+     342       23740 :   vreg->_priority = 10;
+     343             : 
+     344             :   // The following are only used by `RAPass`.
+     345       23740 :   vreg->_raId = kInvalidValue;
+     346       23740 :   vreg->_state = VirtReg::kStateNone;
+     347       23740 :   vreg->_physId = Globals::kInvalidRegId;
+     348             : 
+     349             :   _vRegArray.appendUnsafe(vreg);
+     350       23740 :   return vreg;
+     351             : }
+     352             : 
+     353       23740 : Error CodeCompiler::_newReg(Reg& out, uint32_t typeId, const char* name) {
+     354             :   RegInfo regInfo;
+     355             : 
+     356       23740 :   Error err = ArchUtils::typeIdToRegInfo(getArchType(), typeId, regInfo);
+     357       23740 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     358             : 
+     359       23740 :   VirtReg* vReg = newVirtReg(typeId, regInfo.getSignature(), name);
+     360       23740 :   if (ASMJIT_UNLIKELY(!vReg)) {
+     361             :     out.reset();
+     362           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     363             :   }
+     364             : 
+     365             :   out._initReg(regInfo.getSignature(), vReg->getId());
+     366       23740 :   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.15
+
+ + + 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 0000000000..96dcae4893 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.h.func.html b/coverage-libs/asmjit/codecompiler.h.func.html new file mode 100644 index 0000000000..92abd0edaf --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.h.gcov.html b/coverage-libs/asmjit/codecompiler.h.gcov.html new file mode 100644 index 0000000000..0f30f3a7ba --- /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-06-10 08:19:15Functions: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       32168 :   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       25856 :   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       24694 :   }
+     131             : 
+     132             :   //! Get register index.
+     133      181318 :   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       49960 :     _physId = static_cast<uint8_t>(Globals::kInvalidRegId);
+     142             :   }
+     143             : 
+     144             :   //! Get home registers mask.
+     145       26376 :   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       27864 :   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       10072 :   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       10458 :   ASMJIT_INLINE bool isModified() const noexcept { return static_cast<bool>(_modified); }
+     159             :   //! Set whether the variable was changed.
+     160       88716 :   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        1944 :     : CBLabel(cb),
+     298        1944 :       _funcDetail(),
+     299        1944 :       _frameInfo(),
+     300        1944 :       _exitNode(nullptr),
+     301        1944 :       _end(nullptr),
+     302        1944 :       _args(nullptr),
+     303        1944 :       _isFinished(false) {
+     304             : 
+     305        1944 :     _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        7776 :   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        7776 :   ASMJIT_INLINE CBSentinel* getEnd() const noexcept { return _end; }
+     322             : 
+     323             :   //! Get function declaration.
+     324        1944 :   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        1944 :   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        1944 :   ASMJIT_INLINE CCFuncRet(CodeBuilder* cb, const Operand_& o0, const Operand_& o1) noexcept : CBNode(cb, kNodeFuncExit) {
+     393             :     orFlags(kFlagIsRet);
+     394        1944 :     _ret[0].copyFrom(o0);
+     395        1944 :     _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        1636 :     : CBInst(cb, instId, options, opArray, opCount),
+     439        1636 :       _funcDetail(),
+     440        1636 :       _args(nullptr) {
+     441             : 
+     442        1636 :     _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        1434 :   ASMJIT_INLINE bool setArg(uint32_t i, const Reg& reg) noexcept { return _setArg(i, reg); }
+     503             :   //! Set argument at `i` to `imm`.
+     504         202 :   ASMJIT_INLINE bool setArg(uint32_t i, const Imm& imm) noexcept { return _setArg(i, imm); }
+     505             : 
+     506             :   //! Set return at `i` to `var`.
+     507        1636 :   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        1944 :   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       12136 :     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      116154 :     size_t index = Operand::unpackId(id);
+     705             : 
+     706             :     ASMJIT_ASSERT(index < _vRegArray.getLength());
+     707      128290 :     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.15
+
+ + + 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 0000000000..21d1d8c86f --- /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-06-10 08:19:15Functions: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
_ZN4PLMD6asmjit11CodeEmitter4emitEj1944
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E2216
_ZN4PLMD6asmjit11CodeEmitter8onAttachEPNS0_10CodeHolderE3888
_ZN4PLMD6asmjit11CodeEmitterC2Ej3888
_ZN4PLMD6asmjit11CodeEmitterD2Ev3888
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_40474
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.func.html b/coverage-libs/asmjit/codeemitter.cpp.func.html new file mode 100644 index 0000000000..26c198b8fa --- /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-06-10 08:19:15Functions:93129.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeEmitter12_emitOpArrayEjPKNS0_8Operand_Em0
_ZN4PLMD6asmjit11CodeEmitter12setLastErrorEjPKc0
_ZN4PLMD6asmjit11CodeEmitter14getLabelByNameEPKcmj0
_ZN4PLMD6asmjit11CodeEmitter4emitEj1944
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E2216
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_40474
_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_10CodeHolderE3888
_ZN4PLMD6asmjit11CodeEmitter8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeEmitterC2Ej3888
_ZN4PLMD6asmjit11CodeEmitterD0Ev0
_ZN4PLMD6asmjit11CodeEmitterD2Ev3888
_ZNK4PLMD6asmjit11CodeEmitter12isLabelValidEj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.gcov.html b/coverage-libs/asmjit/codeemitter.cpp.gcov.html new file mode 100644 index 0000000000..2d689f2143 --- /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-06-10 08:19:15Functions: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        3888 : CodeEmitter::CodeEmitter(uint32_t type) noexcept
+      56             :   : _codeInfo(),
+      57        3888 :     _code(nullptr),
+      58        3888 :     _nextEmitter(nullptr),
+      59        3888 :     _type(static_cast<uint8_t>(type)),
+      60        3888 :     _destroyed(false),
+      61        3888 :     _finalized(false),
+      62        3888 :     _reserved(false),
+      63        3888 :     _lastError(kErrorNotInitialized),
+      64        3888 :     _privateData(0),
+      65        3888 :     _globalHints(0),
+      66        3888 :     _globalOptions(kOptionMaybeFailureCase),
+      67        3888 :     _options(0),
+      68        3888 :     _extraReg(),
+      69        3888 :     _inlineComment(nullptr),
+      70        3888 :     _none(),
+      71             :     _nativeGpReg(),
+      72        3888 :     _nativeGpArray(nullptr) {}
+      73             : 
+      74        3888 : CodeEmitter::~CodeEmitter() noexcept {
+      75        3888 :   if (_code) {
+      76        3888 :     _destroyed = true;
+      77        3888 :     _code->detach(this);
+      78             :   }
+      79        3888 : }
+      80             : 
+      81             : // ============================================================================
+      82             : // [asmjit::CodeEmitter - Events]
+      83             : // ============================================================================
+      84             : 
+      85        3888 : Error CodeEmitter::onAttach(CodeHolder* code) noexcept {
+      86             :   _codeInfo = code->getCodeInfo();
+      87        3888 :   _lastError = kErrorOk;
+      88             : 
+      89        3888 :   _globalHints = code->getGlobalHints();
+      90        3888 :   _globalOptions = code->getGlobalOptions();
+      91             : 
+      92        3888 :   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        1944 : Error CodeEmitter::emit(uint32_t instId) { return _emit(instId, _none, _none, _none, _none); }
+     232        2216 : Error CodeEmitter::emit(uint32_t instId, OP o0) { return _emit(instId, o0, _none, _none, _none); }
+     233       40474 : 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.15
+
+ + + 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 0000000000..15bb8aa6b6 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.h.func.html b/coverage-libs/asmjit/codeemitter.h.func.html new file mode 100644 index 0000000000..990c79d438 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.h.gcov.html b/coverage-libs/asmjit/codeemitter.h.gcov.html new file mode 100644 index 0000000000..ef58fcbd39 --- /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-06-10 08:19:15Functions: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        7776 :   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       98760 :   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       94872 :   ASMJIT_INLINE uint32_t getOptions() const noexcept { return _options; }
+     336             :   //! Set options of the next instruction.
+     337       48254 :   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       94872 :   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       46618 :   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       65114 :   ASMJIT_INLINE void setInlineComment(const char* s) noexcept { _inlineComment = s; }
+     362             :   //! Reset annotation of the next instruction to null.
+     363       98760 :   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       48254 :     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.15
+
+ + + 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 0000000000..f7db41ae2a --- /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-06-10 08:19:15Functions: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_10CodeBufferEm1944
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE1944
_ZN4PLMD6asmjit10CodeHolderC2Ev1944
_ZN4PLMD6asmjit10CodeHolderD2Ev1944
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb1944
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm1944
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm1944
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj3888
_ZN4PLMD6asmjit10CodeHolder4syncEv3888
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE3888
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE3888
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv3888
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.func.html b/coverage-libs/asmjit/codeholder.cpp.func.html new file mode 100644 index 0000000000..63a30b6c92 --- /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-06-10 08:19:15Functions:122548.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CodeHolder10growBufferEPNS0_10CodeBufferEm1944
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj3888
_ZN4PLMD6asmjit10CodeHolder12newLabelLinkEPNS0_10LabelEntryEjml0
_ZN4PLMD6asmjit10CodeHolder13newRelocEntryEPPNS0_10RelocEntryEjj0
_ZN4PLMD6asmjit10CodeHolder13reserveBufferEPNS0_10CodeBufferEm0
_ZN4PLMD6asmjit10CodeHolder15newNamedLabelIdERjPKcmjj0
_ZN4PLMD6asmjit10CodeHolder15setErrorHandlerEPNS0_12ErrorHandlerE0
_ZN4PLMD6asmjit10CodeHolder16getLabelIdByNameEPKcmj0
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE1944
_ZN4PLMD6asmjit10CodeHolder4syncEv3888
_ZN4PLMD6asmjit10CodeHolder5resetEb0
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE3888
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE3888
_ZN4PLMD6asmjit10CodeHolder9setLoggerEPNS0_6LoggerE0
_ZN4PLMD6asmjit10CodeHolderC2Ev1944
_ZN4PLMD6asmjit10CodeHolderD2Ev1944
_ZN4PLMD6asmjit12ErrorHandlerC2Ev0
_ZN4PLMD6asmjit12ErrorHandlerD0Ev0
_ZN4PLMD6asmjit12ErrorHandlerD2Ev0
_ZN4PLMD6asmjit12_GLOBAL__N_1L28CodeHolder_hashNameAndFixLenEPKcRm0
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb1944
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm1944
_ZN4PLMD6asmjitL26CodeHolder_setGlobalOptionEPNS0_10CodeHolderEjj0
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv3888
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm1944
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.gcov.html b/coverage-libs/asmjit/codeholder.cpp.gcov.html new file mode 100644 index 0000000000..677f49a610 --- /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-06-10 08:19:15Functions: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        1944 : static void CodeHolder_resetInternal(CodeHolder* self, bool releaseMemory) noexcept {
+      67             :   // Detach all `CodeEmitter`s.
+      68        1944 :   while (self->_emitters)
+      69           0 :     self->detach(self->_emitters);
+      70             : 
+      71             :   // Reset everything into its construction state.
+      72             :   self->_codeInfo.reset();
+      73        1944 :   self->_globalHints = 0;
+      74        1944 :   self->_globalOptions = 0;
+      75        1944 :   self->_logger = nullptr;
+      76        1944 :   self->_errorHandler = nullptr;
+      77             : 
+      78        1944 :   self->_unresolvedLabelsCount = 0;
+      79        1944 :   self->_trampolinesSize = 0;
+      80             : 
+      81             :   // Reset all sections.
+      82             :   size_t numSections = self->_sections.getLength();
+      83        3888 :   for (size_t i = 0; i < numSections; i++) {
+      84        1944 :     SectionEntry* section = self->_sections[i];
+      85        1944 :     if (section->_buffer.hasData() && !section->_buffer.isExternal())
+      86             :       Internal::releaseMemory(section->_buffer._data);
+      87        1944 :     section->_buffer._data = nullptr;
+      88        1944 :     section->_buffer._capacity = 0;
+      89             :   }
+      90             : 
+      91             :   // Reset zone allocator and all containers using it.
+      92        1944 :   ZoneHeap* heap = &self->_baseHeap;
+      93             : 
+      94        1944 :   self->_namedLabels.reset(heap);
+      95             :   self->_relocations.reset();
+      96             :   self->_labels.reset();
+      97             :   self->_sections.reset();
+      98             : 
+      99        1944 :   heap->reset(&self->_baseZone);
+     100        1944 :   self->_baseZone.reset(releaseMemory);
+     101        1944 : }
+     102             : 
+     103             : // ============================================================================
+     104             : // [asmjit::CodeHolder - Construction / Destruction]
+     105             : // ============================================================================
+     106             : 
+     107        1944 : CodeHolder::CodeHolder() noexcept
+     108             :   : _codeInfo(),
+     109        1944 :     _globalHints(0),
+     110        1944 :     _globalOptions(0),
+     111        1944 :     _emitters(nullptr),
+     112        1944 :     _cgAsm(nullptr),
+     113        1944 :     _logger(nullptr),
+     114        1944 :     _errorHandler(nullptr),
+     115        1944 :     _unresolvedLabelsCount(0),
+     116        1944 :     _trampolinesSize(0),
+     117        1944 :     _baseZone(16384 - Zone::kZoneOverhead),
+     118        1944 :     _dataZone(16384 - Zone::kZoneOverhead),
+     119        1944 :     _baseHeap(&_baseZone),
+     120        1944 :     _namedLabels(&_baseHeap) {}
+     121             : 
+     122        1944 : CodeHolder::~CodeHolder() noexcept {
+     123        1944 :   CodeHolder_resetInternal(this, true);
+     124        1944 : }
+     125             : 
+     126             : // ============================================================================
+     127             : // [asmjit::CodeHolder - Init / Reset]
+     128             : // ============================================================================
+     129             : 
+     130        1944 : Error CodeHolder::init(const CodeInfo& info) noexcept {
+     131             :   // Cannot reinitialize if it's locked or there is one or more CodeEmitter
+     132             :   // attached.
+     133        1944 :   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        1944 :   Error err = _sections.willGrow(&_baseHeap);
+     141        1944 :   if (err == kErrorOk) {
+     142        1944 :     SectionEntry* se = _baseZone.allocZeroedT<SectionEntry>();
+     143        1944 :     if (ASMJIT_LIKELY(se)) {
+     144        1944 :       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        1944 :   if (ASMJIT_UNLIKELY(err)) {
+     154           0 :     _baseZone.reset(false);
+     155           0 :     return err;
+     156             :   }
+     157             :   else {
+     158             :     _codeInfo = info;
+     159        1944 :     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        3888 : Error CodeHolder::attach(CodeEmitter* emitter) noexcept {
+     172             :   // Catch a possible misuse of the API.
+     173        3888 :   if (!emitter)
+     174             :     return DebugUtils::errored(kErrorInvalidArgument);
+     175             : 
+     176             :   uint32_t type = emitter->getType();
+     177        3888 :   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        3888 :   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        3888 :   if (type == CodeEmitter::kTypeAssembler) {
+     189        1944 :     if (_cgAsm)
+     190             :       return DebugUtils::errored(kErrorSlotOccupied);
+     191        1944 :     pSlot = reinterpret_cast<CodeEmitter**>(&_cgAsm);
+     192             :   }
+     193             : 
+     194        3888 :   Error err = emitter->onAttach(this);
+     195        3888 :   if (err != kErrorOk) return err;
+     196             : 
+     197             :   // Add to a single-linked list of `CodeEmitter`s.
+     198        3888 :   emitter->_nextEmitter = _emitters;
+     199        3888 :   _emitters = emitter;
+     200        3888 :   if (pSlot) *pSlot = emitter;
+     201             : 
+     202             :   // Establish the connection.
+     203        3888 :   emitter->_code = this;
+     204        3888 :   return kErrorOk;
+     205             : }
+     206             : 
+     207        3888 : Error CodeHolder::detach(CodeEmitter* emitter) noexcept {
+     208        3888 :   if (!emitter)
+     209             :     return DebugUtils::errored(kErrorInvalidArgument);
+     210             : 
+     211        3888 :   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        3888 :   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        3888 :   if (type == CodeEmitter::kTypeAssembler)
+     228        1944 :     _cgAsm = nullptr;
+     229             : 
+     230             :   // Remove from a single-linked list of `CodeEmitter`s.
+     231        3888 :   CodeEmitter** pPrev = &_emitters;
+     232             :   for (;;) {
+     233             :     ASMJIT_ASSERT(*pPrev != nullptr);
+     234        3888 :     CodeEmitter* cur = *pPrev;
+     235             : 
+     236        3888 :     if (cur == emitter) {
+     237        3888 :       *pPrev = emitter->_nextEmitter;
+     238             :       break;
+     239             :     }
+     240             : 
+     241           0 :     pPrev = &cur->_nextEmitter;
+     242           0 :   }
+     243             : 
+     244        3888 :   emitter->_code = nullptr;
+     245        3888 :   emitter->_nextEmitter = nullptr;
+     246             : 
+     247        3888 :   return err;
+     248             : }
+     249             : 
+     250             : // ============================================================================
+     251             : // [asmjit::CodeHolder - Sync]
+     252             : // ============================================================================
+     253             : 
+     254        3888 : void CodeHolder::sync() noexcept {
+     255        3888 :   if (_cgAsm) _cgAsm->sync();
+     256        3888 : }
+     257             : 
+     258             : // ============================================================================
+     259             : // [asmjit::CodeHolder - Result Information]
+     260             : // ============================================================================
+     261             : 
+     262        3888 : size_t CodeHolder::getCodeSize() const noexcept {
+     263             :   // Reflect all changes first.
+     264        3888 :   const_cast<CodeHolder*>(this)->sync();
+     265             : 
+     266             :   // TODO: Support sections.
+     267        3888 :   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        1944 : static Error CodeHolder_reserveInternal(CodeHolder* self, CodeBuffer* cb, size_t n) noexcept {
+     294        1944 :   uint8_t* oldData = cb->_data;
+     295             :   uint8_t* newData;
+     296             : 
+     297        1944 :   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        1944 :   if (ASMJIT_UNLIKELY(!newData))
+     303             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     304             : 
+     305        1944 :   cb->_data = newData;
+     306        1944 :   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        1944 :   Assembler* a = self->_cgAsm;
+     312        1944 :   if (a && &a->_section->_buffer == cb) {
+     313             :     size_t offset = a->getOffset();
+     314             : 
+     315        1944 :     a->_bufferData = newData;
+     316        1944 :     a->_bufferEnd  = newData + n;
+     317        1944 :     a->_bufferPtr  = newData + offset;
+     318             :   }
+     319             : 
+     320             :   return kErrorOk;
+     321             : }
+     322             : 
+     323        1944 : 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        1944 :   if (_cgAsm) _cgAsm->sync();
+     329             : 
+     330             :   // Now the length of the section must be valid.
+     331             :   size_t length = cb->getLength();
+     332        1944 :   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        1944 :   size_t required = cb->getLength() + n;
+     339        1944 :   if (ASMJIT_UNLIKELY(required <= capacity)) return kErrorOk;
+     340             : 
+     341        1944 :   if (cb->isFixedSize())
+     342             :     return DebugUtils::errored(kErrorCodeTooLarge);
+     343             : 
+     344        1944 :   if (capacity < 8096)
+     345             :     capacity = 8096;
+     346             :   else
+     347           0 :     capacity += Globals::kAllocOverhead;
+     348             : 
+     349             :   do {
+     350             :     size_t old = capacity;
+     351        1944 :     if (capacity < Globals::kAllocThreshold)
+     352        1944 :       capacity *= 2;
+     353             :     else
+     354           0 :       capacity += Globals::kAllocThreshold;
+     355             : 
+     356        1944 :     if (capacity < Globals::kAllocThreshold)
+     357        1944 :       capacity *= 2;
+     358             :     else
+     359           0 :       capacity += Globals::kAllocThreshold;
+     360             : 
+     361             :     // Overflow.
+     362        1944 :     if (ASMJIT_UNLIKELY(old > capacity))
+     363             :       return DebugUtils::errored(kErrorNoHeapMemory);
+     364        1944 :   } while (capacity - Globals::kAllocOverhead < required);
+     365             : 
+     366        1944 :   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        3888 : Error CodeHolder::newLabelId(uint32_t& idOut) noexcept {
+     450        3888 :   idOut = 0;
+     451             : 
+     452             :   size_t index = _labels.getLength();
+     453        3888 :   if (ASMJIT_LIKELY(index >= Operand::kPackedIdCount))
+     454             :     return DebugUtils::errored(kErrorLabelIndexOverflow);
+     455             : 
+     456        5832 :   ASMJIT_PROPAGATE(_labels.willGrow(&_baseHeap));
+     457        3888 :   LabelEntry* le = _baseHeap.allocZeroedT<LabelEntry>();
+     458             : 
+     459        3888 :   if (ASMJIT_UNLIKELY(!le))
+     460             :     return DebugUtils::errored(kErrorNoHeapMemory);;
+     461             : 
+     462        3888 :   uint32_t id = Operand::packId(static_cast<uint32_t>(index));
+     463             :   le->_setId(id);
+     464        3888 :   le->_parentId = 0;
+     465        3888 :   le->_sectionId = SectionEntry::kInvalidId;
+     466        3888 :   le->_offset = 0;
+     467             : 
+     468             :   _labels.appendUnsafe(le);
+     469        3888 :   idOut = id;
+     470        3888 :   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        1944 : size_t CodeHolder::relocate(void* _dst, uint64_t baseAddress) const noexcept {
+     588        1944 :   SectionEntry* section = _sections[0];
+     589             :   ASMJIT_ASSERT(section != nullptr);
+     590             : 
+     591             :   uint8_t* dst = static_cast<uint8_t*>(_dst);
+     592        1944 :   if (baseAddress == Globals::kNoBaseAddress)
+     593        1944 :     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        1944 :   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        1944 :   ::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        1944 :   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.15
+
+ + + 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 0000000000..11ca24a113 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.h.func.html b/coverage-libs/asmjit/codeholder.h.func.html new file mode 100644 index 0000000000..bf32108f82 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.h.gcov.html b/coverage-libs/asmjit/codeholder.h.gcov.html new file mode 100644 index 0000000000..15dedc414d --- /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-06-10 08:19:15Functions: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        7804 :     : _archInfo(),
+     137        7804 :       _stackAlignment(0),
+     138        7804 :       _cdeclCallConv(CallConv::kIdNone),
+     139        7804 :       _stdCallConv(CallConv::kIdNone),
+     140        7804 :       _fastCallConv(CallConv::kIdNone),
+     141        7804 :       _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        1944 :     return _archInfo._type != ArchInfo::kTypeNone;
+     155             :   }
+     156             : 
+     157             :   ASMJIT_INLINE void init(const CodeInfo& other) noexcept {
+     158        5832 :     _archInfo = other._archInfo;
+     159        5832 :     _packedMiscInfo = other._packedMiscInfo;
+     160        5832 :     _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        1944 :     _stackAlignment = 0;
+     172        1944 :     _cdeclCallConv = CallConv::kIdNone;
+     173        1944 :     _stdCallConv = CallConv::kIdNone;
+     174        1944 :     _fastCallConv = CallConv::kIdNone;
+     175        1944 :     _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        1944 :   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        1944 :   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        5832 :   ASMJIT_INLINE size_t getLength() const noexcept { return _length; }
+     263        1944 :   ASMJIT_INLINE size_t getCapacity() const noexcept { return _capacity; }
+     264             : 
+     265        1944 :   ASMJIT_INLINE bool isExternal() const noexcept { return _isExternal; }
+     266        1944 :   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        3888 :   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        1944 :     _nameAsU32[0] = Utils::pack32_4x8(c0, c1, c2, c3);
+     310        1944 :     _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        3888 :   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        3888 :   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        3888 :   ASMJIT_INLINE uint32_t getGlobalHints() const noexcept { return _globalHints; }
+     575             :   //! Get global options, internally propagated to all `CodeEmitter`s attached.
+     576        3888 :   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        3888 :   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        1944 :   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        3888 :     size_t index = static_cast<size_t>(Operand::unpackId(id));
+     700        3888 :     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.15
+
+ + + 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 0000000000..e7a6f7e5ce --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/constpool.cpp.func.html b/coverage-libs/asmjit/constpool.cpp.func.html new file mode 100644 index 0000000000..146660106f --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/constpool.cpp.gcov.html b/coverage-libs/asmjit/constpool.cpp.gcov.html new file mode 100644 index 0000000000..e2f7ceeff5 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..5876f15d36 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/constpool.h.func.html b/coverage-libs/asmjit/constpool.h.func.html new file mode 100644 index 0000000000..b3019e98e9 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/constpool.h.gcov.html b/coverage-libs/asmjit/constpool.h.gcov.html new file mode 100644 index 0000000000..ab49c9b7d4 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..c2cb0fd420 --- /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-06-10 08:19:15Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7CpuInfo6detectEv69
_ZN4PLMD6asmjitL16x86DetectCpuInfoEPNS0_7CpuInfoE69
_ZN4PLMD6asmjit7CpuInfo7getHostEv1972
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.cpp.func.html b/coverage-libs/asmjit/cpuinfo.cpp.func.html new file mode 100644 index 0000000000..4ed4f48cd7 --- /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-06-10 08:19:15Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7CpuInfo6detectEv69
_ZN4PLMD6asmjit7CpuInfo7getHostEv1972
_ZN4PLMD6asmjitL16x86DetectCpuInfoEPNS0_7CpuInfoE69
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.cpp.gcov.html b/coverage-libs/asmjit/cpuinfo.cpp.gcov.html new file mode 100644 index 0000000000..4a02861888 --- /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-06-10 08:19:15Functions: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         759 :   __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          69 :   __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          69 : }
+     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          69 :   uint32_t dw0 = reinterpret_cast<const uint32_t*>(vendorString)[0];
+     368          69 :   uint32_t dw1 = reinterpret_cast<const uint32_t*>(vendorString)[1];
+     369          69 :   uint32_t dw2 = reinterpret_cast<const uint32_t*>(vendorString)[2];
+     370             : 
+     371         138 :   for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(vendorList); i++) {
+     372         138 :     if (dw0 == reinterpret_cast<const uint32_t*>(vendorList[i].text)[0] &&
+     373          69 :         dw1 == reinterpret_cast<const uint32_t*>(vendorList[i].text)[1] &&
+     374          69 :         dw2 == reinterpret_cast<const uint32_t*>(vendorList[i].text)[2])
+     375          69 :       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          69 :   char curr = s[0];
+     388          69 :   s[0] = '\0';
+     389             : 
+     390             :   for (;;) {
+     391        3312 :     if (curr == 0)
+     392             :       break;
+     393             : 
+     394        3243 :     if (curr == ' ') {
+     395        1380 :       if (prev == '@' || s[1] == ' ' || s[1] == '@')
+     396        1035 :         goto L_Skip;
+     397             :     }
+     398             : 
+     399        2208 :     d[0] = curr;
+     400        2208 :     d++;
+     401             :     prev = curr;
+     402             : 
+     403        3243 : L_Skip:
+     404        3243 :     curr = *++s;
+     405        3243 :     s[0] = '\0';
+     406             :   }
+     407             : 
+     408          69 :   d[0] = '\0';
+     409             : }
+     410             : 
+     411          69 : 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          69 :   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          69 :   maxId = regs.eax;
+     428          69 :   ::memcpy(cpuInfo->_vendorString + 0, &regs.ebx, 4);
+     429          69 :   ::memcpy(cpuInfo->_vendorString + 4, &regs.edx, 4);
+     430          69 :   ::memcpy(cpuInfo->_vendorString + 8, &regs.ecx, 4);
+     431          69 :   cpuInfo->_vendorId = x86GetCpuVendorID(cpuInfo->_vendorString);
+     432             : 
+     433             :   // --------------------------------------------------------------------------
+     434             :   // [CPUID EAX=0x1]
+     435             :   // --------------------------------------------------------------------------
+     436             : 
+     437          69 :   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          69 :     cpuInfo->_family   = (regs.eax >> 8) & 0x0F;
+     443          69 :     cpuInfo->_model    = (regs.eax >> 4) & 0x0F;
+     444          69 :     cpuInfo->_stepping = (regs.eax     ) & 0x0F;
+     445             : 
+     446             :     // Use extended family and model fields.
+     447          69 :     if (cpuInfo->_family == 0x0F) {
+     448          69 :       cpuInfo->_family += ((regs.eax >> 20) & 0xFF);
+     449          69 :       cpuInfo->_model  += ((regs.eax >> 16) & 0x0F) << 4;
+     450             :     }
+     451             : 
+     452          69 :     cpuInfo->_x86Data._processorType        = ((regs.eax >> 12) & 0x03);
+     453          69 :     cpuInfo->_x86Data._brandIndex           = ((regs.ebx      ) & 0xFF);
+     454          69 :     cpuInfo->_x86Data._flushCacheLineSize   = ((regs.ebx >>  8) & 0xFF) * 8;
+     455          69 :     cpuInfo->_x86Data._maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF);
+     456             : 
+     457          69 :     if (regs.ecx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE3);
+     458          69 :     if (regs.ecx & 0x00000002U) cpuInfo->addFeature(CpuInfo::kX86FeaturePCLMULQDQ);
+     459          69 :     if (regs.ecx & 0x00000008U) cpuInfo->addFeature(CpuInfo::kX86FeatureMONITOR);
+     460          69 :     if (regs.ecx & 0x00000200U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSSE3);
+     461          69 :     if (regs.ecx & 0x00002000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCMPXCHG16B);
+     462          69 :     if (regs.ecx & 0x00080000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE4_1);
+     463          69 :     if (regs.ecx & 0x00100000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE4_2);
+     464          69 :     if (regs.ecx & 0x00400000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMOVBE);
+     465          69 :     if (regs.ecx & 0x00800000U) cpuInfo->addFeature(CpuInfo::kX86FeaturePOPCNT);
+     466          69 :     if (regs.ecx & 0x02000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAESNI);
+     467          69 :     if (regs.ecx & 0x04000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureXSAVE);
+     468          69 :     if (regs.ecx & 0x08000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureOSXSAVE);
+     469          69 :     if (regs.ecx & 0x40000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDRAND);
+     470          69 :     if (regs.edx & 0x00000010U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDTSC);
+     471          69 :     if (regs.edx & 0x00000020U) cpuInfo->addFeature(CpuInfo::kX86FeatureMSR);
+     472          69 :     if (regs.edx & 0x00000100U) cpuInfo->addFeature(CpuInfo::kX86FeatureCMPXCHG8B);
+     473          69 :     if (regs.edx & 0x00008000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCMOV);
+     474          69 :     if (regs.edx & 0x00080000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLFLUSH);
+     475          69 :     if (regs.edx & 0x00800000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMMX);
+     476          69 :     if (regs.edx & 0x01000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFXSR);
+     477          69 :     if (regs.edx & 0x02000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE)
+     478             :                                         .addFeature(CpuInfo::kX86FeatureMMX2);
+     479          69 :     if (regs.edx & 0x04000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE)
+     480             :                                         .addFeature(CpuInfo::kX86FeatureSSE2);
+     481          69 :     if (regs.edx & 0x10000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMT);
+     482             : 
+     483             :     // Get the content of XCR0 if supported by CPU and enabled by OS.
+     484          69 :     if ((regs.ecx & 0x0C000000U) == 0x0C000000U) {
+     485             :       x86CallXGetBV(&xcr0, 0);
+     486             :     }
+     487             : 
+     488             :     // Detect AVX+.
+     489          69 :     if (regs.ecx & 0x10000000U) {
+     490             :       // - XCR0[2:1] == 11b
+     491             :       //   XMM & YMM states need to be enabled by OS.
+     492          69 :       if ((xcr0.eax & 0x00000006U) == 0x00000006U) {
+     493             :         cpuInfo->addFeature(CpuInfo::kX86FeatureAVX);
+     494             : 
+     495          69 :         if (regs.ecx & 0x00001000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFMA);
+     496          69 :         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          69 :   if (maxId >= 0x7) {
+     509             :     x86CallCpuId(&regs, 0x7);
+     510             : 
+     511          69 :     if (regs.ebx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureFSGSBASE);
+     512          69 :     if (regs.ebx & 0x00000008U) cpuInfo->addFeature(CpuInfo::kX86FeatureBMI);
+     513          69 :     if (regs.ebx & 0x00000010U) cpuInfo->addFeature(CpuInfo::kX86FeatureHLE);
+     514          69 :     if (regs.ebx & 0x00000080U) cpuInfo->addFeature(CpuInfo::kX86FeatureSMEP);
+     515          69 :     if (regs.ebx & 0x00000100U) cpuInfo->addFeature(CpuInfo::kX86FeatureBMI2);
+     516          69 :     if (regs.ebx & 0x00000200U) cpuInfo->addFeature(CpuInfo::kX86FeatureERMS);
+     517          69 :     if (regs.ebx & 0x00000800U) cpuInfo->addFeature(CpuInfo::kX86FeatureRTM);
+     518          69 :     if (regs.ebx & 0x00004000U) maybeMPX = true;
+     519          69 :     if (regs.ebx & 0x00040000U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDSEED);
+     520          69 :     if (regs.ebx & 0x00080000U) cpuInfo->addFeature(CpuInfo::kX86FeatureADX);
+     521          69 :     if (regs.ebx & 0x00100000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSMAP);
+     522          69 :     if (regs.ebx & 0x00400000U) cpuInfo->addFeature(CpuInfo::kX86FeaturePCOMMIT);
+     523          69 :     if (regs.ebx & 0x00800000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLFLUSHOPT);
+     524          69 :     if (regs.ebx & 0x01000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLWB);
+     525          69 :     if (regs.ebx & 0x20000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSHA);
+     526          69 :     if (regs.ecx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeaturePREFETCHWT1);
+     527             : 
+     528             :     // TSX is supported if at least one of `HLE` and `RTM` is supported.
+     529          69 :     if (regs.ebx & 0x00000810U) cpuInfo->addFeature(CpuInfo::kX86FeatureTSX);
+     530             : 
+     531             :     // Detect AVX2.
+     532          69 :     if (cpuInfo->hasFeature(CpuInfo::kX86FeatureAVX)) {
+     533          69 :       if (regs.ebx & 0x00000020U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX2);
+     534             :     }
+     535             : 
+     536             :     // Detect AVX-512+.
+     537          69 :     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          69 :   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          69 :     if (((regs.eax & xcr0.eax) & 0x00000018U) == 0x00000018U && maybeMPX)
+     569             :       cpuInfo->addFeature(CpuInfo::kX86FeatureMPX);
+     570             : 
+     571             :     x86CallCpuId(&regs, 0xD, 1);
+     572          69 :     if (regs.eax & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureXSAVEOPT);
+     573          69 :     if (regs.eax & 0x00000002U) cpuInfo->addFeature(CpuInfo::kX86FeatureXSAVEC);
+     574          69 :     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          69 :   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          69 :   uint32_t* brand = reinterpret_cast<uint32_t*>(cpuInfo->_brandString);
+     587             : 
+     588             :   i = maxId = 0x80000000U;
+     589             :   do {
+     590             :     x86CallCpuId(&regs, i);
+     591         414 :     switch (i) {
+     592             :       case 0x80000000U:
+     593          69 :         maxId = std::min<uint32_t>(regs.eax, kHighestProcessedEAX);
+     594          69 :         break;
+     595             : 
+     596          69 :       case 0x80000001U:
+     597          69 :         if (regs.ecx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureLAHFSAHF);
+     598          69 :         if (regs.ecx & 0x00000020U) cpuInfo->addFeature(CpuInfo::kX86FeatureLZCNT);
+     599          69 :         if (regs.ecx & 0x00000040U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE4A);
+     600          69 :         if (regs.ecx & 0x00000080U) cpuInfo->addFeature(CpuInfo::kX86FeatureMSSE);
+     601          69 :         if (regs.ecx & 0x00000100U) cpuInfo->addFeature(CpuInfo::kX86FeaturePREFETCHW);
+     602          69 :         if (regs.ecx & 0x00200000U) cpuInfo->addFeature(CpuInfo::kX86FeatureTBM);
+     603          69 :         if (regs.edx & 0x00100000U) cpuInfo->addFeature(CpuInfo::kX86FeatureNX);
+     604          69 :         if (regs.edx & 0x00200000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFXSROPT);
+     605          69 :         if (regs.edx & 0x00400000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMMX2);
+     606          69 :         if (regs.edx & 0x08000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDTSCP);
+     607          69 :         if (regs.edx & 0x40000000U) cpuInfo->addFeature(CpuInfo::kX86Feature3DNOW2)
+     608             :                                             .addFeature(CpuInfo::kX86FeatureMMX2);
+     609          69 :         if (regs.edx & 0x80000000U) cpuInfo->addFeature(CpuInfo::kX86Feature3DNOW);
+     610             : 
+     611          69 :         if (cpuInfo->hasFeature(CpuInfo::kX86FeatureAVX)) {
+     612          69 :           if (regs.ecx & 0x00000800U) cpuInfo->addFeature(CpuInfo::kX86FeatureXOP);
+     613          69 :           if (regs.ecx & 0x00010000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFMA4);
+     614             :         }
+     615             : 
+     616             :         // These seem to be only supported by AMD.
+     617          69 :         if (cpuInfo->getVendorId() == CpuInfo::kVendorAMD) {
+     618          69 :           if (regs.ecx & 0x00000010U) cpuInfo->addFeature(CpuInfo::kX86FeatureALTMOVCR8);
+     619             :         }
+     620             :         break;
+     621             : 
+     622         207 :       case 0x80000002U:
+     623             :       case 0x80000003U:
+     624             :       case 0x80000004U:
+     625         207 :         *brand++ = regs.eax;
+     626         207 :         *brand++ = regs.ebx;
+     627         207 :         *brand++ = regs.ecx;
+     628         207 :         *brand++ = regs.edx;
+     629             : 
+     630             :         // Go directly to the last one.
+     631         207 :         if (i == 0x80000004U) i = 0x80000008U - 1;
+     632             :         break;
+     633             : 
+     634          69 :       case 0x80000008U:
+     635          69 :         if (regs.ebx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLZERO);
+     636             :         break;
+     637             :     }
+     638         414 :   } while (++i <= maxId);
+     639             : 
+     640             :   // Simplify CPU brand string by removing unnecessary spaces.
+     641             :   x86SimplifyBrandString(cpuInfo->_brandString);
+     642          69 : }
+     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          69 :   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          69 : 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          69 :   x86DetectCpuInfo(this);
+     676             : #endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
+     677             : 
+     678          69 :   _hwThreadsCount = cpuDetectHWThreadsCount();
+     679          69 : }
+     680             : 
+     681             : // ============================================================================
+     682             : // [asmjit::CpuInfo - GetHost]
+     683             : // ============================================================================
+     684             : 
+     685             : struct HostCpuInfo : public CpuInfo {
+     686          69 :   ASMJIT_INLINE HostCpuInfo() noexcept : CpuInfo() { detect(); }
+     687             : };
+     688             : 
+     689        1972 : const CpuInfo& CpuInfo::getHost() noexcept {
+     690        2041 :   static HostCpuInfo host;
+     691        1972 :   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.15
+
+ + + 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 0000000000..1105fdd024 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.h.func.html b/coverage-libs/asmjit/cpuinfo.h.func.html new file mode 100644 index 0000000000..c86930c110 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.h.gcov.html b/coverage-libs/asmjit/cpuinfo.h.gcov.html new file mode 100644 index 0000000000..48fdd40ea6 --- /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-06-10 08:19:15Functions: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          69 :   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         138 :     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         138 :     _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          69 :   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          69 :   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        3381 :   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.15
+
+ + + 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 0000000000..611ff8fb8a --- /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-06-10 08:19:15Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9FuncUtils9allocArgsEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZNK4PLMD6asmjit14FuncArgsMapper15updateFrameInfoERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1944
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1944
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1944
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE3580
_ZN4PLMD6asmjit8CallConv4initEj3580
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.func.html b/coverage-libs/asmjit/func.cpp.func.html new file mode 100644 index 0000000000..acd26cf73e --- /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-06-10 08:19:15Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE3580
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1944
_ZN4PLMD6asmjit8CallConv4initEj3580
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1944
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1944
_ZN4PLMD6asmjit9FuncUtils9allocArgsEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZNK4PLMD6asmjit14FuncArgsMapper15updateFrameInfoERNS0_13FuncFrameInfoE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.gcov.html b/coverage-libs/asmjit/func.cpp.gcov.html new file mode 100644 index 0000000000..597e679b2c --- /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-06-10 08:19:15Functions: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        3580 : ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId) noexcept {
+      57             :   reset();
+      58             : 
+      59             : #if defined(ASMJIT_BUILD_X86)
+      60        3580 :   if (CallConv::isX86Family(ccId))
+      61        3580 :     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        3580 : ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& sign) {
+      77             :   uint32_t ccId = sign.getCallConv();
+      78        3580 :   CallConv& cc = _callConv;
+      79             : 
+      80             :   uint32_t argCount = sign.getArgCount();
+      81        3580 :   if (ASMJIT_UNLIKELY(argCount > kFuncArgCount))
+      82             :     return DebugUtils::errored(kErrorInvalidArgument);
+      83             : 
+      84        3580 :   ASMJIT_PROPAGATE(cc.init(ccId));
+      85             : 
+      86        3580 :   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        5430 :   for (uint32_t i = 0; i < argCount; i++) {
+      91             :     Value& arg = _args[i];
+      92        1850 :     arg.initTypeId(TypeId::deabstract(args[i], deabstractDelta));
+      93             :   }
+      94        3580 :   _argCount = static_cast<uint8_t>(argCount);
+      95             : 
+      96             :   uint32_t ret = sign.getRet();
+      97        3580 :   if (ret != TypeId::kVoid) {
+      98             :     _rets[0].initTypeId(TypeId::deabstract(ret, deabstractDelta));
+      99        3580 :     _retCount = 1;
+     100             :   }
+     101             : 
+     102             : #if defined(ASMJIT_BUILD_X86)
+     103        3580 :   if (CallConv::isX86Family(ccId))
+     104        3580 :     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        1944 : 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        1944 :   if (CallConv::isX86Family(ccId))
+     126        1944 :     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        1944 : ASMJIT_FAVOR_SIZE Error FuncUtils::emitProlog(CodeEmitter* emitter, const FuncFrameLayout& layout) {
+     165             : #if defined(ASMJIT_BUILD_X86)
+     166        1944 :   if (emitter->getArchInfo().isX86Family())
+     167        1944 :     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        1944 : ASMJIT_FAVOR_SIZE Error FuncUtils::emitEpilog(CodeEmitter* emitter, const FuncFrameLayout& layout) {
+     179             : #if defined(ASMJIT_BUILD_X86)
+     180        1944 :   if (emitter->getArchInfo().isX86Family())
+     181        1944 :     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.15
+
+ + + 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 0000000000..ab6998ce55 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/func.h.func.html b/coverage-libs/asmjit/func.h.func.html new file mode 100644 index 0000000000..1abaa55e7a --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/func.h.gcov.html b/coverage-libs/asmjit/func.h.gcov.html new file mode 100644 index 0000000000..065fdc203e --- /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-06-10 08:19:15Functions: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        3580 :   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        3580 :     ::memset(_passedOrder, 0xFF, sizeof(_passedOrder));
+     263             :   }
+     264             : 
+     265             :   // --------------------------------------------------------------------------
+     266             :   // [Accessors]
+     267             :   // --------------------------------------------------------------------------
+     268             : 
+     269             :   //! Get calling convention id, see \ref Id.
+     270        1944 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     271             :   //! Set calling convention id, see \ref Id.
+     272        3580 :   ASMJIT_INLINE void setId(uint32_t id) noexcept { _id = static_cast<uint8_t>(id); }
+     273             : 
+     274             :   //! Get architecture type.
+     275        5524 :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return _archType; }
+     276             :   //! Set architecture type.
+     277        3580 :   ASMJIT_INLINE void setArchType(uint32_t archType) noexcept { _archType = static_cast<uint8_t>(archType); }
+     278             : 
+     279             :   //! Get calling convention algorithm, see \ref Algorithm.
+     280        3580 :   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        5026 :   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        5832 :   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        3580 :     _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        1944 :   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        3580 :   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       11356 :     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        3580 :     _passedOrder[kind].packed[0] = p0;
+     334        3580 :     _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        9412 :     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        3580 :   }
+     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        3580 :     _callConv = static_cast<uint8_t>(ccId);
+     443        3580 :     _argCount = static_cast<uint8_t>(argCount);
+     444        3580 :     _vaIndex = kNoVarArgs;
+     445        3580 :     _ret = ret;
+     446        3580 :     _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        3580 :   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        5216 :   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        3580 :   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        3580 :   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        1944 :   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        1422 :   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         214 :   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        5430 :     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        1446 :       _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         404 :       _value |= (regType << kRegTypeShift) | (regId << kRegIdShift) | kIsByReg;
+     732        3580 :     }
+     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        6354 :     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        5834 :     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        6662 :     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        7066 :     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        3580 :   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        3580 :   ASMJIT_INLINE uint32_t getRetCount() const noexcept { return _retCount; }
+     795             :   //! Get the number of function arguments.
+     796       12590 :   ASMJIT_INLINE uint32_t getArgCount() const noexcept { return _argCount; }
+     797             : 
+     798             :   //! Get whether the function has a return value.
+     799        1944 :   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        5216 :     return _usedRegs[kind];
+     853             :   }
+     854             : 
+     855             :   ASMJIT_INLINE void addUsedRegs(uint32_t kind, uint32_t regs) noexcept {
+     856             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     857        1850 :     _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        1944 :   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        1944 :     _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        5832 :   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        1012 :   ASMJIT_INLINE bool hasCalls() const noexcept { return (_attributes & kAttrHasCalls) != 0; }
+     952             :   //! Set `kFlagHasCalls` to true.
+     953        1636 :   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        1944 :   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        1944 :   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        1944 :   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        7776 :     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        1944 :     _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        1944 :   ASMJIT_INLINE uint32_t getStackFrameAlignment() const noexcept { return _stackFrameAlignment; }
+    1015             :   //! Get minimum call-frame alignment required by the function.
+    1016        1944 :   ASMJIT_INLINE uint32_t getCallFrameAlignment() const noexcept { return _callFrameAlignment; }
+    1017             : 
+    1018        1944 :   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        1944 :     _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        1636 :   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        1944 :   ASMJIT_INLINE uint32_t getStackArgsRegId() const noexcept { return _stackArgsRegId; }
+    1048        1944 :   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        7776 :   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        5832 :   ASMJIT_INLINE bool hasDynamicAlignment() const noexcept { return static_cast<bool>(_dynamicAlignment); }
+    1096             : 
+    1097        1944 :   ASMJIT_INLINE bool hasMmxCleanup() const noexcept { return static_cast<bool>(_mmxCleanup); }
+    1098        1944 :   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        7776 :     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        1944 :   ASMJIT_INLINE uint32_t getStackArgsRegId() const noexcept { return _stackArgsRegId; }
+    1122           0 :   ASMJIT_INLINE uint32_t getStackArgsOffset() const noexcept { return _stackArgsOffset; }
+    1123             : 
+    1124        3888 :   ASMJIT_INLINE bool hasStackAdjustment() const noexcept { return _stackAdjustment != 0; }
+    1125             :   ASMJIT_INLINE uint32_t getStackAdjustment() const noexcept { return _stackAdjustment; }
+    1126             : 
+    1127        1944 :   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.15
+
+ + + 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 0000000000..93df0ca83e --- /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-06-10 08:19:15Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10DebugUtils11debugOutputEPKc0
_ZN4PLMD6asmjit10DebugUtils13errorAsStringEj0
_ZN4PLMD6asmjit10DebugUtils15assertionFailedEPKciS3_0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/globals.cpp.func.html b/coverage-libs/asmjit/globals.cpp.func.html new file mode 100644 index 0000000000..c458725320 --- /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-06-10 08:19:15Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10DebugUtils11debugOutputEPKc0
_ZN4PLMD6asmjit10DebugUtils13errorAsStringEj0
_ZN4PLMD6asmjit10DebugUtils15assertionFailedEPKciS3_0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/globals.cpp.gcov.html b/coverage-libs/asmjit/globals.cpp.gcov.html new file mode 100644 index 0000000000..6b26e45479 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..b914e4d70b --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/globals.h.func.html b/coverage-libs/asmjit/globals.h.func.html new file mode 100644 index 0000000000..8e7b5c3575 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/globals.h.gcov.html b/coverage-libs/asmjit/globals.h.gcov.html new file mode 100644 index 0000000000..0cc4f7c1bb --- /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-06-10 08:19:15Functions: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       11676 : 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       11676 : 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.15
+
+ + + diff --git a/coverage-libs/asmjit/index-sort-f.html b/coverage-libs/asmjit/index-sort-f.html new file mode 100644 index 0000000000..2edace1c27 --- /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-06-10 08:19:15Functions:13935239.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
x86compiler.h +
66.7%66.7%
+
66.7 %4 / 60.0 %0 / 2
inst.cpp +
0.0%
+
0.0 %0 / 60.0 %0 / 2
x86inst.cpp +
0.0%
+
0.0 %0 / 240.0 %0 / 2
x86instimpl.cpp +
0.0%
+
0.0 %0 / 1700.0 %0 / 3
globals.cpp +
0.0%
+
0.0 %0 / 90.0 %0 / 3
x86builder.cpp +
0.0%
+
0.0 %0 / 150.0 %0 / 5
x86logging.cpp +
0.0%
+
0.0 %0 / 2030.0 %0 / 8
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
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
x86compiler.cpp +
31.8%31.8%
+
31.8 %48 / 15171.4 %5 / 7
func.cpp +
77.4%77.4%
+
77.4 %24 / 3171.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
x86operand.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
inst.h +
40.0%40.0%
+
40.0 %2 / 5-0 / 0
moved_string.h +
22.2%22.2%
+
22.2 %6 / 27-0 / 0
x86inst.h +
66.7%66.7%
+
66.7 %10 / 15-0 / 0
arch.h +
75.0%75.0%
+
75.0 %6 / 8-0 / 0
func.h +
70.1%70.1%
+
70.1 %68 / 97-0 / 0
utils.h +
48.9%48.9%
+
48.9 %22 / 45-0 / 0
x86emitter.h +
63.0%63.0%
+
63.0 %17 / 27-0 / 0
globals.h +
66.7%66.7%
+
66.7 %2 / 3-0 / 0
runtime.h +
100.0%
+
100.0 %3 / 3-0 / 0
constpool.h +
0.0%
+
0.0 %0 / 31-0 / 0
operand.h +
54.4%54.4%
+
54.4 %49 / 90-0 / 0
codecompiler.h +
64.1%64.1%
+
64.1 %41 / 64-0 / 0
x86misc.h +
59.5%59.5%
+
59.5 %22 / 37-0 / 0
osutils.h +
100.0%
+
100.0 %5 / 5-0 / 0
cpuinfo.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
x86assembler.h +
100.0%
+
100.0 %2 / 2-0 / 0
x86regalloc_p.h +
69.4%69.4%
+
69.4 %34 / 49-0 / 0
codeemitter.h +
81.8%81.8%
+
81.8 %9 / 11-0 / 0
codebuilder.h +
53.2%53.2%
+
53.2 %50 / 94-0 / 0
assembler.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
regalloc_p.h +
66.7%66.7%
+
66.7 %36 / 54-0 / 0
codeholder.h +
78.0%78.0%
+
78.0 %32 / 41-0 / 0
logging.h +
0.0%
+
0.0 %0 / 5-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.15
+
+ + + diff --git a/coverage-libs/asmjit/index-sort-l.html b/coverage-libs/asmjit/index-sort-l.html new file mode 100644 index 0000000000..183025479f --- /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-06-10 08:19:15Functions: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
x86operand.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
cpuinfo.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.15
+
+ + + diff --git a/coverage-libs/asmjit/index.html b/coverage-libs/asmjit/index.html new file mode 100644 index 0000000000..c52fa83513 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..5ccbffcbb6 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/inst.cpp.func.html b/coverage-libs/asmjit/inst.cpp.func.html new file mode 100644 index 0000000000..306ca9e6e3 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/inst.cpp.gcov.html b/coverage-libs/asmjit/inst.cpp.gcov.html new file mode 100644 index 0000000000..afafe9532f --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..78a3dfa121 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/inst.h.func.html b/coverage-libs/asmjit/inst.h.func.html new file mode 100644 index 0000000000..54801ea6fb --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/inst.h.gcov.html b/coverage-libs/asmjit/inst.h.gcov.html new file mode 100644 index 0000000000..837c9602d0 --- /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-06-10 08:19:15Functions: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       48254 :       : instId(0),
+      78             :         options(0),
+      79       48254 :         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.15
+
+ + + 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 0000000000..e9441b6875 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/logging.cpp.func.html b/coverage-libs/asmjit/logging.cpp.func.html new file mode 100644 index 0000000000..3ca04bb2fa --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/logging.cpp.gcov.html b/coverage-libs/asmjit/logging.cpp.gcov.html new file mode 100644 index 0000000000..1882f63ba4 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..9ebf3b4278 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/logging.h.func.html b/coverage-libs/asmjit/logging.h.func.html new file mode 100644 index 0000000000..1943e37a42 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/logging.h.gcov.html b/coverage-libs/asmjit/logging.h.gcov.html new file mode 100644 index 0000000000..2ea1cd5957 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..3d8b3e743d --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..d134bb09c6 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..6de97dd943 --- /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-06-10 08:19:15Functions: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        1944 :   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        1944 :   ASMJIT_INLINE StringBuilderTmp() noexcept : StringBuilder(NoInit) {
+     289        1944 :     _data = _embeddedData;
+     290        1944 :     _data[0] = 0;
+     291             : 
+     292        1944 :     _length = 0;
+     293        1944 :     _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.15
+
+ + + 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 0000000000..7374c84e2b --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/operand.h.func.html b/coverage-libs/asmjit/operand.h.func.html new file mode 100644 index 0000000000..423c9a0b1e --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/operand.h.gcov.html b/coverage-libs/asmjit/operand.h.gcov.html new file mode 100644 index 0000000000..29681b8802 --- /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-06-10 08:19:15Functions: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      123906 :   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       27628 :   static ASMJIT_INLINE uint32_t packId(uint32_t id) noexcept { return id + kPackedIdMin; }
+     164             :   //! Convert a packed-id back to real-id.
+     165       13844 :   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       87252 :   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         404 :   ASMJIT_INLINE void setSignature(uint32_t signature) noexcept { _signature = signature; }
+     270             : 
+     271       41128 :   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      297092 :   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      146082 :   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       54402 :   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       24672 :   ASMJIT_INLINE Operand() noexcept { reset(); }
+     445             :   //! Create a reference to `other` operand.
+     446        4292 :   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       78516 :     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      182676 :     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        1944 :   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       21852 :   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        2620 :   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      143126 :     _signature = signature;
+     827      143126 :     _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       62212 :   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       48254 :   ASMJIT_INLINE uint32_t getSignature() const noexcept { return _signature; }
+     852             :   //! Get register id or 0.
+     853       48254 :   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       12136 :   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       12136 :   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       20564 :   ASMJIT_INLINE uint32_t getBaseId() const noexcept { return _mem.base; }
+    1019             :   //! Get id of the INDEX register.
+    1020       14496 :   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       14496 :   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        9434 :     _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        9636 :   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        7450 : 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       23740 :   static ASMJIT_INLINE bool isValid(uint32_t typeId) noexcept { return typeId >= _kIntStart && typeId <= _kVec512End; }
+    1461        5430 :   static ASMJIT_INLINE bool isAbstract(uint32_t typeId) noexcept { return typeId >= kIntPtr && typeId <= kUIntPtr; }
+    1462        1850 :   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        1446 :   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       47480 :     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        5430 :     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.15
+
+ + + 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 0000000000..c287e7f7b3 --- /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-06-10 08:19:15Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj1944
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm1944
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv1972
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv3916
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.func.html b/coverage-libs/asmjit/osutils.cpp.func.html new file mode 100644 index 0000000000..4744e7813e --- /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-06-10 08:19:15Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj1944
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv1972
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm1944
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv3916
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.gcov.html b/coverage-libs/asmjit/osutils.cpp.gcov.html new file mode 100644 index 0000000000..ecd4524d18 --- /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-06-10 08:19:15Functions: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        3916 : static const VMemInfo& OSUtils_GetVMemInfo() noexcept {
+     140             :   static VMemInfo vmi;
+     141        3916 :   if (ASMJIT_UNLIKELY(!vmi.pageSize)) {
+     142          69 :     size_t pageSize = ::getpagesize();
+     143          69 :     vmi.pageSize = pageSize;
+     144         138 :     vmi.pageGranularity = std::max<size_t>(pageSize, 65536);
+     145             :   }
+     146        3916 :   return vmi;
+     147             : };
+     148             : 
+     149        1972 : VMemInfo OSUtils::getVirtualMemoryInfo() noexcept { return OSUtils_GetVMemInfo(); }
+     150             : 
+     151        1944 : void* OSUtils::allocVirtualMemory(size_t size, size_t* allocated, uint32_t flags) noexcept {
+     152        1944 :   const VMemInfo& vmi = OSUtils_GetVMemInfo();
+     153             : 
+     154        1944 :   size_t alignedSize = Utils::alignTo<size_t>(size, vmi.pageSize);
+     155             :   int protection = PROT_READ;
+     156             : 
+     157        1944 :   if (flags & kVMWritable  ) protection |= PROT_WRITE;
+     158        1944 :   if (flags & kVMExecutable) protection |= PROT_EXEC;
+     159             : 
+     160        1944 :   void* mbase = ::mmap(nullptr, alignedSize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+     161        1944 :   if (ASMJIT_UNLIKELY(mbase == MAP_FAILED)) return nullptr;
+     162             : 
+     163        1944 :   if (allocated) *allocated = alignedSize;
+     164             :   return mbase;
+     165             : }
+     166             : 
+     167        1944 : Error OSUtils::releaseVirtualMemory(void* p, size_t size) noexcept {
+     168        1944 :   if (ASMJIT_UNLIKELY(::munmap(p, size) != 0))
+     169             :     return DebugUtils::errored(kErrorInvalidState);
+     170             : 
+     171        1944 :   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.15
+
+ + + 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 0000000000..b3b75faf56 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/osutils.h.func.html b/coverage-libs/asmjit/osutils.h.func.html new file mode 100644 index 0000000000..51ca0a5caa --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/osutils.h.gcov.html b/coverage-libs/asmjit/osutils.h.gcov.html new file mode 100644 index 0000000000..d480521cc5 --- /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-06-10 08:19:15Functions: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        1972 :   ASMJIT_INLINE Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
+     153             :   //! Destroy the `Lock` instance.
+     154        1972 :   ASMJIT_INLINE ~Lock() noexcept { pthread_mutex_destroy(&_handle); }
+     155             : 
+     156             :   //! Lock.
+     157        1944 :   ASMJIT_INLINE void lock() noexcept { pthread_mutex_lock(&_handle); }
+     158             :   //! Unlock.
+     159        1944 :   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        1944 :   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.15
+
+ + + 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 0000000000..bc81bb47b8 --- /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-06-10 08:19:15Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPassD0Ev0
_ZN4PLMD6asmjit6RAPassD2Ev0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv1944
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv1944
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv1944
_ZN4PLMD6asmjit6RAPass7cleanupEv1944
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE1944
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE1944
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE1944
_ZN4PLMD6asmjit6RAPassC2Ev1944
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE4004
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.func.html b/coverage-libs/asmjit/regalloc.cpp.func.html new file mode 100644 index 0000000000..a5791b8463 --- /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-06-10 08:19:15Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE4004
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv1944
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv1944
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv1944
_ZN4PLMD6asmjit6RAPass7cleanupEv1944
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE1944
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE1944
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE1944
_ZN4PLMD6asmjit6RAPassC2Ev1944
_ZN4PLMD6asmjit6RAPassD0Ev0
_ZN4PLMD6asmjit6RAPassD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.gcov.html b/coverage-libs/asmjit/regalloc.cpp.gcov.html new file mode 100644 index 0000000000..e35f5ae5f3 --- /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-06-10 08:19:15Functions: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        1944 : RAPass::RAPass() noexcept :
+      51             :   CBPass("RA"),
+      52        1944 :   _varMapToVaListOffset(0) {}
+      53           0 : RAPass::~RAPass() noexcept {}
+      54             : 
+      55             : // ============================================================================
+      56             : // [asmjit::RAPass - Interface]
+      57             : // ============================================================================
+      58             : 
+      59        1944 : Error RAPass::process(Zone* zone) noexcept {
+      60        1944 :   _zone = zone;
+      61        1944 :   _heap.reset(zone);
+      62        1944 :   _emitComments = (cb()->getGlobalOptions() & CodeEmitter::kOptionLoggingEnabled) != 0;
+      63             : 
+      64             :   Error err = kErrorOk;
+      65             :   CBNode* node = cc()->getFirstNode();
+      66        1944 :   if (!node) return err;
+      67             : 
+      68             :   do {
+      69        1944 :     if (node->getType() == CBNode::kNodeFunc) {
+      70             :       CCFunc* func = static_cast<CCFunc*>(node);
+      71             :       node = func->getEnd();
+      72             : 
+      73        1944 :       err = compile(func);
+      74        1944 :       if (err) break;
+      75             :     }
+      76             : 
+      77             :     // Find a function by skipping all nodes that are not `kNodeFunc`.
+      78             :     do {
+      79             :       node = node->getNext();
+      80        1944 :     } while (node && node->getType() != CBNode::kNodeFunc);
+      81        1944 :   } while (node);
+      82             : 
+      83        1944 :   _heap.reset(nullptr);
+      84        1944 :   _zone = nullptr;
+      85        1944 :   return err;
+      86             : }
+      87             : 
+      88        1944 : Error RAPass::compile(CCFunc* func) noexcept {
+      89        1944 :   ASMJIT_PROPAGATE(prepare(func));
+      90             : 
+      91             :   Error err;
+      92             :   do {
+      93        1944 :     err = fetch();
+      94        1944 :     if (err) break;
+      95             : 
+      96        1944 :     err = removeUnreachableCode();
+      97        1944 :     if (err) break;
+      98             : 
+      99        1944 :     err = livenessAnalysis();
+     100        1944 :     if (err) break;
+     101             : 
+     102             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     103        1944 :     if (cc()->getGlobalOptions() & CodeEmitter::kOptionLoggingEnabled) {
+     104           0 :       err = annotate();
+     105           0 :       if (err) break;
+     106             :     }
+     107             : #endif // !ASMJIT_DISABLE_LOGGING
+     108             : 
+     109        1944 :     err = translate();
+     110             :   } while (false);
+     111             : 
+     112        1944 :   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        1944 :   return err;
+     119             : }
+     120             : 
+     121        1944 : Error RAPass::prepare(CCFunc* func) noexcept {
+     122             :   CBNode* end = func->getEnd();
+     123             : 
+     124        1944 :   _func = func;
+     125        1944 :   _stop = end->getNext();
+     126             : 
+     127             :   _unreachableList.reset();
+     128             :   _returningList.reset();
+     129             :   _jccList.reset();
+     130             :   _contextVd.reset();
+     131             : 
+     132        1944 :   _memVarCells = nullptr;
+     133        1944 :   _memStackCells = nullptr;
+     134             : 
+     135        1944 :   _mem1ByteVarsUsed = 0;
+     136        1944 :   _mem2ByteVarsUsed = 0;
+     137        1944 :   _mem4ByteVarsUsed = 0;
+     138        1944 :   _mem8ByteVarsUsed = 0;
+     139        1944 :   _mem16ByteVarsUsed = 0;
+     140        1944 :   _mem32ByteVarsUsed = 0;
+     141        1944 :   _mem64ByteVarsUsed = 0;
+     142        1944 :   _memStackCellsUsed = 0;
+     143             : 
+     144        1944 :   _memMaxAlign = 0;
+     145        1944 :   _memVarTotal = 0;
+     146        1944 :   _memStackTotal = 0;
+     147        1944 :   _memAllTotal = 0;
+     148        1944 :   _annotationLength = 12;
+     149             : 
+     150        1944 :   return kErrorOk;
+     151             : }
+     152             : 
+     153        1944 : void RAPass::cleanup() noexcept {
+     154             :   VirtReg** virtArray = _contextVd.getData();
+     155             :   size_t virtCount = _contextVd.getLength();
+     156             : 
+     157       25684 :   for (size_t i = 0; i < virtCount; i++) {
+     158       23740 :     VirtReg* vreg = virtArray[i];
+     159       23740 :     vreg->_raId = kInvalidValue;
+     160             :     vreg->resetPhysId();
+     161             :   }
+     162             : 
+     163             :   _contextVd.reset();
+     164        1944 : }
+     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        1944 : Error RAPass::resolveCellOffsets() {
+     271        1944 :   RACell* varCell = _memVarCells;
+     272        1944 :   RACell* stackCell = _memStackCells;
+     273             : 
+     274             :   uint32_t pos64 = 0;
+     275        1944 :   uint32_t pos32 = pos64 + _mem64ByteVarsUsed * 64;
+     276        1944 :   uint32_t pos16 = pos32 + _mem32ByteVarsUsed * 32;
+     277        1944 :   uint32_t pos8  = pos16 + _mem16ByteVarsUsed * 16;
+     278        1944 :   uint32_t pos4  = pos8  + _mem8ByteVarsUsed  * 8 ;
+     279        1944 :   uint32_t pos2  = pos4  + _mem4ByteVarsUsed  * 4 ;
+     280        1944 :   uint32_t pos1  = pos2  + _mem2ByteVarsUsed  * 2 ;
+     281             : 
+     282             :   // Assign home slots.
+     283        5948 :   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        1944 :   uint32_t stackPos = pos1 + _mem1ByteVarsUsed;
+     306        1944 :   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        1944 :   _memAllTotal = stackPos;
+     319        1944 :   return kErrorOk;
+     320             : }
+     321             : 
+     322             : // ============================================================================
+     323             : // [asmjit::RAPass - RemoveUnreachableCode]
+     324             : // ============================================================================
+     325             : 
+     326        1944 : Error RAPass::removeUnreachableCode() {
+     327             :   ZoneList<CBNode*>::Link* link = _unreachableList.getFirst();
+     328             :   CBNode* stop = getStop();
+     329             : 
+     330        3888 :   while (link) {
+     331             :     CBNode* node = link->getValue();
+     332        1944 :     if (node && node->getPrev() && node != stop) {
+     333             :       // Locate all unreachable nodes.
+     334             :       CBNode* first = node;
+     335             :       do {
+     336        1944 :         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        1944 :       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        1944 :   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        1944 : Error RAPass::livenessAnalysis() {
+     385             :   uint32_t bLen = static_cast<uint32_t>(
+     386        1944 :     ((_contextVd.getLength() + RABits::kEntityBits - 1) / RABits::kEntityBits));
+     387             : 
+     388             :   // No variables.
+     389        1944 :   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        1944 :   size_t varMapToVaListOffset = _varMapToVaListOffset;
+     405             :   RABits* bCur = newBits(bLen);
+     406        1944 :   if (ASMJIT_UNLIKELY(!bCur)) goto NoMem;
+     407             : 
+     408             :   // Allocate bits for code visited first time.
+     409       36630 : Visit:
+     410             :   for (;;) {
+     411             :     wd = node->getPassData<RAData>();
+     412       36630 :     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       36630 :     if (!bTmp) goto NoMem;
+     421             : 
+     422             :     wd = node->getPassData<RAData>();
+     423       36630 :     wd->liveness = bTmp;
+     424             : 
+     425       36630 :     uint32_t tiedTotal = wd->tiedTotal;
+     426             :     TiedReg* tiedArray = reinterpret_cast<TiedReg*>(((uint8_t*)wd) + varMapToVaListOffset);
+     427             : 
+     428       98004 :     for (uint32_t i = 0; i < tiedTotal; i++) {
+     429       61374 :       TiedReg* tied = &tiedArray[i];
+     430       61374 :       VirtReg* vreg = tied->vreg;
+     431             : 
+     432       61374 :       uint32_t flags = tied->flags;
+     433       61374 :       uint32_t raId = vreg->_raId;
+     434             : 
+     435       61374 :       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       36630 :     if (node->getType() == CBNode::kNodeLabel)
+     448           0 :       goto Target;
+     449             : 
+     450       36630 :     if (node == func)
+     451        1944 :       goto Done;
+     452             : 
+     453             :     ASMJIT_ASSERT(node->getPrev());
+     454             :     node = node->getPrev();
+     455       34686 :   }
+     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        1944 :   if (ltCur) {
+     540           0 :     node = ltCur->node;
+     541           0 :     from = ltCur->from;
+     542             : 
+     543           0 :     goto JumpNext;
+     544             :   }
+     545             : 
+     546             :   retPtr = retPtr->getNext();
+     547        1944 :   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.15
+
+ + + 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 0000000000..9cbf5501f5 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..a0177c23da --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..48706d6835 --- /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-06-10 08:19:15Functions: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       61374 :     this->vreg = vreg;
+     101       61374 :     this->flags = flags;
+     102       61374 :     this->refCount = 0;
+     103       61374 :     this->inPhysId = Globals::kInvalidRegId;
+     104       61374 :     this->outPhysId = Globals::kInvalidRegId;
+     105       61374 :     this->reserved = 0;
+     106       61374 :     this->inRegs = inRegs;
+     107        1636 :     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       26376 :   ASMJIT_INLINE uint32_t hasOutPhysId() const { return outPhysId != Globals::kInvalidRegId; }
+     118             : 
+     119             :   //! Set the input register index.
+     120       37634 :   ASMJIT_INLINE void setInPhysId(uint32_t index) { inPhysId = static_cast<uint8_t>(index); }
+     121             :   //! Set the output register index.
+     122       23740 :   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      178296 :     return (data[index / kEntityBits] >> (index % kEntityBits)) & 1;
+     210             :   }
+     211             : 
+     212             :   ASMJIT_INLINE void setBit(uint32_t index) noexcept {
+     213       61374 :     data[index / kEntityBits] |= static_cast<uintptr_t>(1) << (index % kEntityBits);
+     214       37634 :   }
+     215             : 
+     216             :   ASMJIT_INLINE void delBit(uint32_t index) noexcept {
+     217       23740 :     data[index / kEntityBits] &= ~(static_cast<uintptr_t>(1) << (index % kEntityBits));
+     218       23740 :   }
+     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       40518 :     : liveness(nullptr),
+     323       40518 :       state(nullptr),
+     324       40518 :       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        3888 :   ASMJIT_INLINE CodeCompiler* cc() const noexcept { return static_cast<CodeCompiler*>(_cb); }
+     382             : 
+     383             :   //! Get function.
+     384        3888 :   ASMJIT_INLINE CCFunc* getFunc() const noexcept { return _func; }
+     385             :   //! Get stop node.
+     386        5832 :   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       61374 :     if (ASMJIT_LIKELY(vreg->_raId != kInvalidValue)) return kErrorOk;
+     416             : 
+     417       23740 :     uint32_t raId = static_cast<uint32_t>(_contextVd.getLength());
+     418       23740 :     ASMJIT_PROPAGATE(_contextVd.append(&_heap, vreg));
+     419             : 
+     420       23740 :     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        1944 :       _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       36630 :       _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        1944 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     470        1944 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     471             : 
+     472             :     link->setValue(node);
+     473             :     _unreachableList.append(link);
+     474             : 
+     475        1944 :     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        1944 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     489        1944 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     490             : 
+     491             :     link->setValue(node);
+     492             :     _returningList.append(link);
+     493             : 
+     494        1944 :     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.15
+
+ + + 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 0000000000..b289f76461 --- /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-06-10 08:19:15Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm1944
_ZN4PLMD6asmjit10JitRuntimeC2Ev1972
_ZN4PLMD6asmjit10JitRuntimeD0Ev1972
_ZN4PLMD6asmjit10JitRuntimeD2Ev1972
_ZN4PLMD6asmjit11HostRuntimeC2Ev1972
_ZN4PLMD6asmjit11HostRuntimeD2Ev1972
_ZN4PLMD6asmjit7RuntimeC2Ev1972
_ZN4PLMD6asmjit7RuntimeD2Ev1972
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.func.html b/coverage-libs/asmjit/runtime.cpp.func.html new file mode 100644 index 0000000000..b20597f892 --- /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-06-10 08:19:15Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit10JitRuntimeC2Ev1972
_ZN4PLMD6asmjit10JitRuntimeD0Ev1972
_ZN4PLMD6asmjit10JitRuntimeD2Ev1972
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm1944
_ZN4PLMD6asmjit11HostRuntimeC2Ev1972
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit11HostRuntimeD2Ev1972
_ZN4PLMD6asmjit7RuntimeC2Ev1972
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD2Ev1972
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.gcov.html b/coverage-libs/asmjit/runtime.cpp.gcov.html new file mode 100644 index 0000000000..5203bd58f7 --- /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-06-10 08:19:15Functions: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        1972 : Runtime::Runtime() noexcept
+      93             :   : _codeInfo(),
+      94        1972 :     _runtimeType(kRuntimeNone),
+      95        1972 :     _allocType(VMemMgr::kAllocFreeable) {}
+      96        1972 : Runtime::~Runtime() noexcept {}
+      97             : 
+      98             : // ============================================================================
+      99             : // [asmjit::HostRuntime - Construction / Destruction]
+     100             : // ============================================================================
+     101             : 
+     102        1972 : HostRuntime::HostRuntime() noexcept {
+     103        1972 :   _runtimeType = kRuntimeJit;
+     104             : 
+     105             :   // Setup the CodeInfo of this Runtime.
+     106        1972 :   _codeInfo._archInfo       = CpuInfo::getHost().getArchInfo();
+     107        1972 :   _codeInfo._stackAlignment = static_cast<uint8_t>(hostDetectNaturalStackAlignment());
+     108        1972 :   _codeInfo._cdeclCallConv  = CallConv::kIdHostCDecl;
+     109        1972 :   _codeInfo._stdCallConv    = CallConv::kIdHostStdCall;
+     110        1972 :   _codeInfo._fastCallConv   = CallConv::kIdHostFastCall;
+     111        1972 : }
+     112        1972 : HostRuntime::~HostRuntime() noexcept {}
+     113             : 
+     114             : // ============================================================================
+     115             : // [asmjit::HostRuntime - Interface]
+     116             : // ============================================================================
+     117             : 
+     118        1944 : void HostRuntime::flush(const void* p, size_t size) noexcept {
+     119             :   hostFlushInstructionCache(p, size);
+     120        1944 : }
+     121             : 
+     122             : // ============================================================================
+     123             : // [asmjit::JitRuntime - Construction / Destruction]
+     124             : // ============================================================================
+     125             : 
+     126        1972 : JitRuntime::JitRuntime() noexcept {}
+     127        3944 : JitRuntime::~JitRuntime() noexcept {}
+     128             : 
+     129             : // ============================================================================
+     130             : // [asmjit::JitRuntime - Interface]
+     131             : // ============================================================================
+     132             : 
+     133        1944 : Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
+     134        1944 :   size_t codeSize = code->getCodeSize();
+     135        1944 :   if (ASMJIT_UNLIKELY(codeSize == 0)) {
+     136           0 :     *dst = nullptr;
+     137           0 :     return DebugUtils::errored(kErrorNoCodeGenerated);
+     138             :   }
+     139             : 
+     140        1944 :   void* p = _memMgr.alloc(codeSize, getAllocType());
+     141        1944 :   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        1944 :   size_t relocSize = code->relocate(p);
+     148        1944 :   if (ASMJIT_UNLIKELY(relocSize == 0)) {
+     149           0 :     *dst = nullptr;
+     150           0 :     _memMgr.release(p);
+     151           0 :     return DebugUtils::errored(kErrorInvalidState);
+     152             :   }
+     153             : 
+     154        1944 :   if (relocSize < codeSize)
+     155           0 :     _memMgr.shrink(p, relocSize);
+     156             : 
+     157        1944 :   flush(p, relocSize);
+     158        1944 :   *dst = p;
+     159             : 
+     160        1944 :   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.15
+
+ + + 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 0000000000..12f7482d62 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/runtime.h.func.html b/coverage-libs/asmjit/runtime.h.func.html new file mode 100644 index 0000000000..4e3050047d --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/runtime.h.gcov.html b/coverage-libs/asmjit/runtime.h.gcov.html new file mode 100644 index 0000000000..adb4f9a96f --- /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-06-10 08:19:15Functions: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        1944 :   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        1944 :     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        1944 :   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.15
+
+ + + 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 0000000000..13cf06f2c5 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/string.cpp.func.html b/coverage-libs/asmjit/string.cpp.func.html new file mode 100644 index 0000000000..725a410137 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/string.cpp.gcov.html b/coverage-libs/asmjit/string.cpp.gcov.html new file mode 100644 index 0000000000..fac5a2c139 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..0d9574e09b --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/utils.h.func.html b/coverage-libs/asmjit/utils.h.func.html new file mode 100644 index 0000000000..5c6704ac87 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/utils.h.gcov.html b/coverage-libs/asmjit/utils.h.gcov.html new file mode 100644 index 0000000000..d2b1c6a0d8 --- /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-06-10 08:19:15Functions: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       36630 :     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       47204 :     return ASMJIT_ARCH_LE ? (static_cast<uint64_t>(u1) << 32) + u0
+     146       27628 :                           : (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      122748 :       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       20142 :     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        9920 :       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       26376 :     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      157280 :     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        5524 :     uint32_t overflow = static_cast<uint32_t>(
+     402        5524 :       -static_cast<int32_t>(x >= sizeof(uint32_t) * 8));
+     403             : 
+     404        5524 :     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        1944 :     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       29676 :     if (mask)
+     507       29676 :       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      171540 :     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        1080 :     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        7664 :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     961             :     if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) {
+     962        7664 :       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       80728 :       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       74536 :       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       68044 :       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.15
+
+ + + 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 0000000000..287822a393 --- /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-06-10 08:19:15Functions:81457.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7VMemMgr5resetEv0
_ZN4PLMD6asmjit7VMemMgr6shrinkEPvm0
_ZN4PLMD6asmjit7VMemMgr7releaseEPv0
_ZN4PLMD6asmjitL17vMemMgrRemoveNodeEPNS0_7VMemMgrEPNS1_7MemNodeE0
_ZN4PLMD6asmjitL20vMemMgrFindNodeByPtrEPNS0_7VMemMgrEPh0
_ZN4PLMD6asmjitL21vMemMgrAllocPermanentEPNS0_7VMemMgrEm0
_ZN4PLMD6asmjit7VMemMgr5allocEmj1944
_ZN4PLMD6asmjitL17vMemMgrCreateNodeEPNS0_7VMemMgrEmm1944
_ZN4PLMD6asmjitL17vMemMgrInsertNodeEPNS0_7VMemMgrEPNS1_7MemNodeE1944
_ZN4PLMD6asmjitL20vMemMgrAllocFreeableEPNS0_7VMemMgrEm1944
_ZN4PLMD6asmjit7VMemMgrC2Ev1972
_ZN4PLMD6asmjit7VMemMgrD2Ev1972
_ZN4PLMD6asmjitL12vMemMgrResetEPNS0_7VMemMgrEb1972
_ZN4PLMD6asmjitL8_SetBitsEPmmm3888
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.func.html b/coverage-libs/asmjit/vmem.cpp.func.html new file mode 100644 index 0000000000..40d49ba24c --- /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-06-10 08:19:15Functions:81457.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7VMemMgr5allocEmj1944
_ZN4PLMD6asmjit7VMemMgr5resetEv0
_ZN4PLMD6asmjit7VMemMgr6shrinkEPvm0
_ZN4PLMD6asmjit7VMemMgr7releaseEPv0
_ZN4PLMD6asmjit7VMemMgrC2Ev1972
_ZN4PLMD6asmjit7VMemMgrD2Ev1972
_ZN4PLMD6asmjitL12vMemMgrResetEPNS0_7VMemMgrEb1972
_ZN4PLMD6asmjitL17vMemMgrCreateNodeEPNS0_7VMemMgrEmm1944
_ZN4PLMD6asmjitL17vMemMgrInsertNodeEPNS0_7VMemMgrEPNS1_7MemNodeE1944
_ZN4PLMD6asmjitL17vMemMgrRemoveNodeEPNS0_7VMemMgrEPNS1_7MemNodeE0
_ZN4PLMD6asmjitL20vMemMgrAllocFreeableEPNS0_7VMemMgrEm1944
_ZN4PLMD6asmjitL20vMemMgrFindNodeByPtrEPNS0_7VMemMgrEPh0
_ZN4PLMD6asmjitL21vMemMgrAllocPermanentEPNS0_7VMemMgrEm0
_ZN4PLMD6asmjitL8_SetBitsEPmmm3888
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.gcov.html b/coverage-libs/asmjit/vmem.cpp.gcov.html new file mode 100644 index 0000000000..1a3be99a44 --- /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-06-10 08:19:15Functions: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        3888 : static void _SetBits(size_t* buf, size_t index, size_t len) noexcept {
+      94        3888 :   if (len == 0)
+      95             :     return;
+      96             : 
+      97        3146 :   size_t i = index / kBitsPerEntity; // size_t[]
+      98        3146 :   size_t j = index % kBitsPerEntity; // size_t[][] bit index
+      99             : 
+     100             :   // How many bytes process in the first group.
+     101        3146 :   size_t c = kBitsPerEntity - j;
+     102             :   if (c > len)
+     103             :     c = len;
+     104             : 
+     105             :   // Offset.
+     106        3146 :   buf += i;
+     107             : 
+     108        3146 :   *buf++ |= ((~(size_t)0) >> (kBitsPerEntity - c)) << j;
+     109        3146 :   len -= c;
+     110             : 
+     111        3146 :   while (len >= kBitsPerEntity) {
+     112           0 :     *buf++ = ~(size_t)0;
+     113           0 :     len -= kBitsPerEntity;
+     114             :   }
+     115             : 
+     116        3146 :   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        1944 :   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        1944 : 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        1944 :   if (!vmem) return nullptr;
+     297             : 
+     298        1944 :   size_t blocks = (vSize / density);
+     299        1944 :   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        1944 :   uint8_t* data = static_cast<uint8_t*>(Internal::allocMemory(bsize * 2));
+     303             : 
+     304             :   // Out of memory.
+     305        1944 :   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        1944 :   node->node[0] = nullptr;
+     314        1944 :   node->node[1] = nullptr;
+     315        1944 :   node->mem = vmem;
+     316        1944 :   node->red = 1;
+     317             : 
+     318             :   // Initialize MemNode data.
+     319        1944 :   node->prev = nullptr;
+     320        1944 :   node->next = nullptr;
+     321             : 
+     322        1944 :   node->size = vSize;
+     323        1944 :   node->used = 0;
+     324        1944 :   node->blocks = blocks;
+     325        1944 :   node->density = density;
+     326        1944 :   node->largestBlock = vSize;
+     327             : 
+     328             :   ::memset(data, 0, bsize * 2);
+     329        1944 :   node->baUsed = reinterpret_cast<size_t*>(data);
+     330        1944 :   node->baCont = reinterpret_cast<size_t*>(data + bsize);
+     331             : 
+     332        1944 :   return node;
+     333             : }
+     334             : 
+     335        1944 : static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) noexcept {
+     336        1944 :   if (!self->_root) {
+     337             :     // Empty tree case.
+     338        1944 :     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        1944 :   self->_root->red = 0;
+     396             : 
+     397             :   // Link with others.
+     398        1944 :   node->prev = self->_last;
+     399             : 
+     400        1944 :   if (!self->_first) {
+     401        1944 :     self->_first = node;
+     402        1944 :     self->_last = node;
+     403        1944 :     self->_optimal = node;
+     404             :   }
+     405             :   else {
+     406             :     node->prev = self->_last;
+     407           0 :     self->_last->next = node;
+     408           0 :     self->_last = node;
+     409             :   }
+     410        1944 : }
+     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        1944 : 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        1944 :   if (vSize == 0)
+     595             :     return nullptr;
+     596             : 
+     597             :   AutoLock locked(self->_lock);
+     598        1944 :   MemNode* node = self->_optimal;
+     599        1944 :   minVSize = self->_blockSize;
+     600             : 
+     601             :   // Try to find memory block in existing nodes.
+     602        1944 :   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        1944 :     size_t blockSize = self->_blockSize;
+     673             :     if (blockSize < vSize) blockSize = vSize;
+     674             : 
+     675        1944 :     node = vMemMgrCreateNode(self, blockSize, self->_blockDensity);
+     676        1944 :     if (!node) return nullptr;
+     677             : 
+     678             :     // Update binary tree.
+     679        1944 :     vMemMgrInsertNode(self, node);
+     680             :     ASMJIT_ASSERT(vMemMgrCheckTree(self));
+     681             : 
+     682             :     // Alloc first node at start.
+     683             :     i = 0;
+     684        1944 :     need = (vSize + node->density - 1) / node->density;
+     685             : 
+     686             :     // Update statistics.
+     687        1944 :     self->_allocatedBytes += node->size;
+     688             :   }
+     689             : 
+     690        1944 : L_Found:
+     691             :   // Update bits.
+     692        1944 :   _SetBits(node->baUsed, i, need);
+     693        1944 :   _SetBits(node->baCont, i, need - 1);
+     694             : 
+     695             :   // Update statistics.
+     696             :   {
+     697        1944 :     size_t u = need * node->density;
+     698        1944 :     node->used += u;
+     699        1944 :     node->largestBlock = 0;
+     700        1944 :     self->_usedBytes += u;
+     701             :   }
+     702             : 
+     703             :   // And return pointer to allocated memory.
+     704        1944 :   uint8_t* result = node->mem + i * node->density;
+     705             :   ASMJIT_ASSERT(result >= node->mem && result <= node->mem + node->size - vSize);
+     706        1944 :   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        1972 : static void vMemMgrReset(VMemMgr* self, bool keepVirtualMemory) noexcept {
+     715        1972 :   MemNode* node = self->_first;
+     716             : 
+     717        3916 :   while (node) {
+     718        1944 :     MemNode* next = node->next;
+     719             : 
+     720        1944 :     if (!keepVirtualMemory)
+     721        1944 :       vMemMgrReleaseVMem(self, node->mem, node->size);
+     722             : 
+     723        1944 :     Internal::releaseMemory(node->baUsed);
+     724             :     Internal::releaseMemory(node);
+     725             : 
+     726             :     node = next;
+     727             :   }
+     728             : 
+     729        1972 :   self->_allocatedBytes = 0;
+     730        1972 :   self->_usedBytes = 0;
+     731             : 
+     732        1972 :   self->_root = nullptr;
+     733        1972 :   self->_first = nullptr;
+     734        1972 :   self->_last = nullptr;
+     735        1972 :   self->_optimal = nullptr;
+     736        1972 : }
+     737             : 
+     738             : // ============================================================================
+     739             : // [asmjit::VMemMgr - Construction / Destruction]
+     740             : // ============================================================================
+     741             : 
+     742             : #if !ASMJIT_OS_WINDOWS
+     743        1972 : VMemMgr::VMemMgr() noexcept {
+     744             : #else
+     745             : VMemMgr::VMemMgr(HANDLE hProcess) noexcept {
+     746             : #endif
+     747             : 
+     748        1972 :   VMemInfo vm = OSUtils::getVirtualMemoryInfo();
+     749             : 
+     750             : #if ASMJIT_OS_WINDOWS
+     751             :   _hProcess = hProcess ? hProcess : vm.hCurrentProcess;
+     752             : #endif // ASMJIT_OS_WINDOWS
+     753             : 
+     754        1972 :   _blockSize = vm.pageGranularity;
+     755        1972 :   _blockDensity = 64;
+     756             : 
+     757        1972 :   _allocatedBytes = 0;
+     758        1972 :   _usedBytes = 0;
+     759             : 
+     760        1972 :   _root = nullptr;
+     761        1972 :   _first = nullptr;
+     762        1972 :   _last = nullptr;
+     763        1972 :   _optimal = nullptr;
+     764             : 
+     765        1972 :   _permanent = nullptr;
+     766        1972 :   _keepVirtualMemory = false;
+     767        1972 : }
+     768             : 
+     769        1972 : VMemMgr::~VMemMgr() noexcept {
+     770             :   // Freeable memory cleanup - Also frees the virtual memory if configured to.
+     771        1972 :   vMemMgrReset(this, _keepVirtualMemory);
+     772             : 
+     773             :   // Permanent memory cleanup - Never frees the virtual memory.
+     774        1972 :   PermanentNode* node = _permanent;
+     775        1972 :   while (node) {
+     776           0 :     PermanentNode* prev = node->prev;
+     777             :     Internal::releaseMemory(node);
+     778             :     node = prev;
+     779             :   }
+     780        1972 : }
+     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        1944 : void* VMemMgr::alloc(size_t size, uint32_t type) noexcept {
+     795        1944 :   if (type == kAllocPermanent)
+     796           0 :     return vMemMgrAllocPermanent(this, size);
+     797             :   else
+     798        1944 :     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.15
+
+ + + 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 0000000000..769227a74c --- /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-06-10 08:19:15Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit12X86AssemblerD2Ev1944
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_48254
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.func.html b/coverage-libs/asmjit/x86assembler.cpp.func.html new file mode 100644 index 0000000000..8d631c85e0 --- /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-06-10 08:19:15Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_48254
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86AssemblerD2Ev1944
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.gcov.html b/coverage-libs/asmjit/x86assembler.cpp.gcov.html new file mode 100644 index 0000000000..20ce4bb159 --- /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-06-10 08:19:15Functions: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       48254 :   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       48254 :   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        1944 : X86Assembler::X86Assembler(CodeHolder* code) noexcept : Assembler() {
+     382        1944 :   if (code)
+     383        1944 :     code->attach(this);
+     384        1944 : }
+     385        1944 : X86Assembler::~X86Assembler() noexcept {}
+     386             : 
+     387             : // ============================================================================
+     388             : // [asmjit::X86Assembler - Events]
+     389             : // ============================================================================
+     390             : 
+     391        1944 : Error X86Assembler::onAttach(CodeHolder* code) noexcept {
+     392             :   uint32_t archType = code->getArchType();
+     393        1944 :   if (!ArchInfo::isX86Family(archType))
+     394             :     return DebugUtils::errored(kErrorInvalidArch);
+     395             : 
+     396        1944 :   ASMJIT_PROPAGATE(Base::onAttach(code));
+     397             : 
+     398        1944 :   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        1944 :     _nativeGpArray = x86OpData.gpq;
+     408             :   }
+     409             : 
+     410        1944 :   _nativeGpReg = _nativeGpArray[0];
+     411        1944 :   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       48254 : 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       48254 :   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       48254 :   uint8_t* cursor = _bufferPtr;
+     550       48254 :   uint32_t options = static_cast<uint32_t>(instId >= X86Inst::_kIdCount)       |
+     551       48254 :                      static_cast<uint32_t>((size_t)(_bufferEnd - cursor) < 16) |
+     552       48254 :                      getGlobalOptions() | getOptions();
+     553             : 
+     554       48254 :   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       48254 :   uint32_t isign3 = o0.getOp() + (o1.getOp() << 3) + (o2.getOp() << 6);
+     569             : 
+     570       48254 :   if (ASMJIT_UNLIKELY(options & kErrorsAndSpecialCases)) {
+     571             :     // Don't do anything if we are in error state.
+     572        1944 :     if (_lastError) return _lastError;
+     573             : 
+     574        1944 :     if (options & CodeEmitter::kOptionMaybeFailureCase) {
+     575             :       // Unknown instruction.
+     576        1944 :       if (ASMJIT_UNLIKELY(instId >= X86Inst::_kIdCount))
+     577           0 :         goto InvalidArgument;
+     578             : 
+     579             :       // Grow request, happens rarely.
+     580        1944 :       if ((size_t)(_bufferEnd - cursor) < 16) {
+     581        1944 :         err = _code->growBuffer(&_section->_buffer, 16);
+     582        1944 :         if (ASMJIT_UNLIKELY(err)) goto Failed;
+     583             : 
+     584        1944 :         cursor = _bufferPtr;
+     585        1944 :         options &= ~1;
+     586             :       }
+     587             :     }
+     588             : 
+     589             :     // Strict validation.
+     590             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+     591        1944 :     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        1944 :     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        1944 :     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       48254 :   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        1636 :     case X86Inst::kEncodingX86Call:
+    1063        1636 :       if (isign3 == ENC_OPS1(Reg)) {
+    1064             :         rbReg = o0.getId();
+    1065        1636 :         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        7652 :     case X86Inst::kEncodingX86Mov:
+    1399             :       // Reg <- Reg
+    1400        7652 :       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        7652 :       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        7652 :       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        7652 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    1587             :         opReg = o0.getId();
+    1588        7652 :         imLen = o0.getSize();
+    1589             : 
+    1590        7652 :         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        7652 :           if (imLen == 8 && !(options & X86Inst::kOptionLongForm)) {
+    1603        7652 :             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        7652 :             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        7652 :           ADD_PREFIX_BY_SIZE(imLen);
+    1621        7652 :           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        1108 :     case X86Inst::kEncodingX86Push:
+    1710        1108 :       if (isign3 == ENC_OPS1(Reg)) {
+    1711        1108 :         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        1108 :           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        1108 :       if (isign3 == ENC_OPS1(Reg)) {
+    1741        1108 :         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        2216 : 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        2216 :           if (ASMJIT_UNLIKELY(o0.getSize() < 2))
+    1758           0 :             goto InvalidInstruction;
+    1759             : 
+    1760             :           opCode = commonData->getAltOpCode();
+    1761             :           opReg = o0.getId();
+    1762             : 
+    1763        2216 :           ADD_66H_P_BY_SIZE(o0.getSize());
+    1764        2216 :           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        1944 :     case X86Inst::kEncodingX86Ret:
+    1782        1944 :       if (isign3 == 0) {
+    1783             :         // 'ret' without immediate, change C2 to C3.
+    1784        1944 :         opCode++;
+    1785        1944 :         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       23804 :     case X86Inst::kEncodingExtMov:
+    2349             :       // GP|MMX|XMM <- GP|MMX|XMM
+    2350       23804 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2351             :         opReg = o0.getId();
+    2352             :         rbReg = o1.getId();
+    2353             : 
+    2354        9308 :         if (!(options & X86Inst::kOptionModMR) || !commonData->hasAltOpCode())
+    2355        9308 :           goto EmitX86R;
+    2356             : 
+    2357             :         opCode = commonData->getAltOpCode();
+    2358             :         Utils::swap(opReg, rbReg);
+    2359           0 :         goto EmitX86R;
+    2360             :       }
+    2361             : 
+    2362             :       // GP|MMX|XMM <- Mem
+    2363       14496 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2364             :         opReg = o0.getId();
+    2365             :         rmRel = &o1;
+    2366       10250 :         goto EmitX86M;
+    2367             :       }
+    2368             : 
+    2369             :       // The following instruction uses opCode[1].
+    2370             :       opCode = commonData->getAltOpCode();
+    2371             : 
+    2372             :       // Mem <- GP|MMX|XMM
+    2373        4246 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2374             :         opReg = o1.getId();
+    2375             :         rmRel = &o0;
+    2376        4246 :         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        9018 : CaseExtRm:
+    2551        9018 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2552             :         opReg = o0.getId();
+    2553             :         rbReg = o1.getId();
+    2554        9018 :         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        1944 :   EMIT_PP(opCode);
+    3575             : 
+    3576             :   // Emit REX prefix (64-bit only).
+    3577             :   {
+    3578             :     uint32_t rex = x86ExtractREX(opCode, options);
+    3579        1944 :     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        1944 :   EMIT_MM_OP(opCode);
+    3588             : 
+    3589        1944 :   if (imLen != 0)
+    3590           0 :     goto EmitImm;
+    3591             :   else
+    3592        1944 :     goto EmitDone;
+    3593             : 
+    3594        9868 : EmitX86OpReg:
+    3595             :   // Emit mandatory instruction prefix.
+    3596        9868 :   EMIT_PP(opCode);
+    3597             : 
+    3598             :   // Emit REX prefix (64-bit only).
+    3599             :   {
+    3600             :     uint32_t rex = x86ExtractREX(opCode, options) |
+    3601        9868 :                    (opReg >> 3); // Rex.B (0x01).
+    3602        9868 :     if (rex) {
+    3603        7652 :       EMIT_BYTE(rex | kX86ByteRex);
+    3604        7652 :       if (options & X86Inst::_kOptionInvalidRex)
+    3605           0 :         goto InvalidRexPrefix;
+    3606        7652 :       opReg &= 0x7;
+    3607             :     }
+    3608             :   }
+    3609             : 
+    3610             :   // Emit instruction opcodes.
+    3611        9868 :   opCode += opReg;
+    3612        9868 :   EMIT_MM_OP(opCode);
+    3613             : 
+    3614        9868 :   if (imLen != 0)
+    3615        7652 :     goto EmitImm;
+    3616             :   else
+    3617        2216 :     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       21946 : EmitX86R:
+    3655             :   // Mandatory instruction prefix.
+    3656       21946 :   EMIT_PP(opCode);
+    3657             : 
+    3658             :   // Rex prefix (64-bit only).
+    3659             :   {
+    3660       21946 :     uint32_t rex = x86ExtractREX(opCode, options) |
+    3661       21946 :                    ((opReg & 0x08) >> 1) | // REX.R (0x04).
+    3662       21946 :                    ((rbReg       ) >> 3) ; // REX.B (0x01).
+    3663       21946 :     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       21946 :   EMIT_MM_OP(opCode);
+    3674             :   // ModR.
+    3675       21946 :   EMIT_BYTE(x86EncodeMod(3, opReg, rbReg));
+    3676             : 
+    3677       21946 :   if (imLen != 0)
+    3678        1984 :     goto EmitImm;
+    3679             :   else
+    3680       19962 :     goto EmitDone;
+    3681             : 
+    3682       14496 : EmitX86M:
+    3683             :   ASMJIT_ASSERT(rmRel != nullptr);
+    3684             :   ASMJIT_ASSERT(rmRel->getOp() == Operand::kOpMem);
+    3685       14496 :   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       14496 :   if (rmRel->as<X86Mem>().hasSegment())
+    3692           0 :     EMIT_BYTE(x86SegmentPrefix[rmRel->as<X86Mem>().getSegmentId()]);
+    3693             : 
+    3694             :   // Address-override prefix.
+    3695       14496 :   if (rmInfo & _getAddressOverrideMask())
+    3696           0 :     EMIT_BYTE(0x67);
+    3697             : 
+    3698             :   // Mandatory instruction prefix.
+    3699       14496 :   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       14496 :     rex  = (rbReg >> 3) & 0x01; // REX.B (0x01).
+    3709       14496 :     rex |= (rxReg >> 2) & 0x02; // REX.X (0x02).
+    3710       14496 :     rex |= (opReg >> 1) & 0x04; // REX.R (0x04).
+    3711             : 
+    3712       14496 :     rex &= rmInfo;
+    3713       14496 :     rex |= x86ExtractREX(opCode, options);
+    3714             : 
+    3715       14496 :     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       14496 :   EMIT_MM_OP(opCode);
+    3725             :   // ... Fall through ...
+    3726             : 
+    3727             :   // --------------------------------------------------------------------------
+    3728             :   // [Emit - MOD/SIB]
+    3729             :   // --------------------------------------------------------------------------
+    3730             : 
+    3731       14496 : EmitModSib:
+    3732       14496 :   if (!(rmInfo & (kX86MemInfo_Index | kX86MemInfo_67H_X86))) {
+    3733             :     // ==========|> [BASE + DISP8|DISP32].
+    3734       14496 :     if (rmInfo & kX86MemInfo_BaseGp) {
+    3735       14496 :       rbReg &= 0x7;
+    3736             :       relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3737             : 
+    3738             :       uint32_t mod = x86EncodeMod(0, opReg, rbReg);
+    3739       14496 :       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        6068 :       else if (rbReg != X86Gp::kIdBp && relOffset == 0) {
+    3763             :         // [BASE].
+    3764        3870 :         EMIT_BYTE(mod);
+    3765             :       }
+    3766             :       else {
+    3767             :         // [BASE + DISP8|DISP32].
+    3768        2198 :         uint32_t cdShift = (opCode & X86Inst::kOpCode_CDSHL_Mask) >> X86Inst::kOpCode_CDSHL_Shift;
+    3769        2198 :         int32_t cdOffset = relOffset >> cdShift;
+    3770             : 
+    3771        2198 :         if (Utils::isInt8(cdOffset) && relOffset == (cdOffset << cdShift)) {
+    3772        2186 :           EMIT_BYTE(mod + 0x40);
+    3773        2186 :           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       14496 :   if (imLen != 0)
+    4013           0 :     goto EmitImm;
+    4014             :   else
+    4015       14496 :     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        9636 :     uint32_t i = imLen;
+    4476        9636 :     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        9636 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4484        7652 :     imm >>= 8;
+    4485        7652 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4486        7652 :     imm >>= 8;
+    4487        7652 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4488        7652 :     imm >>= 8;
+    4489        7652 :     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        7652 :     imm >>= 8;
+    4496        7652 :     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       48254 : EmitDone:
+    4507             : #if !defined(ASMJIT_DISABLE_LOGGING)
+    4508             :   // Logging is a performance hit anyway, so make it the unlikely case.
+    4509       48254 :   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       48254 :   _bufferPtr = cursor;
+    4518       48254 :   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.15
+
+ + + 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 0000000000..523a97ea59 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.h.func.html b/coverage-libs/asmjit/x86assembler.h.func.html new file mode 100644 index 0000000000..c9660e7ed3 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.h.gcov.html b/coverage-libs/asmjit/x86assembler.h.gcov.html new file mode 100644 index 0000000000..19278c323e --- /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-06-10 08:19:15Functions: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       14496 :   ASMJIT_INLINE uint32_t _getAddressOverrideMask() const noexcept { return _privateData; }
+      94        1944 :   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.15
+
+ + + 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 0000000000..119423466e --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/x86builder.cpp.func.html b/coverage-libs/asmjit/x86builder.cpp.func.html new file mode 100644 index 0000000000..a773337887 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/x86builder.cpp.gcov.html b/coverage-libs/asmjit/x86builder.cpp.gcov.html new file mode 100644 index 0000000000..d1b61d7d31 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..2895652b58 --- /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-06-10 08:19:15Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv1944
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit11X86CompilerD2Ev1944
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_46618
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.cpp.func.html b/coverage-libs/asmjit/x86compiler.cpp.func.html new file mode 100644 index 0000000000..f1eb21ad2c --- /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-06-10 08:19:15Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_46618
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv1944
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE1944
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86CompilerD2Ev1944
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.cpp.gcov.html b/coverage-libs/asmjit/x86compiler.cpp.gcov.html new file mode 100644 index 0000000000..5bfd0cecc7 --- /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-06-10 08:19:15Functions: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        1944 : X86Compiler::X86Compiler(CodeHolder* code) noexcept : CodeCompiler() {
+      52        1944 :   if (code)
+      53        1944 :     code->attach(this);
+      54        1944 : }
+      55        1944 : X86Compiler::~X86Compiler() noexcept {}
+      56             : 
+      57             : // ============================================================================
+      58             : // [asmjit::X86Compiler - Events]
+      59             : // ============================================================================
+      60             : 
+      61        1944 : Error X86Compiler::onAttach(CodeHolder* code) noexcept {
+      62             :   uint32_t archType = code->getArchType();
+      63        1944 :   if (!ArchInfo::isX86Family(archType))
+      64             :     return DebugUtils::errored(kErrorInvalidArch);
+      65             : 
+      66        3888 :   ASMJIT_PROPAGATE(_cbPasses.willGrow(&_cbHeap, 1));
+      67        1944 :   ASMJIT_PROPAGATE(Base::onAttach(code));
+      68             : 
+      69        1944 :   if (archType == ArchInfo::kTypeX86)
+      70           0 :     _nativeGpArray = x86OpData.gpd;
+      71             :   else
+      72        1944 :     _nativeGpArray = x86OpData.gpq;
+      73        1944 :   _nativeGpReg = _nativeGpArray[0];
+      74             : 
+      75        3888 :   return addPassT<X86RAPass>();
+      76             : }
+      77             : 
+      78             : // ============================================================================
+      79             : // [asmjit::X86Compiler - Finalize]
+      80             : // ============================================================================
+      81             : 
+      82        1944 : Error X86Compiler::finalize() {
+      83        1944 :   if (_lastError) return _lastError;
+      84             : 
+      85             :   // Flush the global constant pool.
+      86        1944 :   if (_globalConstPool) {
+      87           0 :     addNode(_globalConstPool);
+      88           0 :     _globalConstPool = nullptr;
+      89             :   }
+      90             : 
+      91             :   Error err = kErrorOk;
+      92             :   ZoneVector<CBPass*>& passes = _cbPasses;
+      93             : 
+      94        3888 :   for (size_t i = 0, len = passes.getLength(); i < len; i++) {
+      95        1944 :     CBPass* pass = passes[i];
+      96        1944 :     err = pass->process(&_cbPassZone);
+      97        1944 :     _cbPassZone.reset();
+      98        1944 :     if (err) break;
+      99             :   }
+     100             : 
+     101        1944 :   _cbPassZone.reset();
+     102        1944 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     103             : 
+     104             :   // TODO: There must be possibility to attach more assemblers, this is not so nice.
+     105        1944 :   if (_code->_cgAsm) {
+     106           0 :     return serialize(_code->_cgAsm);
+     107             :   }
+     108             :   else {
+     109        1944 :     X86Assembler a(_code);
+     110        1944 :     return serialize(&a);
+     111        1944 :   }
+     112             : }
+     113             : 
+     114             : // ============================================================================
+     115             : // [asmjit::X86Compiler - Inst]
+     116             : // ============================================================================
+     117             : 
+     118             : static ASMJIT_INLINE bool isJumpInst(uint32_t instId) noexcept {
+     119       46618 :   return (instId >= X86Inst::kIdJa   && instId <= X86Inst::kIdJz    ) ||
+     120       46618 :          (instId >= X86Inst::kIdLoop && instId <= X86Inst::kIdLoopne) ;
+     121             : }
+     122             : 
+     123       46618 : Error X86Compiler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+     124       46618 :   uint32_t options = getOptions() | getGlobalOptions();
+     125             :   const char* inlineComment = getInlineComment();
+     126             : 
+     127       46618 :   uint32_t opCount = static_cast<uint32_t>(!o0.isNone()) +
+     128       46618 :                      static_cast<uint32_t>(!o1.isNone()) +
+     129       46618 :                      static_cast<uint32_t>(!o2.isNone()) +
+     130       46618 :                      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       46618 :   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       46618 :   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       46618 :     CBInst* node = _cbHeap.allocT<CBInst>(sizeof(CBInst) + opCount * sizeof(Operand));
+     229       46618 :     Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CBInst));
+     230             : 
+     231       46618 :     if (ASMJIT_UNLIKELY(!node))
+     232           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     233             : 
+     234       46618 :     if (opCount > 0) opArray[0].copyFrom(o0);
+     235       46618 :     if (opCount > 1) opArray[1].copyFrom(o1);
+     236       46618 :     if (opCount > 2) opArray[2].copyFrom(o2);
+     237       46618 :     if (opCount > 3) opArray[3].copyFrom(o3);
+     238             : 
+     239             :     node = new(node) CBInst(this, instId, options, opArray, opCount);
+     240       46618 :     node->_instDetail.extraReg = _extraReg;
+     241             :     _extraReg.reset();
+     242             : 
+     243       46618 :     if (inlineComment) {
+     244           0 :       inlineComment = static_cast<char*>(_cbDataZone.dup(inlineComment, ::strlen(inlineComment), true));
+     245             :       node->setInlineComment(inlineComment);
+     246             :     }
+     247             : 
+     248       46618 :     addNode(node);
+     249       46618 :     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.15
+
+ + + 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 0000000000..8627c3e718 --- /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-06-10 08:19:15Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler6newGpzEPKcz0
_ZN4PLMD6asmjit11X86Compiler6newRegEjPKcz0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.h.func.html b/coverage-libs/asmjit/x86compiler.h.func.html new file mode 100644 index 0000000000..cbecdd5615 --- /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-06-10 08:19:15Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler6newGpzEPKcz0
_ZN4PLMD6asmjit11X86Compiler6newRegEjPKcz0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.h.gcov.html b/coverage-libs/asmjit/x86compiler.h.gcov.html new file mode 100644 index 0000000000..f8f783a852 --- /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-06-10 08:19:15Functions: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        7248 :   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       16492 :   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        1636 :   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        1944 :   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.15
+
+ + + 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 0000000000..9b8908ec2c --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86emitter.h.func.html b/coverage-libs/asmjit/x86emitter.h.func.html new file mode 100644 index 0000000000..64eec4eb57 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86emitter.h.gcov.html b/coverage-libs/asmjit/x86emitter.h.gcov.html new file mode 100644 index 0000000000..da69e41159 --- /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-06-10 08:19:15Functions: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        5832 :     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        7248 :   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        1108 :   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        1108 :   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        1990 :   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        8652 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Xmm)                                // SSE2
+    1166        5826 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Mem)                                // SSE2
+    1167         242 :   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         994 :   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         252 :   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.15
+
+ + + 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 0000000000..3b29f0147f --- /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-06-10 08:19:15Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7X86Inst11getIdByNameEPKcm0
_ZN4PLMD6asmjit7X86Inst11getNameByIdEj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.cpp.func.html b/coverage-libs/asmjit/x86inst.cpp.func.html new file mode 100644 index 0000000000..5b229fa0c7 --- /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-06-10 08:19:15Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7X86Inst11getIdByNameEPKcm0
_ZN4PLMD6asmjit7X86Inst11getNameByIdEj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.cpp.gcov.html b/coverage-libs/asmjit/x86inst.cpp.gcov.html new file mode 100644 index 0000000000..39ff609fb3 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..68899cb83b --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.func.html b/coverage-libs/asmjit/x86inst.h.func.html new file mode 100644 index 0000000000..044365691c --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.gcov.html b/coverage-libs/asmjit/x86inst.h.gcov.html new file mode 100644 index 0000000000..b3d6b82e55 --- /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-06-10 08:19:15Functions: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       30864 :     ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+    2157             :     //! Get if the instruction has a `flag`, see \ref X86Inst::Flags.
+    2158       72996 :     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       30864 :     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       21852 :     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        5826 :     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       48254 :   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       48254 :   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       81304 : ASMJIT_INLINE const X86Inst::CommonData& X86Inst::getCommonData() const noexcept { return X86InstDB::commonData[_commonDataIndex]; }
+    2522        5826 : 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        6462 : 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.15
+
+ + + 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 0000000000..55113f9357 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/x86instimpl.cpp.func.html b/coverage-libs/asmjit/x86instimpl.cpp.func.html new file mode 100644 index 0000000000..4704e66e61 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/x86instimpl.cpp.gcov.html b/coverage-libs/asmjit/x86instimpl.cpp.gcov.html new file mode 100644 index 0000000000..80103c1e7d --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..a8e07c4357 --- /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-06-10 08:19:15Functions: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_15FuncFrameLayoutE1944
_ZN4PLMD6asmjit11X86Internal10emitPrologEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1944
_ZN4PLMD6asmjit11X86Internal15initFrameLayoutERNS0_15FuncFrameLayoutERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1944
_ZN4PLMD6asmjit11X86Internal12initCallConvERNS0_8CallConvEj3580
_ZN4PLMD6asmjit11X86Internal14initFuncDetailERNS0_10FuncDetailERKNS0_13FuncSignatureEj3580
_ZN4PLMD6asmjit11X86Internal11emitRegMoveEPNS0_10X86EmitterERKNS0_8Operand_ES6_jbPKc9084
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86internal.cpp.func.html b/coverage-libs/asmjit/x86internal.cpp.func.html new file mode 100644 index 0000000000..9e36d7f8d4 --- /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-06-10 08:19:15Functions:61442.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Internal10emitEpilogEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1944
_ZN4PLMD6asmjit11X86Internal10emitPrologEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1944
_ZN4PLMD6asmjit11X86Internal11emitArgMoveEPNS0_10X86EmitterERKNS0_6X86RegEjRKNS0_8Operand_EjbPKc0
_ZN4PLMD6asmjit11X86Internal11emitRegMoveEPNS0_10X86EmitterERKNS0_8Operand_ES6_jbPKc9084
_ZN4PLMD6asmjit11X86Internal12initCallConvERNS0_8CallConvEj3580
_ZN4PLMD6asmjit11X86Internal14initFuncDetailERNS0_10FuncDetailERKNS0_13FuncSignatureEj3580
_ZN4PLMD6asmjit11X86Internal15argsToFrameInfoERKNS0_14FuncArgsMapperERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit11X86Internal15initFrameLayoutERNS0_15FuncFrameLayoutERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1944
_ZN4PLMD6asmjit11X86Internal9allocArgsEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZN4PLMD6asmjit18X86FuncArgsContext12initWorkDataERKNS0_14FuncArgsMapperEPKjb0
_ZN4PLMD6asmjit18X86FuncArgsContext16markDstRegsDirtyERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markRegsForSwapsERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markStackArgsRegERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContextC2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86internal.cpp.gcov.html b/coverage-libs/asmjit/x86internal.cpp.gcov.html new file mode 100644 index 0000000000..8f937466b3 --- /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-06-10 08:19:15Functions: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        1446 :   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        3580 : 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        3580 :   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        3580 :   return kErrorOk;
+     414             : }
+     415             : 
+     416             : // ============================================================================
+     417             : // [asmjit::X86Internal - FuncDetail]
+     418             : // ============================================================================
+     419             : 
+     420        3580 : 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        3580 :   if (func.getRetCount() != 0) {
+     428             :     uint32_t typeId = func._rets[0].getTypeId();
+     429        3580 :     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        3580 :       case TypeId::kF32:
+     459             :       case TypeId::kF64: {
+     460        3580 :         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        3580 :   uint32_t stackBase = gpSize;
+     490        3580 :   uint32_t stackOffset = stackBase + cc._spillZoneSize;
+     491             : 
+     492        3580 :   if (cc.getAlgorithm() == CallConv::kAlgorithmDefault) {
+     493             :     uint32_t gpzPos = 0;
+     494             :     uint32_t vecPos = 0;
+     495             : 
+     496        5430 :     for (i = 0; i < argCount; i++) {
+     497             :       FuncDetail::Value& arg = func._args[i];
+     498             :       uint32_t typeId = arg.getTypeId();
+     499             : 
+     500        1850 :       if (TypeId::isInt(typeId)) {
+     501         404 :         uint32_t regId = gpzPos < CallConv::kNumRegArgsPerKind ? cc._passedOrder[X86Reg::kKindGp].id[gpzPos] : Globals::kInvalidRegId;
+     502         404 :         if (regId != Globals::kInvalidRegId) {
+     503             :           uint32_t regType = (typeId <= TypeId::kU32)
+     504         404 :             ? X86Reg::kRegGpd
+     505             :             : X86Reg::kRegGpq;
+     506             :           arg.assignToReg(regType, regId);
+     507             :           func.addUsedRegs(X86Reg::kKindGp, Utils::mask(regId));
+     508         404 :           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         404 :         continue;
+     516         404 :       }
+     517             : 
+     518        1446 :       if (TypeId::isFloat(typeId) || TypeId::isVec(typeId)) {
+     519        1446 :         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        1446 :         if (TypeId::isFloat(typeId) && !cc.hasFlag(CallConv::kFlagPassFloatsByVec))
+     523             :           regId = Globals::kInvalidRegId;
+     524             : 
+     525        1446 :         if (regId != Globals::kInvalidRegId) {
+     526             :           arg.initReg(typeId, x86VecTypeIdToRegType(typeId), regId);
+     527             :           func.addUsedRegs(X86Reg::kKindVec, Utils::mask(regId));
+     528        1446 :           vecPos++;
+     529             :         }
+     530             :         else {
+     531             :           int32_t size = TypeId::sizeOf(typeId);
+     532             :           arg.assignToStack(stackOffset);
+     533           0 :           stackOffset += size;
+     534             :         }
+     535        1446 :         continue;
+     536        1446 :       }
+     537             :     }
+     538             :   }
+     539             : 
+     540        3580 :   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        3580 :   func._argStackSize = stackOffset - stackBase;
+     583        3580 :   return kErrorOk;
+     584             : }
+     585             : 
+     586             : // ============================================================================
+     587             : // [asmjit::X86Internal - FrameLayout]
+     588             : // ============================================================================
+     589             : 
+     590        1944 : ASMJIT_FAVOR_SIZE Error X86Internal::initFrameLayout(FuncFrameLayout& layout, const FuncDetail& func, const FuncFrameInfo& ffi) noexcept {
+     591             :   layout.reset();
+     592             : 
+     593             :   uint32_t kind;
+     594        1944 :   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        9720 :   for (kind = 0; kind < Globals::kMaxVRegKinds; kind++)
+     598        7776 :     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        1944 :   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        1944 :   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        1944 :         ffi.getStackFrameAlignment(),
+     614        1944 :         ffi.getCallFrameAlignment()),
+     615        1944 :       func.getCallConv().getNaturalStackAlignment());
+     616        1944 :   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        1944 :   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        1944 :   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        1944 :   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        1944 :   if (dsa && stackArgsRegId == X86Gp::kIdSp)
+     637             :     stackArgsRegId = X86Gp::kIdBp;
+     638             : 
+     639        1944 :   if (stackArgsRegId != X86Gp::kIdSp)
+     640           0 :     layout._savedRegs[X86Reg::kKindGp] |= Utils::mask(stackArgsRegId) & func.getPreservedRegs(X86Gp::kKindGp);
+     641             : 
+     642        1944 :   layout._stackBaseRegId = X86Gp::kIdSp;
+     643        1944 :   layout._stackArgsRegId = static_cast<uint8_t>(stackArgsRegId);
+     644             : 
+     645             :   // Setup stack size used to save preserved registers.
+     646        1944 :   layout._gpStackSize  = Utils::bitCount(layout.getSavedRegs(X86Reg::kKindGp )) * gpSize;
+     647        1944 :   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        1944 :   v += ffi._callFrameSize;               // Count '_callFrameSize'  <- This is used to call functions.
+     652             :   v  = Utils::alignTo(v, stackAlignment);// Align to function's SA
+     653             : 
+     654        1944 :   layout._stackBaseOffset = v;           // Store '_stackBaseOffset'<- Function's own stack starts here..
+     655        1944 :   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        1944 :   if (stackAlignment >= 16 && layout._vecStackSize) {
+     662             :     v = Utils::alignTo(v, 16);           // Align '_vecStackOffset'.
+     663           0 :     layout._alignedVecSR = true;
+     664             :   }
+     665             : 
+     666        1944 :   layout._vecStackOffset = v;            // Store '_vecStackOffset' <- Functions VEC Save|Restore starts here.
+     667        1944 :   v += layout._vecStackSize;             // Count '_vecStackSize'   <- Functions VEC Save|Restore ends here.
+     668             : 
+     669        1944 :   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        1944 :   if (v || ffi.hasCalls())
+     684        1080 :     v += Utils::alignDiff(v + layout._gpStackSize + gpSize, stackAlignment);
+     685             : 
+     686        1944 :   layout._stackAdjustment = v;           // Store '_stackAdjustment'<- SA used by 'add zsp, SA' and 'sub zsp, SA'.
+     687        1944 :   layout._gpStackOffset = v;             // Store '_gpStackOffset'  <- Functions GP Save|Restore starts here.
+     688        1944 :   v += layout._gpStackSize;              // Count '_gpStackSize'    <- Functions GP Save|Restore ends here.
+     689             : 
+     690        1944 :   v += gpSize;                           // Count 'ReturnAddress'.
+     691        1944 :   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        1944 :   if (stackArgsRegId != X86Gp::kIdSp) {
+     699           0 :     if (ffi.hasPreservedFP())
+     700             :       stackArgsOffset = gpSize;
+     701             :     else
+     702             :       stackArgsOffset = layout._gpStackSize;
+     703             :   }
+     704        1944 :   layout._stackArgsOffset = stackArgsOffset;
+     705             : 
+     706             :   // If the function does dynamic stack adjustment then the stack-adjustment
+     707             :   // must be aligned.
+     708        1944 :   if (dsa)
+     709           0 :     layout._stackAdjustment = Utils::alignTo(layout._stackAdjustment, stackAlignment);
+     710             : 
+     711             :   // Initialize variables based on CallConv flags.
+     712        1944 :   if (func.hasFlag(CallConv::kFlagCalleePopsStack))
+     713           0 :     layout._calleeStackCleanup = static_cast<uint16_t>(func.getArgStackSize());
+     714             : 
+     715             :   // Initialize variables based on FFI flags.
+     716        1944 :   layout._mmxCleanup = ffi.hasMmxCleanup();
+     717        1944 :   layout._avxEnabled = ffi.isAvxEnabled();
+     718        1944 :   layout._avxCleanup = ffi.hasAvxCleanup();
+     719             : 
+     720        1944 :   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        1944 : 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        1944 :   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        1944 :   if (gpSaved) {
+    1067        5408 :     for (uint32_t i = gpSaved, regId = 0; i; i >>= 1, regId++) {
+    1068        4344 :       if (!(i & 0x1)) continue;
+    1069             :       gpReg.setId(regId);
+    1070        1108 :       ASMJIT_PROPAGATE(emitter->push(gpReg));
+    1071             :     }
+    1072             :   }
+    1073             : 
+    1074             :   // Emit: 'mov saReg, zsp'.
+    1075             :   uint32_t stackArgsRegId = layout.getStackArgsRegId();
+    1076        1944 :   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        1944 :   if (layout.hasDynamicAlignment())
+    1084           0 :     ASMJIT_PROPAGATE(emitter->and_(zsp, -static_cast<int32_t>(layout.getStackAlignment())));
+    1085             : 
+    1086             :   // Emit: 'sub zsp, StackAdjustment'.
+    1087        1944 :   if (layout.hasStackAdjustment())
+    1088         932 :     ASMJIT_PROPAGATE(emitter->sub(zsp, layout.getStackAdjustment()));
+    1089             : 
+    1090             :   // Emit: 'mov [zsp + dsaSlot], saReg'.
+    1091        1944 :   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        1944 :   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        1944 : 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        1944 :   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        1944 :   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        1944 :   if (layout.hasMmxCleanup()) ASMJIT_PROPAGATE(emitter->emms());
+    1149        1944 :   if (layout.hasAvxCleanup()) ASMJIT_PROPAGATE(emitter->vzeroupper());
+    1150             : 
+    1151        1944 :   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        1944 :     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        1944 :     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        1944 :   if (gpSaved) {
+    1173             :     i = gpSaved;
+    1174             :     regId = 16;
+    1175             : 
+    1176             :     do {
+    1177       17024 :       regId--;
+    1178       17024 :       if (i & 0x8000) {
+    1179             :         gpReg.setId(regId);
+    1180        1108 :         ASMJIT_PROPAGATE(emitter->pop(gpReg));
+    1181             :       }
+    1182       17024 :       i <<= 1;
+    1183       17024 :     } while (regId != 0);
+    1184             :   }
+    1185             : 
+    1186             :   // Emit 'pop zbp'.
+    1187        1944 :   if (layout.hasPreservedFP()) ASMJIT_PROPAGATE(emitter->pop(zbp));
+    1188             : 
+    1189             :   // Emit 'ret' or 'ret x'.
+    1190        1944 :   if (layout.hasCalleeStackCleanup())
+    1191           0 :     ASMJIT_PROPAGATE(emitter->emit(X86Inst::kIdRet, static_cast<int>(layout.getCalleeStackCleanup())));
+    1192             :   else
+    1193        1944 :     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.15
+
+ + + 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 0000000000..a90ecabb0f --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/x86logging.cpp.func.html b/coverage-libs/asmjit/x86logging.cpp.func.html new file mode 100644 index 0000000000..7065faeced --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/asmjit/x86logging.cpp.gcov.html b/coverage-libs/asmjit/x86logging.cpp.gcov.html new file mode 100644 index 0000000000..63dac8c809 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..1f400ff25a --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86misc.h.func.html b/coverage-libs/asmjit/x86misc.h.func.html new file mode 100644 index 0000000000..85fee01e39 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86misc.h.gcov.html b/coverage-libs/asmjit/x86misc.h.gcov.html new file mode 100644 index 0000000000..1a83008bb3 --- /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-06-10 08:19:15Functions: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      113778 :   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      572782 :     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      122748 :     _packed += n << shift;
+     132       61374 :   }
+     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       36630 :     uint32_t x = static_cast<uint32_t>(count._regs[0]);
+     150       36630 :     uint32_t y = static_cast<uint32_t>(count._regs[1]) + x;
+     151       36630 :     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       54712 :     switch (kind) {
+     231       95434 :       case X86Reg::kKindGp : return _gp;
+     232      214776 :       case X86Reg::kKindVec: return _vec;
+     233       41230 :       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       16588 :       case X86Reg::kKindGp : _gp  = static_cast<uint16_t>(mask); break;
+     278        3272 :       case X86Reg::kKindMm : _mm  = static_cast<uint8_t >(mask); break;
+     279        1636 :       case X86Reg::kKindK  : _k   = static_cast<uint8_t >(mask); break;
+     280       30710 :       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        7248 :       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       22440 :       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       33050 :   }
+     344             : 
+     345             :   ASMJIT_INLINE void or_(uint32_t kind, uint32_t mask) noexcept {
+     346             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     347        1944 :     switch (kind) {
+     348       14496 :       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       42860 :       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.15
+
+ + + 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 0000000000..3c882de990 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86operand.h.func.html b/coverage-libs/asmjit/x86operand.h.func.html new file mode 100644 index 0000000000..704982951c --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86operand.h.gcov.html b/coverage-libs/asmjit/x86operand.h.gcov.html new file mode 100644 index 0000000000..bfbf573893 --- /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-06-10 08:19:15Functions: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        6068 :     uint32_t signature = (base.getType()   << kSignatureMemBaseTypeShift ) |
+     126             :                          (size             << kSignatureSizeShift        ) ;
+     127             : 
+     128        6068 :     _init_packed_d0_d1(kOpMem | signature | flags, 0);
+     129        6068 :     _mem.base = base.getId();
+     130        6068 :     _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        1944 :   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       16492 : 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.15
+
+ + + 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 0000000000..d4213f90a4 --- /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-06-10 08:19:15Functions: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_7TiedRegE252
_ZN4PLMD6asmjit9X86RAPass12emitImmToRegEjjPKNS0_3ImmE404
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc656
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE1636
_ZN4PLMD6asmjit9X86RAPass5fetchEv1944
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE1944
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE1944
_ZN4PLMD6asmjit9X86RAPass9translateEv1944
_ZN4PLMD6asmjit9X86RAPassC2Ev1944
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE1944
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE1944
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE1944
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE1944
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc4004
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc4424
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej32742
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE34994
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.func.html b/coverage-libs/asmjit/x86regalloc.cpp.func.html new file mode 100644 index 0000000000..2827ba84ae --- /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-06-10 08:19:15Functions:172958.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE34994
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE1636
_ZN4PLMD6asmjit9X86RAPass10emitSwapGpEPNS0_7VirtRegES3_jjPKc0
_ZN4PLMD6asmjit9X86RAPass11_checkStateEv0
_ZN4PLMD6asmjit9X86RAPass11switchStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass12emitImmToRegEjjPKNS0_3ImmE404
_ZN4PLMD6asmjit9X86RAPass14emitImmToStackEjPKNS0_6X86MemEPKNS0_3ImmE0
_ZN4PLMD6asmjit9X86RAPass14emitRegToStackEjPKNS0_6X86MemEjj0
_ZN4PLMD6asmjit9X86RAPass15intersectStatesEPNS0_7RAStateES3_0
_ZN4PLMD6asmjit9X86RAPass5fetchEv1944
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE1944
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE1944
_ZN4PLMD6asmjit9X86RAPass8annotateEv0
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc4424
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc656
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc4004
_ZN4PLMD6asmjit9X86RAPass9loadStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass9saveStateEv0
_ZN4PLMD6asmjit9X86RAPass9translateEv1944
_ZN4PLMD6asmjit9X86RAPassC2Ev1944
_ZN4PLMD6asmjit9X86RAPassD0Ev0
_ZN4PLMD6asmjit9X86RAPassD2Ev0
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE1944
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE1944
_ZN4PLMD6asmjitL23X86RAPass_translateJumpEPNS0_9X86RAPassEPNS0_6CBJumpEPNS0_7CBLabelE0
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE1944
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej32742
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE1944
_ZN4PLMD6asmjitL30X86RAPass_prepareSingleVarInstEjPNS0_7TiedRegE252
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.gcov.html b/coverage-libs/asmjit/x86regalloc.cpp.gcov.html new file mode 100644 index 0000000000..4c7a297a27 --- /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-06-10 08:19:15Functions: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        1944 : X86RAPass::X86RAPass() noexcept : RAPass() {
+     200        1944 :   _state = &_x86State;
+     201        1944 :   _varMapToVaListOffset = ASMJIT_OFFSET_OF(X86RAData, tiedArray);
+     202        1944 : }
+     203           0 : X86RAPass::~X86RAPass() noexcept {}
+     204             : 
+     205             : // ============================================================================
+     206             : // [asmjit::X86RAPass - Interface]
+     207             : // ============================================================================
+     208             : 
+     209        1944 : Error X86RAPass::process(Zone* zone) noexcept {
+     210        1944 :   return Base::process(zone);
+     211             : }
+     212             : 
+     213        1944 : Error X86RAPass::prepare(CCFunc* func) noexcept {
+     214        1944 :   ASMJIT_PROPAGATE(Base::prepare(func));
+     215             : 
+     216             :   uint32_t archType = cc()->getArchType();
+     217        1944 :   _regCount._gp  = archType == ArchInfo::kTypeX86 ? 8 : 16;
+     218        1944 :   _regCount._mm  = 8;
+     219        1944 :   _regCount._k   = 8;
+     220        1944 :   _regCount._vec = archType == ArchInfo::kTypeX86 ? 8 : 16;
+     221             :   _zsp = cc()->zsp();
+     222             :   _zbp = cc()->zbp();
+     223             : 
+     224        1944 :   _gaRegs[X86Reg::kKindGp ] = Utils::bits(_regCount.getGp()) & ~Utils::mask(X86Gp::kIdSp);
+     225        1944 :   _gaRegs[X86Reg::kKindMm ] = Utils::bits(_regCount.getMm());
+     226        1944 :   _gaRegs[X86Reg::kKindK  ] = Utils::bits(_regCount.getK());
+     227        1944 :   _gaRegs[X86Reg::kKindVec] = Utils::bits(_regCount.getVec());
+     228             : 
+     229        1944 :   _x86State.reset(0);
+     230             :   _clobberedRegs.reset();
+     231             : 
+     232        1944 :   _avxEnabled = false;
+     233             : 
+     234        1944 :   _varBaseRegId = Globals::kInvalidRegId; // Used by patcher.
+     235        1944 :   _varBaseOffset = 0;                     // Used by patcher.
+     236             : 
+     237        1944 :   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         404 : 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         404 :   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         404 :       if (imm.isUInt32())
+     327           0 :         goto Mov32Truncate;
+     328             : 
+     329             :       r0.setX86RegT<X86Reg::kRegGpq>(dstPhysId);
+     330         404 :       cc()->emit(X86Inst::kIdMov, r0, imm);
+     331         404 :       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         404 :   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         252 : static void X86RAPass_prepareSingleVarInst(uint32_t instId, TiedReg* tr) {
+    1027         252 :   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         252 :     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         252 :       tr->flags &= ~TiedReg::kRReg;
+    1041         252 :       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         252 : }
+    1053             : 
+    1054             : // ============================================================================
+    1055             : // [asmjit::X86RAPass - Helpers]
+    1056             : // ============================================================================
+    1057             : 
+    1058        1944 : 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        1944 :   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        1944 :     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        1944 :     uint32_t regs = passed & ~used;
+    1084             : 
+    1085             :     // Pick any other register if that didn't work out.
+    1086        1944 :     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        1944 : }
+    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        1944 : 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      157464 :   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        1944 :   uint32_t* gaRegs = _gaRegs;
+    1275             : 
+    1276        1944 :   if (func->getFrameInfo().hasPreservedFP())
+    1277           0 :     gaRegs[X86Reg::kKindGp] &= ~Utils::mask(X86Gp::kIdBp);
+    1278             : 
+    1279             :   // Allowed index registers (GP/XMM/YMM).
+    1280        1944 :   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       34686 : _Do:
+    1381       36630 :     while (node_->hasPassData()) {
+    1382           0 : _NextGroup:
+    1383        1944 :       if (!jLink)
+    1384             :         jLink = _jccList.getFirst();
+    1385             :       else
+    1386             :         jLink = jLink->getNext();
+    1387             : 
+    1388        1944 :       if (!jLink) goto _Done;
+    1389             :       node_ = X86RAPass_getOppositeJccFlow(static_cast<CBJump*>(jLink->getValue()));
+    1390             :     }
+    1391             : 
+    1392       36630 :     position++;
+    1393             : 
+    1394             :     next = node_->getNext();
+    1395             :     node_->setPosition(position);
+    1396             : 
+    1397       36630 :     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       31106 :       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       31106 :         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       31106 :           if (commonData.isFpu())
+    1523             :             flags |= CBNode::kFlagIsFp;
+    1524             : 
+    1525       31106 :           if (commonData.hasFixedRM() && (special = X86SpecialInst_get(instId, opArray, opCount)) != nullptr)
+    1526           0 :             flags |= CBNode::kFlagIsSpecial;
+    1527             : 
+    1528       93438 :           for (uint32_t i = 0; i < opCount; i++) {
+    1529       62332 :             Operand* op = &opArray[i];
+    1530             :             VirtReg* vreg;
+    1531             :             TiedReg* tied;
+    1532             : 
+    1533             :             if (op->isVirtReg()) {
+    1534             :               vreg = cc()->getVirtRegById(op->getId());
+    1535       48896 :               if (vreg->isFixed()) continue;
+    1536             : 
+    1537      119644 :               RA_MERGE(vreg, tied, 0, gaRegs[vreg->getKind()] & gpAllowedMask);
+    1538       48896 :               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       48896 :               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       48896 :                 if (i == 0) {
+    1594             :                   // Read/Write is usually the combination of the first operand.
+    1595             :                   combinedFlags = inFlags | outFlags;
+    1596             : 
+    1597       30864 :                   if (node->getOptions() & CodeEmitter::kOptionOverwrite) {
+    1598             :                     // Manually forcing write-only.
+    1599             :                     combinedFlags = outFlags;
+    1600             :                   }
+    1601       30864 :                   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       21852 :                     if (opArray[1].isMem() && inst.getOperationData().isMovSsSd())
+    1609             :                       movSize = 16;
+    1610             : 
+    1611       21852 :                     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        7248 :                       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        7248 :                       if (movSize >= 4 || movSize >= regSize)
+    1624             :                         combinedFlags = outFlags;
+    1625             :                     }
+    1626       14604 :                     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        9012 :                   else if (commonData.isUseR()) {
+    1634             :                     // Comparison/Test instructions don't modify any operand.
+    1635             :                     combinedFlags = inFlags;
+    1636             :                   }
+    1637        9012 :                   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       18032 :                   if (commonData.isUseXX() || (instId == X86Inst::kIdImul && opCount == 3 && i == 1))
+    1651             :                     combinedFlags = inFlags | outFlags;
+    1652             :                 }
+    1653       48896 :                 tied->flags |= combinedFlags;
+    1654             :               }
+    1655             :             }
+    1656       13436 :             else if (op->isMem()) {
+    1657             :               X86Mem* m = static_cast<X86Mem*>(op);
+    1658             :               node->setMemOpIndex(i);
+    1659             : 
+    1660        6068 :               uint32_t specBase = special ? uint32_t(special[i].inReg) : uint32_t(Globals::kInvalidRegId);
+    1661             : 
+    1662        6068 :               if (m->hasBaseReg()) {
+    1663             :                 uint32_t id = m->getBaseId();
+    1664        6068 :                 if (cc()->isVirtRegValid(id)) {
+    1665             :                   vreg = cc()->getVirtRegById(id);
+    1666        6068 :                   if (!vreg->isStack() && !vreg->isFixed()) {
+    1667       12136 :                     RA_MERGE(vreg, tied, 0, gaRegs[vreg->getKind()] & gpAllowedMask);
+    1668        6068 :                     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        6068 :                       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        6068 :                         tied->flags |= TiedReg::kRReg;
+    1714             :                       }
+    1715             :                     }
+    1716             :                   }
+    1717             :                 }
+    1718             :               }
+    1719             : 
+    1720        6068 :               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       31106 :           if (tiedTotal) {
+    1738             :             // Handle instructions which result in zeros/ones or nop if used with the
+    1739             :             // same destination and source operand.
+    1740       31358 :             if (tiedTotal == 1 && opCount >= 2 && opArray[0].isVirtReg() && opArray[1].isVirtReg() && !node->hasMemOp())
+    1741         252 :               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       31106 :           if (tiedCount.getVec() && commonData.hasFlag(X86Inst::kFlagVex | X86Inst::kFlagEvex))
+    1746           0 :             _avxEnabled = true;
+    1747             :         }
+    1748             : 
+    1749             :         const RegOnly& extraReg = node->getExtraReg();
+    1750       31106 :         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       85818 :         RA_FINALIZE(node_);
+    1768             : 
+    1769             :         // Handle conditional/unconditional jump.
+    1770       31106 :         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        1944 :       case CBNode::kNodeFunc: {
+    1826             :         ASMJIT_ASSERT(node_ == func);
+    1827        1944 :         X86RAPass_assignStackArgsRegId(this, func);
+    1828             : 
+    1829             :         FuncDetail& fd = func->getDetail();
+    1830             :         TiedReg* tied;
+    1831             : 
+    1832             :         RA_DECLARE();
+    1833        1944 :         cc()->setCursor(node_);
+    1834             : 
+    1835             :         X86Gp saReg;
+    1836             :         uint32_t argCount = fd.getArgCount();
+    1837             : 
+    1838        1944 :         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        1944 :         if (!saReg.isValid())
+    1901             :           func->getFrameInfo().setStackArgsRegId(Globals::kInvalidRegId);
+    1902             : 
+    1903        1944 :         RA_FINALIZE(node_);
+    1904             :         next = node_->getNext();
+    1905        1944 :         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        1944 :       case CBNode::kNodeFuncExit: {
+    1923             :         CCFuncRet* node = static_cast<CCFuncRet*>(node_);
+    1924        1944 :         ASMJIT_PROPAGATE(addReturningNode(node));
+    1925             : 
+    1926             :         FuncDetail& fd = func->getDetail();
+    1927             :         RA_DECLARE();
+    1928             : 
+    1929        1944 :         if (fd.hasRet()) {
+    1930             :           const FuncDetail::Value& ret = fd.getRet(0);
+    1931             :           uint32_t retKind = X86Reg::kindOf(ret.getRegType());
+    1932             : 
+    1933        5832 :           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        3888 :               RA_MERGE(vreg, tied, 0, 0);
+    1939             : 
+    1940        1944 :               if (retKind == vreg->getKind()) {
+    1941        1944 :                 tied->flags |= TiedReg::kRReg;
+    1942        1944 :                 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        3888 :         RA_FINALIZE(node_);
+    1957             : 
+    1958        1944 :         if (!next->hasPassData())
+    1959        1944 :           ASMJIT_PROPAGATE(addUnreachableNode(next));
+    1960        1944 :         goto _NextGroup;
+    1961             :       }
+    1962             : 
+    1963             :       // ----------------------------------------------------------------------
+    1964             :       // [Func-Call]
+    1965             :       // ----------------------------------------------------------------------
+    1966             : 
+    1967        1636 :       case CBNode::kNodeFuncCall: {
+    1968             :         CCFuncCall* node = static_cast<CCFuncCall*>(node_);
+    1969             :         FuncDetail& fd = node->getDetail();
+    1970             : 
+    1971        1636 :         Operand_* target = node->_opArray;
+    1972        1636 :         Operand_* args = node->_args;
+    1973        1636 :         Operand_* rets = node->_ret;
+    1974             : 
+    1975             :         func->getFrameInfo().enableCalls();
+    1976        1636 :         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        1636 :         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        1636 :           RA_MERGE(vreg, tied, 0, 0);
+    1994             : 
+    1995        1636 :           tied->flags |= TiedReg::kRReg | TiedReg::kRCall;
+    1996        1636 :           if (tied->inRegs == 0)
+    1997        1636 :             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        3486 :         for (i = 0; i < argCount; i++) {
+    2030        1850 :           Operand_* op = &args[i];
+    2031         404 :           if (!op->isVirtReg()) continue;
+    2032             : 
+    2033             :           vreg = cc()->getVirtRegById(op->getId());
+    2034             :           const FuncDetail::Value& arg = fd.getArg(i);
+    2035             : 
+    2036        1446 :           if (arg.byReg()) {
+    2037        2892 :             RA_MERGE(vreg, tied, 0, 0);
+    2038             : 
+    2039             :             uint32_t argClass = X86Reg::kindOf(arg.getRegType());
+    2040             : 
+    2041        1446 :             if (vreg->getKind() == argClass) {
+    2042        1446 :               tied->inRegs |= Utils::mask(arg.getRegId());
+    2043        1446 :               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        4908 :         for (i = 0; i < 2; i++) {
+    2063        3272 :           Operand_* op = &rets[i];
+    2064        1636 :           if (!op->isVirtReg()) continue;
+    2065             : 
+    2066             :           const FuncDetail::Value& ret = fd.getRet(i);
+    2067        1636 :           if (ret.byReg()) {
+    2068             :             uint32_t retKind = X86Reg::kindOf(ret.getRegType());
+    2069             : 
+    2070             :             vreg = cc()->getVirtRegById(op->getId());
+    2071        4908 :             RA_MERGE(vreg, tied, 0, 0);
+    2072             : 
+    2073        1636 :             if (vreg->getKind() == retKind) {
+    2074             :               tied->setOutPhysId(ret.getRegId());
+    2075        1636 :               tied->flags |= TiedReg::kWReg | TiedReg::kWFunc;
+    2076             :             }
+    2077             :             else {
+    2078             :               // TODO: Function-call return value conversion.
+    2079             :             }
+    2080             :           }
+    2081             :         }
+    2082             : 
+    2083             :         // Init clobbered.
+    2084        1636 :         clobberedRegs.set(X86Reg::kKindGp , Utils::bits(_regCount.getGp())  & (fd.getPassedRegs(X86Reg::kKindGp ) | ~fd.getPreservedRegs(X86Reg::kKindGp )));
+    2085        1636 :         clobberedRegs.set(X86Reg::kKindMm , Utils::bits(_regCount.getMm())  & (fd.getPassedRegs(X86Reg::kKindMm ) | ~fd.getPreservedRegs(X86Reg::kKindMm )));
+    2086        1636 :         clobberedRegs.set(X86Reg::kKindK  , Utils::bits(_regCount.getK())   & (fd.getPassedRegs(X86Reg::kKindK  ) | ~fd.getPreservedRegs(X86Reg::kKindK  )));
+    2087        1636 :         clobberedRegs.set(X86Reg::kKindVec, Utils::bits(_regCount.getVec()) & (fd.getPassedRegs(X86Reg::kKindVec) | ~fd.getPreservedRegs(X86Reg::kKindVec)));
+    2088             : 
+    2089        6354 :         RA_FINALIZE(node_);
+    2090             :         break;
+    2091             :       }
+    2092             :     }
+    2093             : 
+    2094             :     node_ = next;
+    2095       34686 :   } while (node_ != stop);
+    2096             : 
+    2097        1944 : _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        1944 :   if (!node_->hasPassData()) {
+    2102             :     CBLabel* fExit = func->getExitNode();
+    2103        1944 :     RA_POPULATE(fExit);
+    2104        1944 :     fExit->setPosition(++position);
+    2105             : 
+    2106        1944 :     RA_POPULATE(node_);
+    2107        1944 :     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        1944 :   ASMJIT_INLINE X86BaseAlloc(X86RAPass* context) {
+    2171        1944 :     _context = context;
+    2172        1944 :     _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       10360 :   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      333328 :   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       26014 :   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       36630 :   _node = node;
+    2262       36630 :   _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       36630 :   _cc->_setCursor(node->getPrev());
+    2268             : 
+    2269             :   // Setup the lists of variables.
+    2270             :   {
+    2271             :     TiedReg* tied = raData->getTiedArray();
+    2272       36630 :     _tiedArray[X86Reg::kKindGp ] = tied;
+    2273       36630 :     _tiedArray[X86Reg::kKindMm ] = tied + raData->getTiedStart(X86Reg::kKindMm );
+    2274       36630 :     _tiedArray[X86Reg::kKindK  ] = tied + raData->getTiedStart(X86Reg::kKindK  );
+    2275       36630 :     _tiedArray[X86Reg::kKindVec] = tied + raData->getTiedStart(X86Reg::kKindVec);
+    2276             :   }
+    2277             : 
+    2278             :   // Setup counters.
+    2279       36630 :   _tiedTotal = raData->tiedTotal;
+    2280       36630 :   _tiedCount = raData->tiedCount;
+    2281             :   _tiedDone.reset();
+    2282             : 
+    2283             :   // Connect VREG->TIED.
+    2284       98004 :   for (uint32_t i = 0; i < _tiedTotal; i++) {
+    2285       61374 :     TiedReg* tied = &_tiedArray[0][i];
+    2286       61374 :     VirtReg* vreg = tied->vreg;
+    2287       61374 :     vreg->_tied = tied;
+    2288             :   }
+    2289             : }
+    2290             : 
+    2291             : ASMJIT_INLINE void X86BaseAlloc::cleanup() {
+    2292             :   // Disconnect VREG->TIED.
+    2293       96060 :   for (uint32_t i = 0; i < _tiedTotal; i++) {
+    2294       61374 :     TiedReg* tied = &_tiedArray[0][i];
+    2295       61374 :     VirtReg* vreg = tied->vreg;
+    2296       61374 :     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       89706 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2315       56656 :     TiedReg* tied = &tiedArray[i];
+    2316       56656 :     if ((tied->flags & checkFlags) == TiedReg::kWReg)
+    2317       22104 :       _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       96060 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2327       61374 :     TiedReg* tied = &tiedArray[i];
+    2328       61374 :     if (tied->flags & TiedReg::kUnuse)
+    2329       21796 :       _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        1944 :   ASMJIT_INLINE X86VarAlloc(X86RAPass* context) : X86BaseAlloc(context) {}
+    2346        1944 :   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       34994 : 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       34994 :   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       33050 :     if (node_->getType() == CBNode::kNodeInst) {
+    2445             :       CBInst* node = static_cast<CBInst*>(node_);
+    2446       31106 :       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       31106 :       ASMJIT_PROPAGATE(X86RAPass_translateOperands(_context, node->getOpArray(), node->getOpCount()));
+    2452             :     }
+    2453        1944 :     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       33050 :     _context->_clobberedRegs.or_(_willAlloc);
+    2505             :   }
+    2506             : 
+    2507             :   // Update clobbered mask.
+    2508       34994 :   _context->_clobberedRegs.or_(raData->clobberedRegs);
+    2509             : 
+    2510             :   // Unuse.
+    2511       34994 :   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       34994 :   _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       46366 :   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       95774 :   for (i = 0; i < tiedCount; i++) {
+    2557       56656 :     TiedReg* tied = &tiedArray[i];
+    2558       56656 :     VirtReg* vreg = tied->vreg;
+    2559             : 
+    2560       56656 :     uint32_t vaFlags = tied->flags;
+    2561             :     uint32_t physId = vreg->getPhysId();
+    2562       56656 :     uint32_t regMask = (physId != Globals::kInvalidRegId) ? Utils::mask(physId) : 0;
+    2563             : 
+    2564       56656 :     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       56656 :       uint32_t mandatoryRegs = tied->inRegs;
+    2573       56656 :       uint32_t allocableRegs = tied->allocableRegs;
+    2574             : 
+    2575       56656 :       if (regMask != 0) {
+    2576             :         // Special path for planning output-only registers.
+    2577       30614 :         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       30614 :           if ((mandatoryRegs | allocableRegs) & regMask) {
+    2601             :             tied->setInPhysId(physId);
+    2602       30280 :             tied->flags |= TiedReg::kRDone;
+    2603             : 
+    2604       30280 :             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       28670 :               tied->inRegs |= regMask;
+    2611       28670 :               willAlloc |= regMask;
+    2612             :             }
+    2613             : 
+    2614             :             addTiedDone(C);
+    2615       30280 :             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       26376 :       willFree |= regMask;
+    2632       26376 :       continue;
+    2633       26376 :     }
+    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       39118 :   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       95774 :   for (i = 0; i < tiedCount; i++) {
+    2655       56656 :     TiedReg* tied = &tiedArray[i];
+    2656       56656 :     VirtReg* vreg = tied->vreg;
+    2657       56656 :     uint32_t vaFlags = tied->flags;
+    2658             : 
+    2659       56656 :     if ((vaFlags & TiedReg::kXReg) != 0) {
+    2660       56656 :       if ((vaFlags & TiedReg::kXReg) == TiedReg::kWReg) {
+    2661       22104 :         if (vaFlags & TiedReg::kWDone)
+    2662           0 :           continue;
+    2663             : 
+    2664             :         // Skip all registers that have assigned outPhysId. Spill if occupied.
+    2665       22104 :         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       34552 :         if (vaFlags & TiedReg::kRDone)
+    2673       30280 :           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       26376 :       uint32_t m = tied->inRegs;
+    2685       26376 :       if (tied->hasOutPhysId())
+    2686           0 :         m |= Utils::mask(tied->outPhysId);
+    2687             : 
+    2688       26376 :       m = tied->allocableRegs & ~(willAlloc ^ m);
+    2689             :       m = guessAlloc<C>(vreg, m);
+    2690             :       ASMJIT_ASSERT(m != 0);
+    2691             : 
+    2692       26376 :       uint32_t candidateRegs = m & ~occupied;
+    2693             :       uint32_t homeMask = vreg->getHomeMask();
+    2694             : 
+    2695             :       uint32_t physId;
+    2696             :       uint32_t regMask;
+    2697             : 
+    2698       26376 :       if (candidateRegs == 0) {
+    2699         138 :         candidateRegs = m & occupied & ~state->_modified.get(C);
+    2700         138 :         if (candidateRegs == 0)
+    2701             :           candidateRegs = m;
+    2702             :       }
+    2703       26376 :       if (candidateRegs & homeMask) candidateRegs &= homeMask;
+    2704             : 
+    2705             :       physId = Utils::findFirstBit(candidateRegs);
+    2706             :       regMask = Utils::mask(physId);
+    2707             : 
+    2708       26376 :       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       26376 :       willAlloc |= regMask;
+    2717       26376 :       willSpill |= regMask & occupied;
+    2718             :       willFree  &=~regMask;
+    2719       26376 :       occupied  |= regMask;
+    2720             : 
+    2721       26376 :       continue;
+    2722       26376 :     }
+    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       33050 :   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       40298 :   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       29526 :   do {
+    2793             :     didWork = false;
+    2794       74516 :     for (i = 0; i < tiedCount; i++) {
+    2795       44990 :       TiedReg* aTied = &tiedArray[i];
+    2796       44990 :       VirtReg* aVReg = aTied->vreg;
+    2797             : 
+    2798       44990 :       if ((aTied->flags & (TiedReg::kRReg | TiedReg::kRDone)) != TiedReg::kRReg)
+    2799       40718 :         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       62068 :   for (i = 0; i < tiedCount; i++) {
+    2853       36814 :     TiedReg* tied = &tiedArray[i];
+    2854       36814 :     VirtReg* vreg = tied->vreg;
+    2855             : 
+    2856       36814 :     if ((tied->flags & (TiedReg::kXReg | TiedReg::kWDone)) != TiedReg::kWReg)
+    2857       14710 :       continue;
+    2858             : 
+    2859       22104 :     uint32_t physId = tied->outPhysId;
+    2860             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+    2861             : 
+    2862       22104 :     if (vreg->getPhysId() != physId) {
+    2863             :       ASMJIT_ASSERT(getState()->getListByKind(C)[physId] == nullptr);
+    2864       22104 :       _context->attach<C>(vreg, physId, false);
+    2865             :     }
+    2866             : 
+    2867       22104 :     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       26042 :   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       26042 :   CBNode* node = _node;
+    2891      118938 :   for (i = 0; i < maxLookAhead; i++) {
+    2892             :     X86RAData* raData = node->getPassData<X86RAData>();
+    2893      118866 :     RABits* liveness = raData ? raData->liveness : static_cast<RABits*>(nullptr);
+    2894             : 
+    2895             :     // If the variable becomes dead it doesn't make sense to continue.
+    2896      118866 :     if (liveness && !liveness->getBit(raId)) break;
+    2897             : 
+    2898             :     // Stop on `CBSentinel` and `CCFuncRet`.
+    2899       99048 :     if (node->hasFlag(CBNode::kFlagIsRet)) break;
+    2900             : 
+    2901             :     // Stop on conditional jump, we don't follow them.
+    2902       99048 :     if (node->hasFlag(CBNode::kFlagIsJcc)) break;
+    2903             : 
+    2904             :     // Advance on non-conditional jump.
+    2905       99048 :     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       99048 :     if (raData) {
+    2916             :       TiedReg* tied = raData->findTiedByKind(C, vreg);
+    2917             :       uint32_t mask;
+    2918             : 
+    2919       99048 :       if (tied) {
+    2920             :         // If the variable is overwritten it doesn't make sense to continue.
+    2921       29868 :         if ((tied->flags & TiedReg::kRAll) == 0)
+    2922             :           break;
+    2923             : 
+    2924       29868 :         mask = tied->allocableRegs;
+    2925       29868 :         if (mask != 0) {
+    2926       29868 :           allocableRegs &= mask;
+    2927       29868 :           if (allocableRegs == 0) break;
+    2928             :           safeRegs = allocableRegs;
+    2929             :         }
+    2930             : 
+    2931       29212 :         mask = tied->inRegs;
+    2932       29212 :         if (mask != 0) {
+    2933        2092 :           allocableRegs &= mask;
+    2934        2092 :           if (allocableRegs == 0) break;
+    2935             :           safeRegs = allocableRegs;
+    2936        2092 :           break;
+    2937             :         }
+    2938             : 
+    2939       27120 :         allocableRegs &= ~(raData->outRegs.get(C) | raData->clobberedRegs.get(C));
+    2940       27120 :         if (allocableRegs == 0) break;
+    2941             :       }
+    2942             :       else {
+    2943       69180 :         allocableRegs &= ~(raData->inRegs.get(C) | raData->outRegs.get(C) | raData->clobberedRegs.get(C));
+    2944       69180 :         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       89706 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2971       56656 :     TiedReg* tied = &tiedArray[i];
+    2972             : 
+    2973       56656 :     if (tied->flags & TiedReg::kWReg) {
+    2974       30864 :       VirtReg* vreg = tied->vreg;
+    2975             : 
+    2976             :       uint32_t physId = vreg->getPhysId();
+    2977             :       uint32_t regMask = Utils::mask(physId);
+    2978             : 
+    2979             :       vreg->setModified(true);
+    2980       30864 :       _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        1944 :   ASMJIT_INLINE X86CallAlloc(X86RAPass* context) : X86BaseAlloc(context) {}
+    2998        1944 :   ASMJIT_INLINE ~X86CallAlloc() {}
+    2999             : 
+    3000             :   // --------------------------------------------------------------------------
+    3001             :   // [Accessors]
+    3002             :   // --------------------------------------------------------------------------
+    3003             : 
+    3004             :   //! Get the node.
+    3005        1636 :   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        1636 : 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        1636 :   ASMJIT_PROPAGATE(X86RAPass_translateOperands(_context, node->getOpArray(), node->getOpCount()));
+    3129             : 
+    3130             :   // To emit instructions after call.
+    3131        1636 :   _cc->_setCursor(node);
+    3132             : 
+    3133             :   // If the callee pops stack it has to be manually adjusted back.
+    3134             :   FuncDetail& fd = node->getDetail();
+    3135        1636 :   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        4908 :   uint32_t clobbered = _raData->clobberedRegs.get(C);
+    3185             : 
+    3186             :   uint32_t willAlloc = _willAlloc.get(C);
+    3187        4908 :   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        9626 :   for (i = 0; i < tiedCount; i++) {
+    3196        4718 :     TiedReg* tied = &tiedArray[i];
+    3197        4718 :     VirtReg* vreg = tied->vreg;
+    3198             : 
+    3199        4718 :     uint32_t vaFlags = tied->flags;
+    3200             :     uint32_t physId = vreg->getPhysId();
+    3201        4718 :     uint32_t regMask = (physId != Globals::kInvalidRegId) ? Utils::mask(physId) : 0;
+    3202             : 
+    3203        4718 :     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        3082 :       uint32_t inRegs = tied->inRegs;
+    3209             : 
+    3210        3082 :       if (inRegs == 0) {
+    3211        1636 :         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        3082 :       if ((regMask & inRegs) != 0 || ((regMask & ~clobbered) != 0 && (vaFlags & TiedReg::kUnuse) == 0)) {
+    3218             :         tied->setInPhysId(physId);
+    3219        2274 :         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        1636 :       if (regMask != 0) {
+    3229           0 :         willFree |= regMask;
+    3230             :       }
+    3231             :       else {
+    3232        1636 :         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        4908 :   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        9626 :   for (i = 0; i < tiedCount; i++) {
+    3247        4718 :     TiedReg* tied = &tiedArray[i];
+    3248        1636 :     VirtReg* vreg = tied->vreg;
+    3249             : 
+    3250        4718 :     uint32_t vaFlags = tied->flags;
+    3251        4718 :     if ((vaFlags & TiedReg::kRDone) != 0 || (vaFlags & TiedReg::kRReg) == 0)
+    3252        3910 :       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        1636 :   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        1636 :   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        1636 :   Operand_* args = node->_args;
+    3417             : 
+    3418        3486 :   for (uint32_t i = 0; i < argCount; i++) {
+    3419        1850 :     Operand_& op = args[i];
+    3420        1850 :     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         404 :     if (arg.byReg()) {
+    3427         404 :       _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        6354 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    3446        4718 :     TiedReg* tied = &tiedArray[i];
+    3447        4718 :     if ((tied->flags & TiedReg::kRReg) == 0) continue;
+    3448             : 
+    3449        3082 :     uint32_t inRegs = tied->inRegs;
+    3450        3082 :     if (!inRegs) continue;
+    3451             : 
+    3452        1446 :     VirtReg* vreg = tied->vreg;
+    3453             :     uint32_t physId = vreg->getPhysId();
+    3454             : 
+    3455             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+    3456             : 
+    3457        1446 :     inRegs &= ~Utils::mask(physId);
+    3458        1446 :     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        4908 :   uint32_t affected = _raData->clobberedRegs.get(C) & state->_occupied.get(C) & state->_modified.get(C);
+    3551             : 
+    3552        6444 :   for (i = 0; affected != 0; i++, affected >>= 1) {
+    3553        4808 :     if (affected & 0x1) {
+    3554        3936 :       VirtReg* vreg = sVars[i];
+    3555             :       ASMJIT_ASSERT(vreg != nullptr);
+    3556             :       ASMJIT_ASSERT(vreg->isModified());
+    3557             : 
+    3558        3936 :       TiedReg* tied = vreg->_tied;
+    3559        3936 :       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        4908 :   uint32_t affected = _raData->clobberedRegs.get(C) & state->_occupied.get(C);
+    3576             : 
+    3577        6870 :   for (i = 0; affected != 0; i++, affected >>= 1) {
+    3578        5234 :     if (affected & 0x1) {
+    3579        4830 :       VirtReg* vreg = sVars[i];
+    3580             :       ASMJIT_ASSERT(vreg != nullptr);
+    3581             : 
+    3582        4830 :       TiedReg* tied = vreg->_tied;
+    3583             :       uint32_t vdState = VirtReg::kStateNone;
+    3584             : 
+    3585        4830 :       if (!vreg->isModified() || (tied && (tied->flags & (TiedReg::kWAll | TiedReg::kUnuse)) != 0))
+    3586             :         vdState = VirtReg::kStateMem;
+    3587        4830 :       _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        1636 :   Operand_* rets = node->_ret;
+    3600             : 
+    3601        4908 :   for (uint32_t i = 0; i < 2; i++) {
+    3602        3272 :     const FuncDetail::Value& ret = fd.getRet(i);
+    3603        3272 :     Operand_* op = &rets[i];
+    3604             : 
+    3605        3272 :     if (!ret.byReg() || !op->isVirtReg())
+    3606        1636 :       continue;
+    3607             : 
+    3608        1636 :     VirtReg* vreg = _cc->getVirtRegById(op->getId());
+    3609             :     uint32_t regId = ret.getRegId();
+    3610             : 
+    3611        1636 :     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        1636 :         if (X86Reg::kindOf(ret.getRegType()) == X86Reg::kKindVec) {
+    3624        1636 :           _context->unuse<X86Reg::kKindVec>(vreg);
+    3625        1636 :           _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       32742 : static Error X86RAPass_translateOperands(X86RAPass* self, Operand_* opArray, uint32_t opCount) {
+    3648             :   X86Compiler* cc = self->cc();
+    3649             : 
+    3650             :   // Translate variables into registers.
+    3651       96710 :   for (uint32_t i = 0; i < opCount; i++) {
+    3652       63968 :     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       50532 :       op->_reg.id = vreg->getPhysId();
+    3658             :     }
+    3659       13436 :     else if (op->isMem()) {
+    3660             :       X86Mem* m = static_cast<X86Mem*>(op);
+    3661             : 
+    3662        6068 :       if (m->hasBaseReg() && cc->isVirtRegValid(m->getBaseId())) {
+    3663             :         VirtReg* vreg = cc->getVirtRegById(m->getBaseId());
+    3664             : 
+    3665        6068 :         if (m->isRegHome()) {
+    3666           0 :           self->getVarCell(vreg);
+    3667             :         }
+    3668             :         else {
+    3669             :           ASMJIT_ASSERT(vreg->getPhysId() != Globals::kInvalidRegId);
+    3670        6068 :           op->_mem.base = vreg->getPhysId();
+    3671             :         }
+    3672             :       }
+    3673             : 
+    3674        6068 :       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       32742 :   return kErrorOk;
+    3682             : }
+    3683             : 
+    3684             : // ============================================================================
+    3685             : // [asmjit::X86RAPass - TranslatePrologEpilog]
+    3686             : // ============================================================================
+    3687             : 
+    3688             : //! \internal
+    3689        1944 : 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        1944 :   ffi.setStackFrameSize(self->_memAllTotal);
+    3702        1944 :   ffi.setStackFrameAlignment(self->_memMaxAlign);
+    3703             : 
+    3704        1944 :   return kErrorOk;
+    3705             : }
+    3706             : 
+    3707             : //! \internal
+    3708        1944 : 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       50006 :     if (node->getType() == CBNode::kNodeInst) {
+    3714             :       CBInst* iNode = static_cast<CBInst*>(node);
+    3715             : 
+    3716       40594 :       if (iNode->hasMemOp()) {
+    3717             :         X86Mem* m = iNode->getMemOp<X86Mem>();
+    3718             : 
+    3719       14496 :         if (m->isArgHome()) {
+    3720             :           m->addOffsetLo32(layout.getStackArgsOffset());
+    3721             :           m->clearArgHome();
+    3722             :         }
+    3723             : 
+    3724       14496 :         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       50006 :   } while (node != stop);
+    3740             : 
+    3741        1944 :   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        1944 : 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        1944 :   if (raData) {
+    3793        1944 :     TiedReg* tiedArray = raData->tiedArray;
+    3794        1944 :     uint32_t tiedTotal = raData->tiedTotal;
+    3795             : 
+    3796        3888 :     for (uint32_t i = 0; i < tiedTotal; i++) {
+    3797        1944 :       TiedReg* tied = &tiedArray[i];
+    3798        1944 :       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        1944 :   while (node) {
+    3814        1944 :     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        1944 :       case CBNode::kNodeLabel:
+    3818        1944 :         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        1944 : 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       36630 :     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        1944 :       if (!jLink) {
+    3884        1944 :         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       36630 :     node_->_flags |= CBNode::kFlagIsTranslated;
+    3910             : 
+    3911       36630 :     if (node_->hasPassData()) {
+    3912       36630 :       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       34686 :           if (!node_->isJcc()) {
+    3945             :             X86RAData* raData = node_->getPassData<X86RAData>();
+    3946             :             RABits* liveness;
+    3947             : 
+    3948       34686 :             if (raData && next && next->hasPassData() && (liveness = next->getPassData<RAData>()->liveness)) {
+    3949       34686 :               TiedReg* tiedArray = raData->tiedArray;
+    3950       34686 :               uint32_t tiedTotal = raData->tiedTotal;
+    3951             : 
+    3952       94116 :               for (uint32_t i = 0; i < tiedTotal; i++) {
+    3953       59430 :                 TiedReg* tied = &tiedArray[i];
+    3954       59430 :                 VirtReg* vreg = tied->vreg;
+    3955             : 
+    3956       59430 :                 if (!liveness->getBit(vreg->_raId) && !vreg->isFixed())
+    3957       21796 :                   tied->flags |= TiedReg::kUnuse;
+    3958             :               }
+    3959             :             }
+    3960             :           }
+    3961             : 
+    3962       34686 :           if (node_->getType() == CBNode::kNodeFuncCall) {
+    3963        1636 :             ASMJIT_PROPAGATE(cAlloc.run(static_cast<CCFuncCall*>(node_)));
+    3964             :             break;
+    3965             :           }
+    3966             :           ASMJIT_FALLTHROUGH;
+    3967             : 
+    3968             :         case CBNode::kNodeHint:
+    3969             :         case CBNode::kNodeFuncExit: {
+    3970       34994 :           ASMJIT_PROPAGATE(vAlloc.run(node_));
+    3971             : 
+    3972             :           // Handle conditional/unconditional jump.
+    3973       34994 :           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       34994 :           else if (node_->isRet()) {
+    4031        1944 :             ASMJIT_PROPAGATE(
+    4032             :               X86RAPass_translateRet(this, static_cast<CCFuncRet*>(node_), func->getExitNode()));
+    4033        1944 :             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       34686 :     if (next == stop)
+    4052           0 :       goto _NextGroup;
+    4053             :     node_ = next;
+    4054             :   }
+    4055             : 
+    4056             : _Done:
+    4057             :   {
+    4058        1944 :     ASMJIT_PROPAGATE(resolveCellOffsets());
+    4059        1944 :     ASMJIT_PROPAGATE(X86RAPass_prepareFuncFrame(this, func));
+    4060             : 
+    4061             :     FuncFrameLayout layout;
+    4062        1944 :     ASMJIT_PROPAGATE(layout.init(func->getDetail(), func->getFrameInfo()));
+    4063             : 
+    4064        1944 :     _varBaseRegId = layout._stackBaseRegId;
+    4065        1944 :     _varBaseOffset = layout._stackBaseOffset;
+    4066             : 
+    4067        1944 :     ASMJIT_PROPAGATE(X86RAPass_patchFuncMem(this, func, stop, layout));
+    4068             : 
+    4069             :     cc->_setCursor(func);
+    4070        1944 :     ASMJIT_PROPAGATE(FuncUtils::emitProlog(this->cc(), layout));
+    4071             : 
+    4072             :     cc->_setCursor(func->getExitNode());
+    4073        1944 :     ASMJIT_PROPAGATE(FuncUtils::emitEpilog(this->cc(), layout));
+    4074             :   }
+    4075             : 
+    4076        1944 :   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.15
+
+ + + 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 0000000000..02baae8af8 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7eae5e1474 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b51c92f2f8 --- /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-06-10 08:19:15Functions: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       81036 :   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       36630 :     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       99048 :     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       61374 :     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      209446 :     for (uint32_t i = 0; i < tiedCount; i++)
+     131      140266 :       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        3272 :       case X86Reg::kKindGp : return _listGp;
+     237        3272 :       case X86Reg::kKindMm : return _listMm;
+     238        8896 :       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      119408 :   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       40518 :     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       23740 :     _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       23740 :   }
+     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       26220 :     _x86State.getListByKind(C)[physId] = nullptr;
+     415             :     _x86State._occupied.andNot(C, regMask);
+     416             :     _x86State._modified.andNot(C, regMask);
+     417             : 
+     418             :     ASMJIT_X86_CHECK_STATE
+     419       26220 :   }
+     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       50366 :     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.15
+
+ + + 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 0000000000..b835cdda9b --- /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-06-10 08:19:15Functions: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_8ZoneHeapE3888
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm3888
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm3888
_ZN4PLMD6asmjit4Zone6_allocEm7780
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE9720
_ZN4PLMD6asmjit4ZoneC2Ejj11664
_ZN4PLMD6asmjit4ZoneD2Ev11664
_ZN4PLMD6asmjit4Zone5resetEb17496
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm18252
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm18252
_ZN4PLMD6asmjit4Zone11allocZeroedEm27628
_ZN4PLMD6asmjit4Zone3dupEPKvmb36630
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm79806
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.func.html b/coverage-libs/asmjit/zone.cpp.func.html new file mode 100644 index 0000000000..319c63cb96 --- /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-06-10 08:19:15Functions:132259.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12ZoneHashBase4_delEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase4_putEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase5resetEPNS0_8ZoneHeapE3888
_ZN4PLMD6asmjit12ZoneHashBase7_rehashEj0
_ZN4PLMD6asmjit13ZoneBitVector4fillEmmb0
_ZN4PLMD6asmjit13ZoneBitVector7_appendEPNS0_8ZoneHeapEb0
_ZN4PLMD6asmjit13ZoneBitVector7_resizeEPNS0_8ZoneHeapEmmb0
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm18252
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm3888
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm18252
_ZN4PLMD6asmjit4Zone11allocZeroedEm27628
_ZN4PLMD6asmjit4Zone3dupEPKvmb36630
_ZN4PLMD6asmjit4Zone5resetEb17496
_ZN4PLMD6asmjit4Zone6_allocEm7780
_ZN4PLMD6asmjit4Zone7sformatEPKcz0
_ZN4PLMD6asmjit4ZoneC2Ejj11664
_ZN4PLMD6asmjit4ZoneD2Ev11664
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm3888
_ZN4PLMD6asmjit8ZoneHeap15_releaseDynamicEPvm0
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE9720
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm79806
_ZN4PLMD6asmjitL24ZoneHash_getClosestPrimeEj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.gcov.html b/coverage-libs/asmjit/zone.cpp.gcov.html new file mode 100644 index 0000000000..b6eb91037f --- /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-06-10 08:19:15Functions: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       11664 :   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       11664 : Zone::Zone(uint32_t blockSize, uint32_t blockAlignment) noexcept
+      64       11664 :   : _ptr(nullptr),
+      65       11664 :     _end(nullptr),
+      66       11664 :     _block(const_cast<Zone::Block*>(&Zone_zeroBlock)),
+      67       11664 :     _blockSize(blockSize),
+      68       11664 :     _blockAlignmentShift(Zone_getAlignmentOffsetFromAlignment(blockAlignment)) {}
+      69             : 
+      70       11664 : Zone::~Zone() noexcept {
+      71       11664 :   reset(true);
+      72       11664 : }
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::Zone - Reset]
+      76             : // ============================================================================
+      77             : 
+      78       17496 : void Zone::reset(bool releaseMemory) noexcept {
+      79       17496 :   Block* cur = _block;
+      80             : 
+      81             :   // Can't be altered.
+      82       17496 :   if (cur == &Zone_zeroBlock)
+      83             :     return;
+      84             : 
+      85       11664 :   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        7776 :     Block* next = cur->next;
+      89             :     do {
+      90        7780 :       Block* prev = cur->prev;
+      91             :       Internal::releaseMemory(cur);
+      92             :       cur = prev;
+      93        7780 :     } while (cur);
+      94             : 
+      95             :     cur = next;
+      96        7776 :     while (cur) {
+      97           0 :       next = cur->next;
+      98             :       Internal::releaseMemory(cur);
+      99             :       cur = next;
+     100             :     }
+     101             : 
+     102        7776 :     _ptr = nullptr;
+     103        7776 :     _end = nullptr;
+     104        7776 :     _block = const_cast<Zone::Block*>(&Zone_zeroBlock);
+     105             :   }
+     106             :   else {
+     107        3888 :     while (cur->prev)
+     108             :       cur = cur->prev;
+     109             : 
+     110        3888 :     _ptr = cur->data;
+     111        3888 :     _end = _ptr + cur->size;
+     112        3888 :     _block = cur;
+     113             :   }
+     114             : }
+     115             : 
+     116             : // ============================================================================
+     117             : // [asmjit::Zone - Alloc]
+     118             : // ============================================================================
+     119             : 
+     120        7780 : void* Zone::_alloc(size_t size) noexcept {
+     121        7780 :   Block* curBlock = _block;
+     122             :   uint8_t* p;
+     123             : 
+     124        7780 :   size_t blockSize = std::max<size_t>(_blockSize, size);
+     125        7780 :   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        7780 :   Block* next = curBlock->next;
+     136        7780 :   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        7780 :   if (ASMJIT_UNLIKELY(blockSize > (~static_cast<size_t>(0) - sizeof(Block) - blockAlignment)))
+     148             :     return nullptr;
+     149             : 
+     150        7780 :   blockSize += blockAlignment;
+     151        7780 :   Block* newBlock = static_cast<Block*>(Internal::allocMemory(sizeof(Block) + blockSize));
+     152             : 
+     153        7780 :   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        7780 :   p = Utils::alignTo(newBlock->data, blockAlignment);
+     160        7780 :   newBlock->prev = nullptr;
+     161        7780 :   newBlock->next = nullptr;
+     162        7780 :   newBlock->size = blockSize;
+     163             : 
+     164        7780 :   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        7780 :   _block = newBlock;
+     178        7780 :   _ptr = p + size;
+     179        7780 :   _end = newBlock->data + blockSize;
+     180             : 
+     181        7780 :   return static_cast<void*>(p);
+     182             : }
+     183             : 
+     184       27628 : void* Zone::allocZeroed(size_t size) noexcept {
+     185             :   void* p = alloc(size);
+     186       27628 :   if (ASMJIT_UNLIKELY(!p)) return p;
+     187       27628 :   return ::memset(p, 0, size);
+     188             : }
+     189             : 
+     190       36630 : void* Zone::dup(const void* data, size_t size, bool nullTerminate) noexcept {
+     191       36630 :   if (ASMJIT_UNLIKELY(!data || !size)) return nullptr;
+     192             : 
+     193             :   ASMJIT_ASSERT(size != IntTraits<size_t>::maxValue());
+     194       36630 :   uint8_t* m = allocT<uint8_t>(size + nullTerminate);
+     195       36630 :   if (ASMJIT_UNLIKELY(!m)) return nullptr;
+     196             : 
+     197             :   ::memcpy(m, data, size);
+     198       36630 :   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        9720 : void ZoneHeap::reset(Zone* zone) noexcept {
+     238             :   // Free dynamic blocks.
+     239        9720 :   DynamicBlock* block = _dynamicBlocks;
+     240        9728 :   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        9720 :   _zone = zone;
+     249        9720 : }
+     250             : 
+     251             : // ============================================================================
+     252             : // [asmjit::ZoneHeap - Alloc / Release]
+     253             : // ============================================================================
+     254             : 
+     255       79806 : 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       79798 :     uint8_t* p = reinterpret_cast<uint8_t*>(_slots[slot]);
+     263       79798 :     size = allocatedSize;
+     264             : 
+     265       79798 :     if (p) {
+     266        1676 :       _slots[slot] = reinterpret_cast<Slot*>(p)->next;
+     267             :       //printf("ALLOCATED %p of size %d (SLOT %d)\n", p, int(size), slot);
+     268        1676 :       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       78122 :     Zone* zone = _zone;
+     275             :     p = Utils::alignTo(zone->getCursor(), kBlockAlignment);
+     276       78122 :     size_t remain = (p <= zone->getEnd()) ? (size_t)(zone->getEnd() - p) : size_t(0);
+     277             : 
+     278       78122 :     if (ASMJIT_LIKELY(remain >= size)) {
+     279       74234 :       zone->setCursor(p + size);
+     280             :       //printf("ALLOCATED %p of size %d (SLOT %d)\n", p, int(size), slot);
+     281       74234 :       return p;
+     282             :     }
+     283             :     else {
+     284             :       // Distribute the remaining memory to suitable slots.
+     285        3888 :       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        3888 :       p = static_cast<uint8_t*>(zone->_alloc(size));
+     301        3888 :       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        3888 : void* ZoneHeap::_allocZeroed(size_t size, size_t& allocatedSize) noexcept {
+     347             :   ASMJIT_ASSERT(isInitialized());
+     348             : 
+     349        3888 :   void* p = _alloc(size, allocatedSize);
+     350        3888 :   if (ASMJIT_UNLIKELY(!p)) return p;
+     351        3888 :   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       18252 : Error ZoneVectorBase::_grow(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     382       18252 :   size_t threshold = Globals::kAllocThreshold / sizeOfT;
+     383       18252 :   size_t capacity = _capacity;
+     384       18252 :   size_t after = _length;
+     385             : 
+     386       18252 :   if (ASMJIT_UNLIKELY(IntTraits<size_t>::maxValue() - n < after))
+     387             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     388             : 
+     389       18252 :   after += n;
+     390       18252 :   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       18252 :   if (capacity < 4)
+     398             :     capacity = 4;
+     399        6588 :   else if (capacity < 8)
+     400             :     capacity = 8;
+     401        3496 :   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       18252 :   while (capacity < after) {
+     409           0 :     if (capacity < threshold)
+     410           0 :       capacity *= 2;
+     411             :     else
+     412           0 :       capacity += threshold;
+     413             :   }
+     414             : 
+     415       18252 :   return _reserve(heap, sizeOfT, capacity);
+     416             : }
+     417             : 
+     418       18252 : Error ZoneVectorBase::_reserve(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     419       18252 :   size_t oldCapacity = _capacity;
+     420       18252 :   if (oldCapacity >= n) return kErrorOk;
+     421             : 
+     422       18252 :   size_t nBytes = n * sizeOfT;
+     423       18252 :   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       18252 :   if (ASMJIT_UNLIKELY(!newData))
+     430             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     431             : 
+     432       18252 :   void* oldData = _data;
+     433       18252 :   if (_length)
+     434        6588 :     ::memcpy(newData, oldData, _length * sizeOfT);
+     435             : 
+     436       18252 :   if (oldData)
+     437        6588 :     heap->release(oldData, oldCapacity * sizeOfT);
+     438             : 
+     439       18252 :   _capacity = allocatedBytes / sizeOfT;
+     440             :   ASMJIT_ASSERT(_capacity >= n);
+     441             : 
+     442       18252 :   _data = newData;
+     443       18252 :   return kErrorOk;
+     444             : }
+     445             : 
+     446        3888 : Error ZoneVectorBase::_resize(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     447        3888 :   size_t length = _length;
+     448        3888 :   if (_capacity < n) {
+     449        1944 :     ASMJIT_PROPAGATE(_grow(heap, sizeOfT, n - length));
+     450             :     ASMJIT_ASSERT(_capacity >= n);
+     451             :   }
+     452             : 
+     453        3888 :   if (length < n)
+     454        3888 :     ::memset(static_cast<uint8_t*>(_data) + length * sizeOfT, 0, (n - length) * sizeOfT);
+     455             : 
+     456        3888 :   _length = n;
+     457        3888 :   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        3888 : void ZoneHashBase::reset(ZoneHeap* heap) noexcept {
+     678        3888 :   ZoneHashNode** oldData = _data;
+     679        3888 :   if (oldData != _embedded)
+     680           0 :     _heap->release(oldData, _bucketsCount * sizeof(ZoneHashNode*));
+     681             : 
+     682        3888 :   _heap = heap;
+     683        3888 :   _size = 0;
+     684        3888 :   _bucketsCount = 1;
+     685        3888 :   _bucketsGrow = 1;
+     686        3888 :   _data = _embedded;
+     687        3888 :   _embedded[0] = nullptr;
+     688        3888 : }
+     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.15
+
+ + + 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 0000000000..44e77f461c --- /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-06-10 08:19:15Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_1944
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_23740
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.func.html b/coverage-libs/asmjit/zone.h.func.html new file mode 100644 index 0000000000..427c2cc6da --- /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-06-10 08:19:15Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_1944
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_23740
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.gcov.html b/coverage-libs/asmjit/zone.h.gcov.html new file mode 100644 index 0000000000..f0bdd2d171 --- /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-06-10 08:19:15Functions: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        7780 :   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       78122 :   ASMJIT_INLINE uint8_t* getCursor() noexcept { return _ptr; }
+     125             :   //! Get the end of the current zone block, only useful if you use `getCursor()`.
+     126       78122 :   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       74234 :     _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      114612 :     uint8_t* ptr = _ptr;
+     174      114612 :     size_t remainingBytes = (size_t)(_end - ptr);
+     175             : 
+     176      114612 :     if (ASMJIT_UNLIKELY(remainingBytes < size))
+     177        3892 :       return _alloc(size);
+     178             : 
+     179      110720 :     _ptr += size;
+     180             :     ASMJIT_ASSERT(_ptr <= _end);
+     181             : 
+     182      110720 :     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       25684 :     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        1944 :   ASMJIT_INLINE ZoneHeap() noexcept {
+     326             :     ::memset(this, 0, sizeof(*this));
+     327             :   }
+     328             :   //! Create a new `ZoneHeap` initialized to use `zone`.
+     329        3888 :   explicit ASMJIT_INLINE ZoneHeap(Zone* zone) noexcept {
+     330             :     ::memset(this, 0, sizeof(*this));
+     331        3888 :     _zone = zone;
+     332             :   }
+     333             :   //! Destroy the `ZoneHeap`.
+     334        3888 :   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        6588 :     if (size > kHiMaxSize)
+     372             :       return false;
+     373             : 
+     374        6588 :     if (size <= kLoMaxSize)
+     375        6580 :       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       79806 :     if (size > kHiMaxSize)
+     386             :       return false;
+     387             : 
+     388       79798 :     if (size <= kLoMaxSize) {
+     389       74994 :       slot = static_cast<uint32_t>((size - 1) / kLoGranularity);
+     390       74994 :       allocatedSize = Utils::alignTo(size, kLoGranularity);
+     391             :     }
+     392             :     else {
+     393        4804 :       slot = static_cast<uint32_t>((size - kLoMaxSize - 1) / kHiGranularity) + kLoCount;
+     394        4804 :       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       57666 :     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       18252 :     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        3888 :     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        6588 :       static_cast<Slot*>(p)->next = static_cast<Slot*>(_slots[slot]);
+     465        6588 :       _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        3888 :     ASMJIT_INLINE Link* getNext() const noexcept { return _next; }
+     499             :     //! Get value.
+     500        1944 :     ASMJIT_INLINE T getValue() const noexcept { return _value; }
+     501             :     //! Set value to `value`.
+     502        3888 :     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        1944 :   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        7776 :   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        1944 :     _first = nullptr;
+     555        1944 :     _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        3888 :     link->_next = nullptr;
+     566        3888 :     if (!_first)
+     567        3888 :       _first = link;
+     568             :     else
+     569           0 :       _last->_next = link;
+     570        3888 :     _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        7776 :     : _data(nullptr),
+     598        7776 :       _length(0),
+     599        7776 :       _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       73224 :   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        5832 :     _data = nullptr;
+     622        5832 :     _length = 0;
+     623        5832 :     _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       11664 :   ASMJIT_INLINE T* getData() noexcept { return static_cast<T*>(_data); }
+     686             :   //! \overload
+     687      136066 :   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       25684 :   Error append(ZoneHeap* heap, const T& item) noexcept {
+     722       25684 :     if (ASMJIT_UNLIKELY(_length == _capacity))
+     723        5238 :       ASMJIT_PROPAGATE(grow(heap, 1));
+     724             : 
+     725       25684 :     ::memcpy(static_cast<T*>(_data) + _length, &item, sizeof(T));
+     726             : 
+     727       25684 :     _length++;
+     728       25684 :     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       29572 :     ::memcpy(static_cast<T*>(_data) + _length, &item, sizeof(T));
+     767       27628 :     _length++;
+     768        1944 :   }
+     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        7776 :     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      132178 :     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       16308 :   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        3888 :   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       31516 :     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        1944 :   ASMJIT_INLINE ZoneHashBase(ZoneHeap* heap) noexcept {
+    1068        1944 :     _heap = heap;
+    1069        1944 :     _size = 0;
+    1070        1944 :     _bucketsCount = 1;
+    1071        1944 :     _bucketsGrow = 1;
+    1072        1944 :     _data = _embedded;
+    1073        1944 :     _embedded[0] = nullptr;
+    1074             :   }
+    1075        1944 :   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        1944 :   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.15
+
+ + + 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 0000000000..86eb7cd0f1 --- /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-06-10 08:19:15Functions: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_1113895
_ZN4PLMD4blas6daxpy_EPiPdS2_S1_S2_S1_1114408
_ZN4PLMD4blas6dsymv_EPKcPiPdS4_S3_S4_S3_S4_S4_S3_1114408
_ZN4PLMD4blas5ddot_EPiPdS1_S2_S1_1114409
_ZN4PLMD4blas5dger_EPiS1_PdS2_S1_S2_S1_S2_S1_1119685
_ZN4PLMD4blas6dnrm2_EPiPdS1_1125776
_ZN4PLMD4blas6dgemv_EPKcPiS3_PdS4_S3_S4_S3_S4_S4_S3_1131535
_ZN4PLMD4blas6dscal_EPiPdS2_S1_1728052
_ZN4PLMD4blas6dcopy_EPiPdS1_S2_S1_4000772
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/blas/blas.cpp.func.html b/coverage-libs/blas/blas.cpp.func.html new file mode 100644 index 0000000000..c242275099 --- /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-06-10 08:19:15Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4blas5ddot_EPiPdS1_S2_S1_1114409
_ZN4PLMD4blas5dger_EPiS1_PdS2_S1_S2_S1_S2_S1_1119685
_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_1114408
_ZN4PLMD4blas6dcopy_EPiPdS1_S2_S1_4000772
_ZN4PLMD4blas6dgemm_EPKcS2_PiS3_S3_PdS4_S3_S4_S3_S4_S4_S3_520
_ZN4PLMD4blas6dgemv_EPKcPiS3_PdS4_S3_S4_S3_S4_S4_S3_1131535
_ZN4PLMD4blas6dnrm2_EPiPdS1_1125776
_ZN4PLMD4blas6dscal_EPiPdS2_S1_1728052
_ZN4PLMD4blas6dswap_EPiPdS1_S2_S1_5884
_ZN4PLMD4blas6dsymv_EPKcPiPdS4_S3_S4_S3_S4_S4_S3_1114408
_ZN4PLMD4blas6dsyr2_EPKcPiPdS4_S3_S4_S3_S4_S3_1113895
_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.15
+
+ + + diff --git a/coverage-libs/blas/blas.cpp.gcov.html b/coverage-libs/blas/blas.cpp.gcov.html new file mode 100644 index 0000000000..98dea09f53 --- /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-06-10 08:19:15Functions: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     1114408 : 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     1114408 :   int n=*n_arg;
+      97     1114408 :   double da=*da_arg;
+      98     1114408 :   int incx = *incx_arg;
+      99     1114408 :   int incy = *incy_arg;
+     100             : 
+     101     1114408 :   if (n<=0)
+     102             :     return;
+     103             : 
+     104     1114408 :   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     1162445 :     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     3900117 :     for(;i<n;i++)
+     129     2785709 :       dy[i]   += da*dx[i];
+     130             :   }
+     131             : }
+     132             : }
+     133             : }
+     134             : #include "blas.h"
+     135             : 
+     136             : namespace PLMD{
+     137             : namespace blas{
+     138             : void
+     139     4000772 : 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     4000772 :     int n= *n__;
+     148     4000772 :     int incx = *incx__;
+     149     4000772 :     int incy = *incy__;
+     150             :     
+     151             : 
+     152     4000772 :     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     4101553 :         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    16426615 :         for(;i<n;i++)
+     181    12431975 :             dy[i] = dx[i];
+     182             :     }
+     183             : }
+     184             : }
+     185             : }
+     186             : #include "blas.h"
+     187             : 
+     188             : namespace PLMD{
+     189             : namespace blas{
+     190             : double
+     191     1114409 : 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     1114409 :     int n=*n_arg;
+     199     1114409 :     int incx = *incx_arg;
+     200     1114409 :     int incy = *incy_arg;
+     201             :     double t1;
+     202             :     
+     203     1114409 :     if(n<=0)
+     204             :         return 0.0;
+     205             :     
+     206             :     t1 = 0.0;
+     207             :     
+     208     1114409 :     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     1114409 :         m = n%5;
+     224             :         
+     225     3899271 :         for(i=0;i<m;i++)
+     226     2784862 :             t1 += dx[i] * dy[i];
+     227             :         
+     228             :         /* unroll */
+     229     1153009 :         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      714726 :             temp = alpha * b[ l*(ldb) + j ];
+     349   208048410 :             for(i=0;i<m;i++)
+     350   207333684 :               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     1131535 : 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     1131535 :   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     1131535 :   int m = *m__;
+     401     1131535 :   int n = *n__;
+     402     1131535 :   double alpha = *alpha__;
+     403     1131535 :   double beta = *beta__;
+     404     1131535 :   int incx = *incx__;
+     405     1131535 :   int incy = *incy__;
+     406     1131535 :   int lda = *lda__;
+     407             :   
+     408     1131535 :   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     1131343 :   if(ch=='N') {
+     412             :     lenx = n;
+     413             :     leny = m;
+     414             :   } else {
+     415             :     lenx = m;
+     416             :     leny = n;
+     417             :   }
+     418             :   
+     419     1131343 :    if(incx>0)
+     420             :     kx = 1;
+     421             :   else
+     422           0 :     kx = 1 - (lenx -1)*(incx);
+     423             : 
+     424     1131343 :   if(incy>0)
+     425             :     ky = 1;
+     426             :   else
+     427           0 :     ky = 1 - (leny -1)*(incy);
+     428             :  
+     429     1131343 :   if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     430     1126310 :     if(incy==1) {
+     431     1126310 :       if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+     432     2736412 :         for(i=0;i<leny;i++)
+     433     1610102 :           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     1131343 :   if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN)
+     450             :     return;
+     451             :   
+     452     1131343 :   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     1122018 :     if(incx==1) {
+     475     2638116 :       for(j=1;j<=n;j++,jy+=incy) {
+     476             :         temp = 0.0;
+     477    60769798 :         for(i=1;i<=m;i++)
+     478    59252944 :           temp += a[(j-1)*(lda)+(i-1)] * x[i-1];
+     479     1516854 :         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     1119685 : 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     1119685 :     int m = *m__;
+     521     1119685 :     int n = *n__;
+     522     1119685 :     int incx = *incx__;
+     523     1119685 :     int incy = *incy__;
+     524     1119685 :     int lda = *lda__;
+     525     1119685 :     double alpha = *alpha__;
+     526             :     
+     527     1119685 :     if(m<=0 || n<=0 || std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN)
+     528             :         return;
+     529             :     
+     530     1119685 :     if(incy>0)
+     531             :         jy = 0;
+     532             :     else
+     533           0 :         jy = incy * (1 - n);
+     534             :     
+     535     1119685 :     if(incx==1) {
+     536     2387900 :         for(j=0;j<n;j++,jy+=incy)
+     537     1268215 :             if(std::abs(y[jy])>PLUMED_GMX_DOUBLE_MIN) {
+     538     1268207 :                 temp = alpha * y[jy];
+     539     6935852 :                 for(i=0;i<m;i++)
+     540     5667645 :                     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     1125776 : 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     1125776 :     int n = *n__;
+     578     1125776 :     int incx = *incx__;
+     579             :     
+     580     1125776 :     if(n<1 || incx<1)
+     581             :         return 0;
+     582     1125776 :     else if (n==1) {
+     583      556841 :         t = x[0];
+     584      556841 :         if(t>=0)
+     585             :             return t;
+     586             :         else 
+     587      417153 :             return -t;
+     588             :     }
+     589             :     
+     590             :     scale = 0.0;
+     591             :     ssq   = 1.0;
+     592             :     
+     593      568935 :     max_ix = 1+(n-1)*(incx);
+     594     3017084 :     for(ix=1;ix<=max_ix;ix+=incx) {
+     595     2448149 :         t = x[ix-1];
+     596     2448149 :         if(std::abs(t)>PLUMED_GMX_DOUBLE_MIN) {
+     597     2447160 :             absxi = (t>=0) ? t : (-t);
+     598     2447160 :             if(scale<absxi) {
+     599      823428 :                 t = scale/absxi;
+     600      823428 :                 t = t*t;
+     601      823428 :                 ssq = ssq*t + 1.0;
+     602             :                 scale = absxi;
+     603             :             } else {
+     604     1623732 :                 t = absxi/scale;
+     605     1623732 :                 ssq += t*t;
+     606             :             }
+     607             :         }
+     608             :     }
+     609      568935 :     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     1728052 : PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(int  *    n__,
+     674             :                       double *   fact__,
+     675             :                       double *   dx,
+     676             :                       int    *   incx__)
+     677             : {
+     678             :     int nincx,i;
+     679             : 
+     680     1728052 :     int n = *n__;
+     681     1728052 :     double fact = *fact__;
+     682     1728052 :     int incx = *incx__;
+     683             :     
+     684     1728052 :     if(n<=0 || incx<=0)
+     685             :         return;
+     686             :     
+     687     1727995 :     if(incx==1) {
+     688             :         /* Unrool factor 5 */
+     689     1912098 :         for(i=0;i<(n-5);i+=5) {
+     690      186986 :             dx[i]   *= fact;
+     691      186986 :             dx[i+1] *= fact;
+     692      186986 :             dx[i+2] *= fact;
+     693      186986 :             dx[i+3] *= fact;
+     694      186986 :             dx[i+4] *= fact;
+     695             :         }    
+     696             :         /* continue with current value of i */
+     697     5781782 :         for(;i<n;i++)
+     698     4056670 :             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     1114408 : 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     1114408 :     const char ch=std::toupper(*uplo);
+     793             :     int kx,ky,i,j,ix,iy,jx,jy;
+     794             :     double temp1,temp2;
+     795             :     
+     796     1114408 :     int n = *n__;
+     797     1114408 :     int lda = *lda__;
+     798     1114408 :     int incx = *incx__;
+     799     1114408 :     int incy = *incy__;
+     800     1114408 :     double alpha = *alpha__;
+     801     1114408 :     double beta  = *beta__;
+     802             :     
+     803     1114408 :     if(n<=0 || incx==0 || incy==0)
+     804             :         return;
+     805             :     
+     806     1114408 :     if(incx>0)
+     807             :         kx = 1;
+     808             :     else
+     809           0 :         kx = 1 - (n -1)*(incx);
+     810             :     
+     811     1114408 :     if(incy>0)
+     812             :         ky = 1;
+     813             :     else
+     814           0 :         ky = 1 - (n -1)*(incy);
+     815             :     
+     816     1114408 :     if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     817     1114408 :         if(incy==1) {
+     818     1114408 :             if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) 
+     819     4092265 :                 for(i=1;i<=n;i++)
+     820     2977857 :                     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     1114408 :         if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN) 
+     841             :             return;
+     842             :         
+     843     1114408 :         if(ch=='U') {
+     844     1114408 :             if(incx==1 && incy==1) {
+     845     4092265 :                 for(j=1;j<=n;j++) {
+     846     2977857 :                     temp1 = alpha * x[j-1];
+     847             :                     temp2 = 0.0;
+     848    29707007 :                     for(i=1;i<j;i++) {
+     849    26729150 :                         y[i-1] += temp1*a[(j-1)*(lda)+(i-1)];
+     850    26729150 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[i-1];
+     851             :                     }
+     852     2977857 :                     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     1113895 : 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     1113895 :     const char ch=std::toupper(*uplo);
+     936             :     
+     937     1113895 :     int n = *n__;
+     938     1113895 :     int lda = *lda__;
+     939     1113895 :     int incx = *incx__;
+     940     1113895 :     int incy = *incy__;
+     941     1113895 :     float alpha = *alpha__;
+     942             :     
+     943             :     
+     944     1113895 :     if(n<=0 || std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN || incx==0 || incy==0 ||
+     945     1113895 :        (ch != 'U' && ch != 'L'))
+     946             :         return;
+     947             :     
+     948             :     jx = jy = kx = ky = 0;
+     949             :     
+     950             :     /* init start points for non-unit increments */
+     951     1113895 :     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     1113895 :     if(ch == 'U') {
+     966             :         /* Data in upper part of A */
+     967     1113895 :         if(incx==1 && incy==1) {
+     968             :             /* Unit increments for both x and y */
+     969     3949813 :             for(j=1;j<=n;j++) {
+     970     2835918 :                 if( std::abs(x[j-1])>PLUMED_GMX_DOUBLE_MIN  || std::abs(y[j-1])>PLUMED_GMX_DOUBLE_MIN ) {
+     971     2835918 :                     temp1 = alpha * y[j-1];
+     972     2835918 :                     temp2 = alpha * x[j-1];
+     973     9661631 :                     for(i=1;i<=j;i++)
+     974     6825713 :                         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.15
+
+ + + diff --git a/coverage-libs/blas/index-sort-f.html b/coverage-libs/blas/index-sort-f.html new file mode 100644 index 0000000000..323ad21cba --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/blas/index-sort-l.html b/coverage-libs/blas/index-sort-l.html new file mode 100644 index 0000000000..37a7cae7fc --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/blas/index.html b/coverage-libs/blas/index.html new file mode 100644 index 0000000000..71c9b85f1e --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..bfd0a83e10 --- /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: black; + 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 0000000000..6aec57feda --- /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:94962901332.7 %
Date:2024-06-10 08:19:15Functions: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.8%40.8%
+
40.8 %856 / 209745.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.1%89.1%
+
89.1 %1599 / 179592.3 %395 / 428
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/index-sort-l.html b/coverage-libs/index-sort-l.html new file mode 100644 index 0000000000..fc2e96a436 --- /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:94962901332.7 %
Date:2024-06-10 08:19:15Functions: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.8%40.8%
+
40.8 %856 / 209745.2 %56 / 124
xdrfile +
48.3%48.3%
+
48.3 %563 / 116646.2 %43 / 93
lepton +
89.1%89.1%
+
89.1 %1599 / 179592.3 %395 / 428
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/index.html b/coverage-libs/index.html new file mode 100644 index 0000000000..c186db057a --- /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:94962901332.7 %
Date:2024-06-10 08:19:15Functions: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.1%89.1%
+
89.1 %1599 / 179592.3 %395 / 428
molfile +
40.8%40.8%
+
40.8 %856 / 209745.2 %56 / 124
xdrfile +
48.3%48.3%
+
48.3 %563 / 116646.2 %43 / 93
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lapack/index-sort-f.html b/coverage-libs/lapack/index-sort-f.html new file mode 100644 index 0000000000..bd41a14a98 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/lapack/index-sort-l.html b/coverage-libs/lapack/index-sort-l.html new file mode 100644 index 0000000000..6ec840c3be --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/lapack/index.html b/coverage-libs/lapack/index.html new file mode 100644 index 0000000000..75cf216212 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..ce4659015c --- /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-06-10 08:19:15Functions: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
_ZN4PLMD6lapack7dlabrd_EPiS1_S1_PdS1_S2_S2_S2_S2_S2_S1_S2_S1_12
_ZN4PLMD6lapack8dlasrt2_EPKcPiPdS3_S3_12
_ZN4PLMD6lapack8ilasrt2_EPKcPiS3_S3_S3_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_557325
_ZN4PLMD6lapack7dorm2l_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_569952
_ZN4PLMD6lapack7dormql_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_569964
_ZN4PLMD6lapack7dormtr_EPKcS2_S2_PiS3_PdS3_S4_S4_S3_S4_S3_S3_569964
_ZN4PLMD6lapack8dlarrvx_EPiPdS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_569964
_ZN4PLMD6lapack7dlansy_EPKcS2_PiPdS3_S4_570008
_ZN4PLMD6lapack7dstegr_EPKcS2_PiPdS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_570008
_ZN4PLMD6lapack7dsytd2_EPKcPiPdS3_S4_S4_S4_S3_570008
_ZN4PLMD6lapack7dsytrd_EPKcPiPdS3_S4_S4_S4_S4_S3_S3_570008
_ZN4PLMD6lapack8dlarrex_EPKcPiPdS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_570008
_ZN4PLMD6lapack7dlasq2_EPiPdS1_570010
_ZN4PLMD6lapack7dlanst_EPKcPiPdS4_570037
_ZN4PLMD6lapack8dlarrbx_EPiPdS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_570080
_ZN4PLMD6lapack7dlaset_EPKcPiS3_PdS4_S4_S3_570476
_ZN4PLMD6lapack7dsyevr_EPKcS2_S2_PiPdS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_584795
_ZN4PLMD6lapack8dlar1vx_EPiS1_S1_PdS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S2_608131
_ZN4PLMD6lapack7dlapy2_EPdS1_1119236
_ZN4PLMD6lapack7dlarfg_EPiPdS2_S1_S2_1689415
_ZN4PLMD6lapack6dlarf_EPKcPiS3_PdS3_S4_S4_S3_S4_1689941
_ZN4PLMD6lapack7dlasq4_EPiS1_PdS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_12568618
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_12568622
_ZN4PLMD6lapack7dlasq3_EPiS1_PdS1_S2_S2_S2_S2_S1_S1_S1_S1_13125402
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.func.html b/coverage-libs/lapack/lapack.cpp.func.html new file mode 100644 index 0000000000..a1fec2cdea --- /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-06-10 08:19:15Functions: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_1689941
_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_570037
_ZN4PLMD6lapack7dlansy_EPKcS2_PiPdS3_S4_570008
_ZN4PLMD6lapack7dlapy2_EPdS1_1119236
_ZN4PLMD6lapack7dlarfb_EPKcS2_S2_S2_PiS3_S3_PdS3_S4_S3_S4_S3_S4_S3_147
_ZN4PLMD6lapack7dlarfg_EPiPdS2_S1_S2_1689415
_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_570476
_ZN4PLMD6lapack7dlasq1_EPiPdS2_S2_S1_0
_ZN4PLMD6lapack7dlasq2_EPiPdS1_570010
_ZN4PLMD6lapack7dlasq3_EPiS1_PdS1_S2_S2_S2_S2_S1_S1_S1_S1_13125402
_ZN4PLMD6lapack7dlasq4_EPiS1_PdS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_12568618
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_12568622
_ZN4PLMD6lapack7dlasq6_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlasrt_EPKcPiPdS3_557325
_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_569952
_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_569964
_ZN4PLMD6lapack7dormqr_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_96
_ZN4PLMD6lapack7dormtr_EPKcS2_S2_PiS3_PdS3_S4_S4_S3_S4_S3_S3_569964
_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_570008
_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_584795
_ZN4PLMD6lapack7dsytd2_EPKcPiPdS3_S4_S4_S4_S3_570008
_ZN4PLMD6lapack7dsytrd_EPKcPiPdS3_S4_S4_S4_S4_S3_S3_570008
_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_570080
_ZN4PLMD6lapack8dlarrex_EPKcPiPdS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_570008
_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_569964
_ZN4PLMD6lapack8dlasrt2_EPKcPiPdS3_S3_12
_ZN4PLMD6lapack8ilasrt2_EPKcPiS3_S3_S3_12
_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.15
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.gcov.html b/coverage-libs/lapack/lapack.cpp.gcov.html new file mode 100644 index 0000000000..1b2a7c175b --- /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-06-10 08:19:15Functions: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      570037 : PLUMED_BLAS_F77_FUNC(dlanst,DLANST)(const char *norm,
+    3626             :         int *n,
+    3627             :         double *d,
+    3628             :         double *e)
+    3629             : {
+    3630      570037 :   const char ch=std::toupper(*norm);
+    3631             :   double dtemp,max,val,scale,sum;
+    3632             :   int i,j;
+    3633             : 
+    3634             : 
+    3635      570037 :   if(*n<=0)
+    3636             :     return 0.0;
+    3637             :   
+    3638      570037 :   switch(ch) {
+    3639      570037 :   case 'M':
+    3640      570037 :     max = std::abs(d[*n-1]);
+    3641     2255853 :       for(i=0;i<(*n-1);i++) {
+    3642     1685816 :         dtemp = std::abs(d[i]);
+    3643     1685816 :         if(dtemp>max)
+    3644             :           max = dtemp;
+    3645     1685816 :         dtemp = std::abs(e[i]);
+    3646     1685816 :         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      570008 : 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      570008 :     int c__1 = 1;
+    3711             : 
+    3712             :     /* Local variables */
+    3713             :     int i__, j;
+    3714             :     double sum, absa, scale;
+    3715             :     double value =0.0;
+    3716             : 
+    3717      570008 :     a_dim1 = *lda;
+    3718      570008 :     a_offset = 1 + a_dim1;
+    3719      570008 :     a -= a_offset;
+    3720      570008 :     --work;
+    3721             : 
+    3722      570008 :     if (*n == 0) {
+    3723             :         value = 0.;
+    3724      570008 :     } else if (*norm=='M' || *norm=='m') {
+    3725             : 
+    3726             :         value = 0.;
+    3727      570008 :         if (*uplo=='U' || *uplo=='u') {
+    3728      570008 :             i__1 = *n;
+    3729     2824437 :             for (j = 1; j <= i__1; ++j) {
+    3730             :                 i__2 = j;
+    3731     8056735 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+    3732             :                   d__2 = value;
+    3733     5802306 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+    3734     5802306 :                   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      570008 :     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     1119236 : PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(double * x, double * y)
+    3827             : {
+    3828             :   double xabs,yabs;
+    3829             :   double w,z;
+    3830             : 
+    3831     1119236 :   xabs = std::abs(*x);
+    3832     1119236 :   yabs = std::abs(*y);
+    3833             :   
+    3834     1119236 :   if(xabs>yabs) {
+    3835             :     w = xabs;
+    3836             :     z = yabs;
+    3837             :   } else {
+    3838             :     w = yabs;
+    3839             :     z = xabs;
+    3840             :   }
+    3841             : 
+    3842     1119236 :   if( std::abs(z)<PLUMED_GMX_DOUBLE_MIN) 
+    3843             :     return w;
+    3844             :   else {
+    3845     1119236 :     z = z/w;
+    3846     1119236 :     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      606858 :         r1 = *b1;
+    3907      606858 :         r2 = *bn;
+    3908             :         i__1 = *bn;
+    3909     1399077 :         for (i__ = *b1; i__ <= i__1; ++i__) {
+    3910     1399077 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3911             :                 r1 = i__;
+    3912      606858 :                 goto L20;
+    3913             :             }
+    3914             :         }
+    3915           0 :         goto L40;
+    3916             : L20:
+    3917             :         i__1 = *b1;
+    3918     1557129 :         for (i__ = *bn; i__ >= i__1; --i__) {
+    3919     1557129 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3920             :                 r2 = i__;
+    3921      606858 :                 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     1842425 :     for (i__ = *b1; i__ <= i__1; ++i__) {
+    3943     1234294 :         dplus = d__[i__] + s;
+    3944     1234294 :         work[i__] = ld[i__] / dplus;
+    3945     1234294 :         work[inds + i__] = s * work[i__] * l[i__];
+    3946     1234294 :         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     2110704 :     for (i__ = *bn - 1; i__ >= i__1; --i__) {
+    3976     1502573 :         dminus = lld[i__] + work[indp + i__];
+    3977     1502573 :         tmp = d__[i__] / dminus;
+    3978     1502573 :         work[indumn + i__] = l[i__] * tmp;
+    3979     1502573 :         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      956138 :     for (i__ = r1; i__ <= i__1; ++i__) {
+    4012      348007 :         tmp = work[inds + i__] + work[indp + i__];
+    4013      348007 :         if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    4014       23351 :             tmp = eps * work[inds + i__];
+    4015             :         }
+    4016      348007 :         if (std::abs(tmp) < std::abs(*mingma)) {
+    4017       50692 :             *mingma = tmp;
+    4018       50692 :             *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     1148720 :         if (from >= *b1) {
+    4032             :             i__1 = to;
+    4033     1355224 :             for (i__ = from; i__ >= i__1; --i__) {
+    4034      813427 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+    4035      813427 :                 *ztz += z__[i__] * z__[i__];
+    4036             :             }
+    4037      541797 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to + 1]) <= eps) {
+    4038        1208 :                 isuppz[1] = to + 2;
+    4039             :             } else {
+    4040      540589 :                 from = to - 1;
+    4041      540589 :                 i__1 = to - 32;
+    4042      540589 :                 to = (i__1>*b1) ? i__1 : *b1;
+    4043      540589 :                 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     2016487 :             for (i__ = from; i__ <= i__1; ++i__) {
+    4053     1432272 :                 z__[i__] = -(work[indumn + i__ - 1] * z__[i__ - 1]);
+    4054     1432272 :                 *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     1689941 : 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     1689941 :   const char ch=std::toupper(*side);
+    4126     1689941 :   double one = 1.0;
+    4127     1689941 :   double zero = 0.0;
+    4128     1689941 :   double minustau = -(*tau);
+    4129     1689941 :   int i1 = 1;
+    4130             : 
+    4131             : 
+    4132     1689941 :   if(ch=='L') {
+    4133     1686360 :     if(std::abs(*tau)>PLUMED_GMX_DOUBLE_MIN) {
+    4134     1116226 :       PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("T",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+    4135     1116226 :       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     1689941 :   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     1689415 : 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     1689415 :   if(*n<=1) {
+    4573      570200 :     *tau = 0;
+    4574      570200 :     return;
+    4575             :   }
+    4576             : 
+    4577     1119215 :   ti1 = *n-1;
+    4578             : 
+    4579     1119215 :   xnorm = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(&ti1,x,incx);
+    4580             : 
+    4581     1119215 :   if(std::abs(xnorm)<PLUMED_GMX_DOUBLE_MIN) {
+    4582           6 :     *tau = 0.0;
+    4583             :   } else {
+    4584             : 
+    4585     1119209 :     t = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(alpha,&xnorm);
+    4586             : 
+    4587     1119209 :     if(*alpha<0)
+    4588             :       beta = t;
+    4589             :     else
+    4590      453446 :       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     1119209 :     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     1119209 :       *tau = (beta-*alpha)/beta;
+    4631     1119209 :       ti1= *n-1;
+    4632     1119209 :       t = 1.0/(*alpha-beta);
+    4633     1119209 :       PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&ti1,&t,x,incx);
+    4634     1119209 :       *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      570080 : 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      570080 :     --iwork;
+    4881      570080 :     --work;
+    4882      570080 :     --werr;
+    4883      570080 :     --wgap;
+    4884      570080 :     --w;
+    4885      570080 :     --lld;
+    4886             :     --ld;
+    4887             :     --l;
+    4888      570080 :     --d__;
+    4889             : 
+    4890      570080 :     *info = 0;
+    4891      570080 :     i__1 = *n << 1;
+    4892     5134148 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    4893     4564068 :         iwork[i__] = 0;
+    4894             :     }
+    4895      570080 :     i1 = *ifirst;
+    4896             :     i2 = *ifirst;
+    4897             :     prev = 0;
+    4898      570080 :     i__1 = *ilast;
+    4899     1141026 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+    4900      570946 :         k = i__ << 1;
+    4901      570946 :         iwork[k - 1] = 1;
+    4902             :         i2 = i__;
+    4903             :     }
+    4904             : 
+    4905             :     i__ = i1;
+    4906             :     nint = 0;
+    4907     1141026 : L30:
+    4908     1141026 :     if (i__ <= i2) {
+    4909      570946 :         ii = i__ - *offset;
+    4910      570946 :         if (iwork[(i__ << 1) - 1] == 1) {
+    4911             :             fac = 1.;
+    4912      570946 :             left = w[ii] - werr[ii];
+    4913             : 
+    4914             : 
+    4915      571036 : L40:
+    4916      571036 :             if (i__ > i1 && left <= right) {
+    4917             :                 left = right;
+    4918           0 :                 cnt = i__ - 1;
+    4919             :             } else {
+    4920      571036 :                 s = -left;
+    4921             :                 cnt = 0;
+    4922      571036 :                 i__1 = *n - 1;
+    4923     2677326 :                 for (j = 1; j <= i__1; ++j) {
+    4924     2106290 :                     dplus = d__[j] + s;
+    4925     2106290 :                     s = s * lld[j] / dplus - left;
+    4926     2106290 :                     if (dplus < 0.) {
+    4927      209478 :                         ++cnt;
+    4928             :                     }
+    4929             :                 }
+    4930      571036 :                 dplus = d__[*n] + s;
+    4931      571036 :                 if (dplus < 0.) {
+    4932          90 :                     ++cnt;
+    4933             :                 }
+    4934      571036 :         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      571036 :                 if (cnt > i__ - 1) {
+    4957          90 :                     left -= werr[ii] * fac;
+    4958          90 :                     fac *= 2.;
+    4959          90 :                     goto L40;
+    4960             :                 }
+    4961             :             }
+    4962      570946 :             nleft = cnt + 1;
+    4963             :             i1 = (i1<nleft) ? i1 : nleft;
+    4964             :             fac = 1.;
+    4965      570946 :             right = w[ii] + werr[ii];
+    4966      570962 : L60:
+    4967      570962 :             s = -right;
+    4968             :             cnt = 0;
+    4969      570962 :             i__1 = *n - 1;
+    4970     2654326 :             for (j = 1; j <= i__1; ++j) {
+    4971     2083364 :                 dplus = d__[j] + s;
+    4972     2083364 :                 s = s * lld[j] / dplus - right;
+    4973     2083364 :                 if (dplus < 0.) {
+    4974     1882759 :                     ++cnt;
+    4975             :                 }
+    4976             :             }
+    4977      570962 :             dplus = d__[*n] + s;
+    4978      570962 :             if (dplus < 0.) {
+    4979      570942 :                 ++cnt;
+    4980             :             }
+    4981      570962 :             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      570962 :             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      570946 :             ++nint;
+    5010      570946 :             k = nleft << 1;
+    5011      570946 :             work[k - 1] = left;
+    5012      570946 :             work[k] = right;
+    5013      570946 :             i__ = cnt + 1;
+    5014      570946 :             iwork[k - 1] = i__;
+    5015      570946 :             iwork[k] = cnt;
+    5016      570946 :             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      570946 :         goto L30;
+    5028             :     }
+    5029      570080 :     if (i__ <= *n && iwork[(i__ << 1) - 1] != -1) {
+    5030      490521 :         work[(i__ << 1) - 1] = work[prev * 2];
+    5031             :     }
+    5032             : 
+    5033       79559 : L80:
+    5034    29310201 :     prev = i1 - 1;
+    5035             :     olnint = nint;
+    5036             :     i__ = i1;
+    5037             :     i__1 = olnint;
+    5038    58621950 :     for (p = 1; p <= i__1; ++p) {
+    5039    29311749 :         k = i__ << 1;
+    5040    29311749 :         left = work[k - 1];
+    5041    29311749 :         right = work[k];
+    5042    29311749 :         next = iwork[k - 1];
+    5043    29311749 :         nright = iwork[k];
+    5044    29311749 :         mid = (left + right) * .5;
+    5045    29311749 :         width = right - mid;
+    5046             :         d__1 = std::abs(left);
+    5047             :         d__2 = std::abs(right);
+    5048    29311749 :         tmp = (d__1>d__2) ? d__1 : d__2;
+    5049             : 
+    5050             :         gap = 0.;
+    5051    29311749 :         if (i__ == nright) {
+    5052    29071087 :             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    29068696 :             } else if (prev > 0) {
+    5056     4055695 :                 gap = left - work[k - 2];
+    5057    25013001 :             } else if (next <= *n) {
+    5058    25013001 :                 gap = work[k + 1] - right;
+    5059             :             }
+    5060             :         }
+    5061    29311749 :         d__1 = *rtol1 * gap, d__2 = *rtol2 * tmp;
+    5062    32850455 :         if (width < ((d__1>d__2) ? d__1 : d__2)) {
+    5063      570946 :             --nint;
+    5064      570946 :             iwork[k - 1] = 0;
+    5065             :             kk = k;
+    5066             :             i__2 = nright;
+    5067      570946 :             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      570946 :             if (i1 == i__) {
+    5075             :                 i1 = next;
+    5076             :             } else {
+    5077         831 :                 iwork[(prev << 1) - 1] = next;
+    5078             :             }
+    5079             :             i__ = next;
+    5080      570946 :             continue;
+    5081             :         }
+    5082             :         prev = i__;
+    5083             : 
+    5084    28740803 :         s = -mid;
+    5085             :         cnt = 0;
+    5086    28740803 :         i__2 = *n - 1;
+    5087   114232646 :         for (j = 1; j <= i__2; ++j) {
+    5088    85491843 :             dplus = d__[j] + s;
+    5089    85491843 :             s = s * lld[j] / dplus - mid;
+    5090    85491843 :             if (dplus < 0.) {
+    5091    15244804 :                 ++cnt;
+    5092             :             }
+    5093             :         }
+    5094    28740803 :         dplus = d__[*n] + s;
+    5095    28740803 :         if (dplus < 0.) {
+    5096    12605336 :             ++cnt;
+    5097             :         }
+    5098    28740803 :         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    28740803 :         i__2 = i__ - 1, i__3 = (nright<cnt) ? nright : cnt;
+    5120             :         cnt = (i__2>i__3) ? i__2 : i__3;
+    5121    28740803 :         if (cnt == i__ - 1) {
+    5122    13873731 :             work[k - 1] = mid;
+    5123    14867072 :         } else if (cnt == nright) {
+    5124    14658933 :             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    29310201 :     if (nint > 0) {
+    5148    28740121 :         goto L80;
+    5149             :     }
+    5150      570080 :     i__1 = *ilast;
+    5151     1141026 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+    5152      570946 :         k = i__ << 1;
+    5153      570946 :         ii = i__ - *offset;
+    5154      570946 :         if (iwork[k - 1] != -1) {
+    5155      570946 :             w[ii] = (work[k - 1] + work[k]) * .5;
+    5156      570946 :             werr[ii] = work[k] - w[ii];
+    5157      570946 :             if (i__ != *ilast) {
+    5158         866 :                 wgap[ii] = work[k + 1] - work[k];
+    5159             :             }
+    5160             :         }
+    5161             :     }
+    5162             : 
+    5163      570080 :     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      570008 : 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      570008 :     int c__1 = 1;
+    5207      570008 :     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      570008 :     --iwork;
+    5224      570008 :     --work;
+    5225      570008 :     --gersch;
+    5226      570008 :     --indexw;
+    5227      570008 :     --iblock;
+    5228      570008 :     --w;
+    5229      570008 :     --isplit;
+    5230      570008 :     --e;
+    5231      570008 :     --d__;
+    5232             : 
+    5233             :     sigma = 0;
+    5234             :     irange = 0;
+    5235             :     sgndef = 0;
+    5236             :     maxcnt = 0;
+    5237             : 
+    5238      570008 :     *info = 0;
+    5239             : 
+    5240      570008 :     if (*range=='A' || *range=='a')
+    5241             :         irange = 1;
+    5242      562533 :     else if (*range=='V' || *range=='v')
+    5243             :         irange = 2;
+    5244      562533 :     else if (*range=='I' || *range=='i')
+    5245             :         irange = 3;
+    5246             :     
+    5247             : 
+    5248      570008 :     *m = 0;
+    5249             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5250             : 
+    5251      570008 :     *nsplit = 1;
+    5252      570008 :     i__1 = *n - 1;
+    5253     2254429 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5254     1684421 :         if (std::abs(e[i__]) <= *tol) {
+    5255         675 :             isplit[*nsplit] = i__;
+    5256         675 :             ++(*nsplit);
+    5257             :         }
+    5258             :     }
+    5259      570008 :     isplit[*nsplit] = *n;
+    5260             : 
+    5261             :     ibegin = 1;
+    5262      570008 :     i__1 = *nsplit;
+    5263     1140691 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5264      570683 :         iend = isplit[jblk];
+    5265      570683 :         if (ibegin == iend) {
+    5266         673 :             ++(*m);
+    5267         673 :             w[*m] = d__[ibegin];
+    5268         673 :             iblock[*m] = jblk;
+    5269         673 :             indexw[*m] = 1;
+    5270         673 :             e[iend] = 0.;
+    5271         673 :             ibegin = iend + 1;
+    5272         673 :             goto L170;
+    5273             :         }
+    5274      570010 :         in = iend - ibegin + 1;
+    5275             : 
+    5276      570010 :         gl = d__[ibegin] - std::abs(e[ibegin]);
+    5277      570010 :         gu = d__[ibegin] + std::abs(e[ibegin]);
+    5278      570010 :         gersch[(ibegin << 1) - 1] = gl;
+    5279      570010 :         gersch[ibegin * 2] = gu;
+    5280      570010 :         gersch[(iend << 1) - 1] = d__[iend] - std::abs(e[iend - 1]);
+    5281      570010 :         gersch[iend * 2] = d__[iend] + std::abs(e[iend - 1]);
+    5282      570010 :         d__1 = gersch[(iend << 1) - 1];
+    5283      570010 :         gl = (d__1<gl) ? d__1 : gl;
+    5284             :         d__1 = gersch[iend * 2];
+    5285      570010 :         gu = (d__1>gu) ? d__1 : gu;
+    5286      570010 :         i__2 = iend - 1;
+    5287     1683746 :         for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5288     1113736 :             offd = std::abs(e[i__ - 1]) + std::abs(e[i__]);
+    5289     1113736 :             gersch[(i__ << 1) - 1] = d__[i__] - offd;
+    5290             :             d__1 = gersch[(i__ << 1) - 1];
+    5291     1113736 :             gl = (d__1<gl) ? d__1 : gl;
+    5292     1113736 :             gersch[i__ * 2] = d__[i__] + offd;
+    5293             :             d__1 = gersch[i__ * 2];
+    5294     1113736 :             gu = (d__1>gu) ? d__1 : gu;
+    5295             :         }
+    5296             :         d__1 = std::abs(gl), d__2 = std::abs(gu);
+    5297      570010 :         nrm = (d__1>d__2) ? d__1 : d__2;
+    5298             : 
+    5299      570010 :         width = gu - gl;
+    5300             :         i__2 = iend - 1;
+    5301     2253756 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5302     1683746 :             work[i__] = e[i__] * e[i__];
+    5303             :         }
+    5304     1710030 :         for (j = 1; j <= 2; ++j) {
+    5305     1140020 :             if (j == 1) {
+    5306      570010 :                 tau = gl + width * .25;
+    5307             :             } else {
+    5308      570010 :                 tau = gu - width * .25;
+    5309             :             }
+    5310     1140020 :             tmp = d__[ibegin] - tau;
+    5311     1140020 :             if (tmp < 0.) {
+    5312      596324 :                 cnt = 1;
+    5313             :             } else {
+    5314      543696 :                 cnt = 0;
+    5315             :             }
+    5316     1140020 :             i__2 = iend;
+    5317     4507512 :             for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5318     3367492 :                 tmp = d__[i__] - tau - work[i__ - 1] / tmp;
+    5319     3367492 :                 if (tmp < 0.) {
+    5320     1585152 :                     ++cnt;
+    5321             :                 }
+    5322             :             }
+    5323     1140020 :             if (cnt == 0) {
+    5324             :                 gl = tau;
+    5325     1140020 :             } else if (cnt == in) {
+    5326             :                 gu = tau;
+    5327             :             }
+    5328     1140020 :             if (j == 1) {
+    5329             :                 maxcnt = cnt;
+    5330             :                 sigma = gl;
+    5331             :                 sgndef = 1.;
+    5332             :             } else {
+    5333      570010 :                 if (in - cnt > maxcnt) {
+    5334             :                     sigma = gu;
+    5335             :                     sgndef = -1.;
+    5336             :                 }
+    5337             :             }
+    5338             :         }
+    5339             : 
+    5340      570010 :         work[in * 3] = 1.;
+    5341             :         delta = eps;
+    5342      570010 :         tau = sgndef * nrm;
+    5343      570010 : L60:
+    5344      570010 :         sigma -= delta * tau;
+    5345      570010 :         work[1] = d__[ibegin] - sigma;
+    5346             :         j = ibegin;
+    5347      570010 :         i__2 = in - 1;
+    5348     2253756 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5349     1683746 :             work[(in << 1) + i__] = 1. / work[i__];
+    5350     1683746 :             tmp = e[j] * work[(in << 1) + i__];
+    5351     1683746 :             work[i__ + 1] = d__[j + 1] - sigma - tmp * e[j];
+    5352     1683746 :             work[in + i__] = tmp;
+    5353     1683746 :             ++j;
+    5354             :         }
+    5355     2823766 :         for (i__ = in; i__ >= 1; --i__) {
+    5356     2253756 :             tmp = sgndef * work[i__];
+    5357     2253756 :         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      570010 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+    5364      570010 :         i__2 = in - 1;
+    5365      570010 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+    5366      570010 :         i__2 = in - 1;
+    5367     2253756 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5368     1683746 :             work[in * 3 + i__] = work[i__] * work[in + i__];
+    5369     1683746 :             work[(in << 2) + i__] = work[in * 3 + i__] * work[in + i__];
+    5370             :         }
+    5371      570010 :         if (sgndef > 0.) {
+    5372      490451 :             cnt = 1;
+    5373      490451 :             work[1] = (gl + gu) / 2. - sigma;
+    5374      490451 :             work[in + 1] = 0.;
+    5375      490451 :             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      570010 :         rtol = eps * 4.;
+    5383      570010 :         PLUMED_BLAS_F77_FUNC(dlarrbx,DLARRBX)(&in, &d__[ibegin], &e[ibegin], &work[in * 3 + 1], &work[(in <<
+    5384      570010 :                  2) + 1], &cnt, &cnt, &rtol, &rtol, &c__0, &work[1], &work[in 
+    5385      570010 :                 + 1], &work[(in << 1) + 1], &work[in * 5 + 1], &iwork[1], &
+    5386             :                 iinfo);
+    5387      570010 :         if (sgndef > 0.) {
+    5388      490451 :             tau = work[1] - work[(in << 1) + 1];
+    5389             :         } else {
+    5390       79559 :             tau = work[in] + work[in * 3];
+    5391             :         }
+    5392             : 
+    5393      570010 :         work[in * 3] = 1.;
+    5394             :         delta = eps * 2.;
+    5395      570010 : L100:
+    5396      570010 :         tau *= 1. - delta;
+    5397             : 
+    5398      570010 :         s = -tau;
+    5399             :         j = ibegin;
+    5400      570010 :         i__2 = in - 1;
+    5401     2253756 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5402     1683746 :             work[i__] = d__[j] + s;
+    5403     1683746 :             work[(in << 1) + i__] = 1. / work[i__];
+    5404     1683746 :             work[in + i__] = e[j] * d__[j] * work[(in << 1) + i__];
+    5405     1683746 :             s = s * work[in + i__] * e[j] - tau;
+    5406     1683746 :             ++j;
+    5407             :         }
+    5408      570010 :         work[in] = d__[iend] + s;
+    5409             : 
+    5410     2823766 :         for (i__ = in; i__ >= 1; --i__) {
+    5411     2253756 :             tmp = sgndef * work[i__];
+    5412     2253756 :             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      570010 :         sigma += tau;
+    5419      570010 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+    5420      570010 :         i__2 = in - 1;
+    5421      570010 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+    5422      570010 :         e[iend] = sigma;
+    5423      570010 :         tmp = (double) in * 4. * eps * (std::abs(sigma) + std::abs(tau));
+    5424             :         i__2 = iend;
+    5425     2823766 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5426     2253756 :             gersch[(i__ << 1) - 1] = gersch[(i__ << 1) - 1] - sigma - tmp;
+    5427     2253756 :             gersch[i__ * 2] = gersch[i__ * 2] - sigma + tmp;
+    5428             :         }
+    5429             : 
+    5430             :         j = ibegin;
+    5431      570010 :         i__2 = in - 1;
+    5432     2253756 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5433     1683746 :             work[(i__ << 1) - 1] = std::abs(d__[j]);
+    5434     1683746 :             work[i__ * 2] = e[j] * e[j] * work[(i__ << 1) - 1];
+    5435     1683746 :             ++j;
+    5436             :         }
+    5437      570010 :         work[(in << 1) - 1] = std::abs(d__[iend]);
+    5438             : 
+    5439      570010 :         PLUMED_BLAS_F77_FUNC(dlasq2,DLASQ2)(&in, &work[1], info);
+    5440      570010 :         if (*info != 0) {
+    5441             :             return;
+    5442             :         }
+    5443             : 
+    5444      570010 :         if (sgndef > 0.) {
+    5445      490451 :             i__2 = in;
+    5446     2426211 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5447     1935760 :                 ++(*m);
+    5448     1935760 :                 w[*m] = work[in - i__ + 1];
+    5449     1935760 :                 iblock[*m] = jblk;
+    5450     1935760 :                 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      570010 :         ibegin = iend + 1;
+    5462      570683 : L170:
+    5463             :         ;
+    5464             :     }
+    5465      570008 :     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      570008 :     } else if (irange == 3) {
+    5485      562533 :         *m = *iu - *il + 1;
+    5486      562533 :         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         693 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5496         681 :                 iend = isplit[i__];
+    5497         681 :                 i__2 = iend;
+    5498        1459 :                 for (j = ibegin; j <= i__2; ++j) {
+    5499         778 :                     work[j] = w[j] + e[iend];
+    5500             :                 }
+    5501         681 :                 ibegin = iend + 1;
+    5502             :             }
+    5503          12 :             i__1 = *n;
+    5504         790 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5505         778 :                 iwork[i__] = i__;
+    5506         778 :                 iwork[*n + i__] = iblock[i__];
+    5507             :             }
+    5508          12 :             PLUMED_BLAS_F77_FUNC(dlasrt2,DLASRT2)("I", n, &work[1], &iwork[1], &iinfo);
+    5509          12 :             i__1 = *m;
+    5510         781 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5511         769 :                 itmp = iwork[*il + i__ - 1];
+    5512         769 :                 work[i__] = w[itmp];
+    5513         769 :                 iblock[i__] = iwork[*n + itmp];
+    5514             :             }
+    5515          12 :             i__1 = *m;
+    5516         781 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5517         769 :                 iwork[*n + i__] = iwork[*il + i__ - 1];
+    5518         769 :                 iwork[i__] = i__;
+    5519             :             }
+    5520          12 :             PLUMED_BLAS_F77_FUNC(ilasrt2,ILASRT2)("I", m, &iblock[1], &iwork[1], &iinfo);
+    5521             :             j = 1;
+    5522          12 :             itmp = iblock[j];
+    5523          12 :             cnt = iwork[*n + iwork[j]];
+    5524          12 :             if (itmp == 1) {
+    5525             :                 ibegin = 1;
+    5526             :             } else {
+    5527           0 :                 ibegin = isplit[itmp - 1] + 1;
+    5528             :             }
+    5529          12 :             i__1 = *m;
+    5530         781 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5531         769 :                 w[i__] = work[iwork[i__]];
+    5532         769 :                 if (iblock[i__] != itmp || i__ == *m) {
+    5533         678 :                     if (iblock[i__] == itmp) {
+    5534          12 :                         till = *m;
+    5535             :                     } else {
+    5536         666 :                         till = i__ - 1;
+    5537             :                     }
+    5538         678 :                     i__2 = till - j + 1;
+    5539         678 :                     PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("I", &i__2, &w[j], &iinfo);
+    5540         678 :                     cnt = cnt - ibegin + 1;
+    5541         678 :                     i__2 = till;
+    5542        1447 :                     for (k = j; k <= i__2; ++k) {
+    5543         769 :                         indexw[k] = cnt + k - j;
+    5544             :                     }
+    5545             :                     j = i__;
+    5546         678 :                     itmp = iblock[j];
+    5547         678 :                     cnt = iwork[*n + iwork[j]];
+    5548         678 :                     ibegin = isplit[itmp - 1] + 1;
+    5549         678 :                     if (i__ == *m && till < *m) {
+    5550           0 :                         indexw[*m] = cnt - ibegin + 1;
+    5551             :                     }
+    5552             :                 } else {
+    5553          91 :                     i__2 = cnt, i__3 = iwork[*n + iwork[i__]];
+    5554          91 :                     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      569964 : 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      569964 :     double c_b5 = 0.;
+    5696      569964 :     int c__1 = 1;
+    5697      569964 :     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      569964 :     --d__;
+    5732      569964 :     --l;
+    5733             :     --isplit;
+    5734      569964 :     --w;
+    5735      569964 :     --iblock;
+    5736      569964 :     --indexw;
+    5737             :     --gersch;
+    5738      569964 :     z_dim1 = *ldz;
+    5739      569964 :     z_offset = 1 + z_dim1;
+    5740      569964 :     z__ -= z_offset;
+    5741      569964 :     --isuppz;
+    5742      569964 :     --work;
+    5743      569964 :     --iwork;
+    5744             : 
+    5745      569964 :     inderr = *n;
+    5746      569964 :     indld = *n << 1;
+    5747      569964 :     indlld = *n * 3;
+    5748      569964 :     indgap = *n << 2;
+    5749      569964 :     indwrk = *n * 5 + 1;
+    5750             : 
+    5751             :     iindr = *n;
+    5752             :     iindc1 = *n << 1;
+    5753             :     iindc2 = *n * 3;
+    5754      569964 :     iindwk = (*n << 2) + 1;
+    5755             : 
+    5756             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5757             : 
+    5758             :     i__1 = *n << 1;
+    5759     5078558 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5760     4508594 :         iwork[i__] = 0;
+    5761             :     }
+    5762      569964 :     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      569964 :     i__1 = iblock[*m];
+    5768     1140600 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5769      570636 :         iend = isplit[jblk];
+    5770             : 
+    5771      570636 :         wend = wbegin - 1;
+    5772     1178167 : L171:
+    5773     1178167 :         if (wend < *m) {
+    5774      608203 :             if (iblock[wend + 1] == jblk) {
+    5775      607531 :                 ++wend;
+    5776      607531 :                 goto L171;
+    5777             :             }
+    5778             :         }
+    5779      570636 :         if (wend < wbegin) {
+    5780           0 :             ibegin = iend + 1;
+    5781           0 :             continue;
+    5782             :         }
+    5783             : 
+    5784      570636 :         if (ibegin == iend) {
+    5785         673 :             z__[ibegin + wbegin * z_dim1] = 1.;
+    5786         673 :             isuppz[(wbegin << 1) - 1] = ibegin;
+    5787         673 :             isuppz[wbegin * 2] = ibegin;
+    5788         673 :             ibegin = iend + 1;
+    5789         673 :             wbegin = wend + 1;
+    5790         673 :             continue;
+    5791             :         }
+    5792      569963 :         oldien = ibegin - 1;
+    5793      569963 :         in = iend - oldien;
+    5794      569963 :         d__1 = .001, d__2 = 1. / (double) in;
+    5795      569963 :         reltol = (d__1<d__2) ? d__1 : d__2;
+    5796      569963 :         im = wend - wbegin + 1;
+    5797      569963 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&im, &w[wbegin], &c__1, &work[1], &c__1);
+    5798      569963 :         i__2 = im - 1;
+    5799      606858 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5800       36895 :             work[inderr + i__] = eps * std::abs(work[i__]);
+    5801       36895 :             work[indgap + i__] = work[i__ + 1] - work[i__];
+    5802             :         }
+    5803      569963 :         work[inderr + im] = eps * std::abs(work[im]);
+    5804      569963 :         d__2 = std::abs(work[im]);
+    5805      569963 :         work[indgap + im] = (d__2>eps) ? d__2 : eps;
+    5806             :         ndone = 0;
+    5807             : 
+    5808             :         ndepth = 0;
+    5809             :         parity = 1;
+    5810             :         nclus = 1;
+    5811      569963 :         iwork[iindc1 + 1] = 1;
+    5812      569963 :         iwork[iindc1 + 2] = im;
+    5813             : 
+    5814     1139933 : L40:
+    5815     1139933 :         if (ndone < im) {
+    5816             :             oldncl = nclus;
+    5817             :             nclus = 0;
+    5818      569970 :             parity = 1 - parity;
+    5819      569970 :             if (parity == 0) {
+    5820             :                 oldcls = iindc1;
+    5821             :                 newcls = iindc2;
+    5822             :             } else {
+    5823             :                 oldcls = iindc2;
+    5824             :                 newcls = iindc1;
+    5825             :             }
+    5826             :             i__2 = oldncl;
+    5827     1140003 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5828             : 
+    5829      570033 :                 j = oldcls + (i__ << 1);
+    5830      570033 :                 oldfst = iwork[j - 1];
+    5831      570033 :                 oldlst = iwork[j];
+    5832      570033 :                 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      570033 :                 i__3 = in - 1;
+    5844     2281895 :                 for (j = 1; j <= i__3; ++j) {
+    5845     1711862 :                     tmp = d__[k] * l[k];
+    5846     1711862 :                     work[indld + j] = tmp;
+    5847     1711862 :                     work[indlld + j] = tmp * l[k];
+    5848     1711862 :                     ++k;
+    5849             :                 }
+    5850      570033 :                 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      570033 :                 newfrs = oldfst;
+    5862      570033 :                 i__3 = oldlst;
+    5863     1177827 :                 for (j = oldfst; j <= i__3; ++j) {
+    5864      607794 :                     if (j == oldlst || work[indgap + j] >= 
+    5865       37761 :                         reltol * std::abs(work[j])) {
+    5866      606928 :                         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      606928 :                     newsiz = newlst - newfrs + 1;
+    5878      606928 :                     newftt = wbegin + newfrs - 1;
+    5879      606928 :                     nomgs = newsiz == 1 || newsiz > 1 || minrgp < mgstol;
+    5880      606928 :                     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     1213716 :                         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       21047 :                                 gap = work[indgap + k - 1];
+    5951      587084 :                             } else if (k == 1) {
+    5952      570469 :                                 gap = work[indgap + k];
+    5953             :                             } else {
+    5954       16615 :                                 d__1 = work[indgap + k - 1], d__2 = work[
+    5955       16615 :                                         indgap + k];
+    5956       16615 :                                 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        1285 :                                 work[k] = lambda + rqcorr;
+    5962        1285 :                                 if (iter < 8) {
+    5963        1273 :                                     goto L90;
+    5964             :                                 }
+    5965             :                             }
+    5966      606858 :                             iwork[ktot] = 1;
+    5967      606858 :                             if (newsiz == 1) {
+    5968      606858 :                                 ++ndone;
+    5969             :                             }
+    5970      606858 :                             zfrom = isuppz[(ktot << 1) - 1];
+    5971      606858 :                             zto = isuppz[ktot * 2];
+    5972      606858 :                             i__5 = zto - zfrom + 1;
+    5973      606858 :                             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__5, &nrminv, &z__[ibegin + zfrom - 1 + 
+    5974      606858 :                                     ktot * z_dim1], &c__1);
+    5975      606858 :                             ++ktot;
+    5976             :                         }
+    5977      606858 :                         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      606928 :                     newfrs = j + 1;
+    6010             :                 }
+    6011             :             }
+    6012      569970 :             ++ndepth;
+    6013      569970 :             goto L40;
+    6014             :         }
+    6015      569963 :         j = wbegin << 1;
+    6016             :         i__2 = wend;
+    6017     1176821 :         for (i__ = wbegin; i__ <= i__2; ++i__) {
+    6018      606858 :             isuppz[j - 1] += oldien;
+    6019      606858 :             isuppz[j] += oldien;
+    6020      606858 :             j += 2;
+    6021             : 
+    6022             :         }
+    6023      569963 :         ibegin = iend + 1;
+    6024      569963 :         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      570476 : 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      570476 :   const char ch=std::toupper(*uplo);
+    9107             : 
+    9108      570476 :   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      570476 :   } 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     1185835 :     for(j=0;j<*n;j++) {
+    9122     4343218 :       for(i=0;i<*m;i++)
+    9123     3727858 :         a[j*(*lda)+i] = *alpha;
+    9124             :     }    
+    9125             :   }
+    9126             : 
+    9127      570476 :   k = (*m < *n) ? *m : *n;
+    9128     1185837 :   for(i=0;i<k;i++)
+    9129      615361 :     a[i*(*lda)+i] = *beta;
+    9130      570476 : }
+    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      570010 : 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      570010 :     --z__;
+    9265             : 
+    9266      570010 :     *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      570010 :     if (*n < 0) {
+    9277           0 :         *info = -1;
+    9278           0 :         return;
+    9279      570010 :     } else if (*n == 0) {
+    9280             :         return;
+    9281      570010 :     } else if (*n == 1) {
+    9282             : 
+    9283           0 :         if (z__[1] < 0.) {
+    9284           0 :             *info = -201;
+    9285             :         }
+    9286           0 :         return;
+    9287      570010 :     } else if (*n == 2) {
+    9288             : 
+    9289       13363 :         if (z__[2] < 0. || z__[3] < 0.) {
+    9290           0 :             *info = -2;
+    9291           0 :             return;
+    9292       13363 :         } else if (z__[3] > z__[1]) {
+    9293             :             d__ = z__[3];
+    9294           0 :             z__[3] = z__[1];
+    9295           0 :             z__[1] = d__;
+    9296             :         }
+    9297       13363 :         z__[5] = z__[1] + z__[2] + z__[3];
+    9298       13363 :         if (z__[2] > z__[3] * tol2) {
+    9299       13363 :             t = (z__[1] - z__[3] + z__[2]) * .5;
+    9300       13363 :             s = z__[3] * (z__[2] / t);
+    9301       13363 :             if (s <= t) {
+    9302       13363 :                 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       13363 :             t = z__[1] + (s + z__[2]);
+    9307       13363 :             z__[3] *= z__[1] / t;
+    9308       13363 :             z__[1] = t;
+    9309             :         }
+    9310       13363 :         z__[2] = z__[3];
+    9311       13363 :         z__[6] = z__[2] + z__[1];
+    9312       13363 :         return;
+    9313             :     }
+    9314      556647 :     z__[*n * 2] = 0.;
+    9315      556647 :     emin = z__[2];
+    9316      556647 :     qmax = 0.;
+    9317             :     zmax = 0.;
+    9318             :     d__ = 0.;
+    9319             :     e = 0.;
+    9320             : 
+    9321      556647 :     i__1 = 2*(*n - 1);
+    9322     2227030 :     for (k = 1; k <= i__1; k += 2) {
+    9323     1670383 :         if (z__[k] < 0.) {
+    9324           0 :             *info = -(k + 200);
+    9325           0 :             return;
+    9326     1670383 :         } else if (z__[k + 1] < 0.) {
+    9327           0 :             *info = -(k + 201);
+    9328           0 :             return;
+    9329             :         }
+    9330     1670383 :         d__ += z__[k];
+    9331     1670383 :         e += z__[k + 1];
+    9332     1670383 :         d__1 = qmax, d__2 = z__[k];
+    9333     1670383 :         qmax = (d__1>d__2) ? d__1 : d__2;
+    9334             :         d__1 = emin, d__2 = z__[k + 1];
+    9335     1670383 :         emin = (d__1<d__2) ? d__1 : d__2;
+    9336     1670383 :         d__1 = (qmax>zmax) ? qmax : zmax;
+    9337             :         d__2 = z__[k + 1];
+    9338     1670383 :         zmax = (d__1>d__2) ? d__1 : d__2;
+    9339             :     }
+    9340      556647 :     if (z__[(*n << 1) - 1] < 0.) {
+    9341           0 :         *info = -((*n << 1) + 199);
+    9342           0 :         return;
+    9343             :     }
+    9344      556647 :     d__ += z__[(*n << 1) - 1];
+    9345      556647 :     d__1 = qmax, d__2 = z__[(*n << 1) - 1];
+    9346      556658 :     qmax = (d__1>d__2) ? d__1 : d__2;
+    9347             : 
+    9348      556647 :     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      556647 :     trace = d__ + e;
+    9359             : 
+    9360      556647 :     if (std::abs(trace)<PLUMED_GMX_DOUBLE_MIN) {
+    9361           0 :         z__[(*n << 1) - 1] = 0.;
+    9362           0 :         return;
+    9363             :     }
+    9364             : 
+    9365      556647 :     ieee = 1;
+    9366      556647 :     posinf = one/zero;
+    9367      556647 :     if(posinf<=1.0)
+    9368           0 :       ieee = 0;
+    9369             :     neginf = -one/zero;
+    9370      556647 :     if(neginf>=0.0)
+    9371           0 :       ieee = 0;
+    9372      556647 :     negzro = one/(neginf+one);
+    9373      556647 :     if(std::abs(negzro)>PLUMED_GMX_DOUBLE_MIN)
+    9374           0 :       ieee = 0;
+    9375      556647 :     neginf = one/negzro;
+    9376      556647 :     if(neginf>=0)
+    9377           0 :       ieee = 0;
+    9378      556647 :     newzro = negzro + zero;
+    9379      556647 :     if(std::abs(newzro-zero)>PLUMED_GMX_DOUBLE_MIN)
+    9380           0 :       ieee = 0;
+    9381      556647 :     posinf = one /newzro;
+    9382      556647 :     if(posinf<=one)
+    9383           0 :       ieee = 0;
+    9384      556647 :     neginf = neginf*posinf;
+    9385      556647 :     if(neginf>=zero)
+    9386           0 :       ieee = 0;
+    9387      556647 :     posinf = posinf*posinf;
+    9388      556647 :     if(posinf<=1.0)
+    9389           0 :       ieee = 0;
+    9390             : 
+    9391     2783677 :     for (k = *n << 1; k >= 2; k += -2) {
+    9392     2227030 :         z__[k * 2] = 0.;
+    9393     2227030 :         z__[(k << 1) - 1] = z__[k];
+    9394     2227030 :         z__[(k << 1) - 2] = 0.;
+    9395     2227030 :         z__[(k << 1) - 3] = z__[k - 1];
+    9396             :     }
+    9397             : 
+    9398      556647 :     i0 = 1;
+    9399      556647 :     n0 = *n;
+    9400             : 
+    9401      556647 :     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      556647 :     pp = 0;
+    9415             : 
+    9416     1669941 :     for (k = 1; k <= 2; ++k) {
+    9417             : 
+    9418     1113294 :         d__ = z__[(n0 << 2) + pp - 3];
+    9419     1113294 :         i__1 = (i0 << 2) + pp;
+    9420     4454060 :         for (i4 = 4*(n0 - 1) + pp; i4 >= i__1; i4 += -4) {
+    9421     3340766 :             if (z__[i4 - 1] <= tol2 * d__) {
+    9422           4 :                 z__[i4 - 1] = -0.;
+    9423           4 :                 d__ = z__[i4 - 3];
+    9424             :             } else {
+    9425     3340762 :                 d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1]));
+    9426             :             }
+    9427             :         }
+    9428             : 
+    9429     1113294 :         emin = z__[(i0 << 2) + pp + 1];
+    9430     1113294 :         d__ = z__[(i0 << 2) + pp - 3];
+    9431             :         i__1 = 4*(n0 - 1) + pp;
+    9432     4454060 :         for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
+    9433     3340766 :             z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
+    9434     3340766 :             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     3340743 :             } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && 
+    9440     3340743 :                     safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
+    9441     3340739 :                 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
+    9442     3340739 :                 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
+    9443     3340739 :                 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     3340766 :             d__1 = emin, d__2 = z__[i4 - (pp << 1)];
+    9450     3340766 :             emin = (d__1<d__2) ? d__1 : d__2;
+    9451             :         }
+    9452     1113294 :         z__[(n0 << 2) - pp - 2] = d__;
+    9453             : 
+    9454             : 
+    9455     1113294 :         qmax = z__[(i0 << 2) - pp - 2];
+    9456     1113294 :         i__1 = (n0 << 2) - pp - 2;
+    9457     4454060 :         for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
+    9458     3340766 :             d__1 = qmax, d__2 = z__[i4];
+    9459     4475339 :             qmax = (d__1>d__2) ? d__1 : d__2;
+    9460             :         }
+    9461             : 
+    9462     1113294 :         pp = 1 - pp;
+    9463             :     }
+    9464             : 
+    9465      556647 :     iter = 2;
+    9466      556647 :     nfail = 0;
+    9467      556647 :     ndiv = 2*(n0 - i0);
+    9468             : 
+    9469      556647 :     i__1 = *n + 1;
+    9470     1113431 :     for (iwhila = 1; iwhila <= i__1; ++iwhila) {
+    9471     1113431 :         if (n0 < 1) {
+    9472      556647 :             goto L170;
+    9473             :         }
+    9474             : 
+    9475      556784 :         desig = 0.;
+    9476      556784 :         if (n0 == *n) {
+    9477      556647 :             sigma = 0.;
+    9478             :         } else {
+    9479         137 :             sigma = -z__[(n0 << 2) - 1];
+    9480             :         }
+    9481      556784 :         if (sigma < 0.) {
+    9482           0 :             *info = 1;
+    9483           0 :             return;
+    9484             :         }
+    9485             : 
+    9486             :         emax = 0.;
+    9487      556784 :         if (n0 > i0) {
+    9488      556647 :             emin = std::abs(z__[(n0 << 2) - 5]);
+    9489             :         } else {
+    9490             :             emin = 0.;
+    9491             :         }
+    9492      556784 :         qmin = z__[(n0 << 2) - 3];
+    9493      556784 :         qmax = qmin;
+    9494     2232245 :         for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
+    9495     1675574 :             if (z__[i4 - 5] <= 0.) {
+    9496         113 :                 goto L100;
+    9497             :             }
+    9498     1675461 :             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     1675461 :             d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
+    9505     1675461 :             qmax = (d__1>d__2) ? d__1 : d__2;
+    9506             :             d__1 = emin, d__2 = z__[i4 - 5];
+    9507     1675461 :             emin = (d__1<d__2) ? d__1 : d__2;
+    9508             :         }
+    9509             :         i4 = 4;
+    9510             : 
+    9511      556784 : L100:
+    9512      556784 :         i0 = i4 / 4;
+    9513      556784 :         pp = 0;
+    9514             : 
+    9515      556784 :         if (n0 - i0 > 1) {
+    9516      556742 :             dee = z__[(i0 << 2) - 3];
+    9517             :             deemin = dee;
+    9518             :             kmin = i0;
+    9519      556742 :             i__2 = (n0 << 2) - 3;
+    9520     2788941 :             for (i4 = (i0 << 2) - 3; i4 <= i__2; i4 += 4) {
+    9521     2232199 :                 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
+    9522     2232199 :                 if (dee <= deemin) {
+    9523             :                     deemin = dee;
+    9524     1206047 :                     kmin = (i4 + 3) / 4;
+    9525             :                 }
+    9526             :             }
+    9527      556742 :             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      556784 :         d__1 = 0., d__2 = qmin -  std::sqrt(qmin) * 2. * std::sqrt(emax);
+    9551      556784 :         dmin__ = -((d__1>d__2) ? d__1 : d__2);
+    9552             : 
+    9553      556784 :         nbig = (n0 - i0 + 1) * 30;
+    9554             :         i__2 = nbig;
+    9555    13682186 :         for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
+    9556    13682186 :             if (i0 > n0) {
+    9557      556784 :                 goto L150;
+    9558             :             }
+    9559             : 
+    9560    13125402 :             PLUMED_BLAS_F77_FUNC(dlasq3,DLASQ3)(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
+    9561             :                     nfail, &iter, &ndiv, &ieee);
+    9562             : 
+    9563    13125402 :             pp = 1 - pp;
+    9564             : 
+    9565    13125402 :             if (pp == 0 && n0 - i0 >= 3) {
+    9566      162442 :                 if (z__[n0 * 4] <= tol2 * qmax || z__[(n0 << 2) - 1] <= tol2 *
+    9567             :                          sigma) {
+    9568         295 :                     splt = i0 - 1;
+    9569         295 :                     qmax = z__[(i0 << 2) - 3];
+    9570         295 :                     emin = z__[(i0 << 2) - 1];
+    9571         295 :                     oldemn = z__[i0 * 4];
+    9572         295 :                     i__3 = 4*(n0 - 3);
+    9573       41884 :                     for (i4 = i0 << 2; i4 <= i__3; i4 += 4) {
+    9574       41589 :                         if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <= 
+    9575       41562 :                                 tol2 * sigma) {
+    9576         114 :                             z__[i4 - 1] = -sigma;
+    9577         114 :                             splt = i4 / 4;
+    9578         114 :                             qmax = 0.;
+    9579         114 :                             emin = z__[i4 + 3];
+    9580         114 :                             oldemn = z__[i4 + 4];
+    9581             :                         } else {
+    9582       41475 :                             d__1 = qmax, d__2 = z__[i4 + 1];
+    9583       41475 :                             qmax = (d__1>d__2) ? d__1 : d__2;
+    9584             :                             d__1 = emin, d__2 = z__[i4 - 1];
+    9585       41475 :                             emin = (d__1<d__2) ? d__1 : d__2;
+    9586             :                             d__1 = oldemn, d__2 = z__[i4];
+    9587       41475 :                             oldemn = (d__1<d__2) ? d__1 : d__2;
+    9588             :                         }
+    9589             :                     }
+    9590         295 :                     z__[(n0 << 2) - 1] = emin;
+    9591         295 :                     z__[n0 * 4] = oldemn;
+    9592         295 :                     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      556647 :     i__1 = *n;
+    9611     2227030 :     for (k = 2; k <= i__1; ++k) {
+    9612     1670383 :         z__[k] = z__[(k << 2) - 3];
+    9613             :     }
+    9614             : 
+    9615      556647 :     PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("D", n, &z__[1], &iinfo);
+    9616             : 
+    9617             :     e = 0.;
+    9618     2783677 :     for (k = *n; k >= 1; --k) {
+    9619     2227030 :         e += z__[k];
+    9620             :     }
+    9621             : 
+    9622             : 
+    9623      556647 :     z__[(*n << 1) + 1] = trace;
+    9624      556647 :     z__[(*n << 1) + 2] = e;
+    9625      556647 :     z__[(*n << 1) + 3] = (double) iter;
+    9626      556647 :     i__1 = *n;
+    9627      556647 :     z__[(*n << 1) + 4] = (double) ndiv / (double) (i__1 * i__1);
+    9628      556647 :     z__[(*n << 1) + 5] = nfail * 100. / (double) iter;
+    9629             : 
+    9630      556647 :     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    13125402 : 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    13125402 :     int ttype = 0;
+    9664    13125402 :     double dmin1 = 0.;
+    9665    13125402 :     double dmin2 = 0.;
+    9666    13125402 :     double dn = 0.;
+    9667    13125402 :     double dn1 = 0.;
+    9668    13125402 :     double dn2 = 0.;
+    9669    13125402 :     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    13125402 :     --z__;
+    9679             : 
+    9680    13125402 :     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     1670169 : L10:
+    9688             : 
+    9689    14795571 :     if (*n0 < *i0) {
+    9690             :         return;
+    9691             :     }
+    9692    14238787 :     if (*n0 == *i0) {
+    9693          82 :         goto L20;
+    9694             :     }
+    9695    14238705 :     nn = (*n0 << 2) + *pp;
+    9696    14238705 :     if (*n0 == *i0 + 1) {
+    9697      556702 :         goto L40;
+    9698             :     }
+    9699             : 
+    9700    13682003 :     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
+    9701    12568777 :             4] > tol2 * z__[nn - 7]) {
+    9702    12568777 :         goto L30;
+    9703             :     }
+    9704             : 
+    9705     1113226 : L20:
+    9706             : 
+    9707     1113308 :     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
+    9708     1113308 :     --(*n0);
+    9709     1113308 :     goto L10;
+    9710             : 
+    9711             : L30:
+    9712             : 
+    9713    12568777 :     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
+    9714    12568618 :             nn - 11]) {
+    9715    12568618 :         goto L50;
+    9716             :     }
+    9717             : 
+    9718         159 : L40:
+    9719             : 
+    9720      556861 :     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      556861 :     if (z__[nn - 5] > z__[nn - 3] * tol2) {
+    9726      556861 :         t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
+    9727      556861 :         s = z__[nn - 3] * (z__[nn - 5] / t);
+    9728      556861 :         if (s <= t) {
+    9729      539400 :             s = z__[nn - 3] * (z__[nn - 5] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+    9730             :         } else {
+    9731       17461 :             s = z__[nn - 3] * (z__[nn - 5] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+    9732             :         }
+    9733      556861 :         t = z__[nn - 7] + (s + z__[nn - 5]);
+    9734      556861 :         z__[nn - 3] *= z__[nn - 7] / t;
+    9735      556861 :         z__[nn - 7] = t;
+    9736             :     }
+    9737      556861 :     z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
+    9738      556861 :     z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
+    9739      556861 :     *n0 += -2;
+    9740      556861 :     goto L10;
+    9741             : 
+    9742             : L50:
+    9743    12568618 :     if (*pp == 2) {
+    9744        7987 :         *pp = 0;
+    9745             :     }
+    9746             : 
+    9747    12568618 :     if (*dmin__ <= 0. || *n0 < n0in) {
+    9748     1113374 :         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    12568618 :     PLUMED_BLAS_F77_FUNC(dlasq4,DLASQ4)(i0, n0, &z__[1], pp, &n0in, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9788             :             dn2, &tau, &ttype);
+    9789             : 
+    9790    12568622 : L70:
+    9791             : 
+    9792    12568622 :     PLUMED_BLAS_F77_FUNC(dlasq5,DLASQ5)(i0, n0, &z__[1], pp, &tau, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9793             :             dn2, ieee);
+    9794             : 
+    9795    12568622 :     *ndiv += *n0 - *i0 + 2;
+    9796    12568622 :     ++(*iter);
+    9797             : 
+    9798    12568622 :     if (*dmin__ >= 0. && dmin1 > 0.) {
+    9799             : 
+    9800    12568618 :         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    12568618 : L90:
+    9837    12568618 :     if (tau < *sigma) {
+    9838    10899679 :         *desig += tau;
+    9839    10899679 :         t = *sigma + *desig;
+    9840    10899679 :         *desig -= t - *sigma;
+    9841             :     } else {
+    9842     1668939 :         t = *sigma + tau;
+    9843     1668939 :         *desig = *sigma - (t - tau) + *desig;
+    9844             :     }
+    9845    12568618 :     *sigma = t;
+    9846             : 
+    9847    12568618 :     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    12568618 : 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    12568618 :     if (*dmin__ <= 0.) {
+    9885      848266 :         *tau = -(*dmin__);
+    9886      848266 :         *ttype = -1;
+    9887      848266 :         return;
+    9888             :     }
+    9889             : 
+    9890             :     s = 0.0;
+    9891             : 
+    9892    11720352 :     nn = (*n0 << 2) + *pp;
+    9893    11720352 :     if (*n0in == *n0) {
+    9894             : 
+    9895    11455244 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin__ + *dn) ||
+    9896    11455244 :          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    11455244 :         } 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    11455244 :             if (*ttype == -6) {
+   10023             :                 g += (1. - g) * .333;
+   10024    11455244 :             } else if (*ttype == -18) {
+   10025             :                 g = .083250000000000005;
+   10026             :             } else {
+   10027             :                 g = .25;
+   10028             :             }
+   10029    11455244 :             s = g * *dmin__;
+   10030    11455244 :             *ttype = -6;
+   10031             :         }
+   10032             : 
+   10033      265108 :     } else if (*n0in == *n0 + 1) {
+   10034             : 
+   10035      264999 :         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      264999 :             s = *dmin1 * .25;
+   10076      264999 :             if (std::abs(*dmin1 - *dn1)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin1 + *dn1)) {
+   10077           0 :                 s = *dmin1 * .5;
+   10078             :             }
+   10079      264999 :             *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    11720352 :     *tau = s;
+   10131    11720352 :     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    12568622 : 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    12568622 :     --z__;
+   10167             : 
+   10168    12568622 :     if (*n0 - *i0 - 1 <= 0) {
+   10169             :         return;
+   10170             :     }
+   10171             : 
+   10172    12568622 :     j4 = (*i0 << 2) + *pp - 3;
+   10173    12568622 :     emin = z__[j4 + 4];
+   10174    12568622 :     d__ = z__[j4] - *tau;
+   10175    12568622 :     *dmin__ = d__;
+   10176    12568622 :     *dmin1 = -z__[j4];
+   10177             : 
+   10178    12568622 :     if (*ieee) {
+   10179             : 
+   10180    12568622 :         if (*pp == 0) {
+   10181     6430722 :             i__1 = 4*(*n0 - 3);
+   10182     7707448 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10183     1276726 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   10184     1276726 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   10185     1276726 :                 d__ = d__ * temp - *tau;
+   10186     1276726 :                 if(d__<*dmin__)
+   10187      328355 :                   *dmin__ = d__;
+   10188     1276726 :                 z__[j4] = z__[j4 - 1] * temp;
+   10189             :                 d__1 = z__[j4];
+   10190     1276726 :                 if(d__1<emin)
+   10191             :                   emin = d__1;
+   10192             :             }
+   10193             :         } else {
+   10194     6137900 :             i__1 = 4*(*n0 - 3);
+   10195     7015624 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10196      877724 :                 z__[j4 - 3] = d__ + z__[j4];
+   10197      877724 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   10198      877724 :                 d__ = d__ * temp - *tau;
+   10199      877724 :                 if(d__<*dmin__)
+   10200      239825 :                   *dmin__ = d__;
+   10201      877724 :                 z__[j4 - 1] = z__[j4] * temp;
+   10202             :                 d__1 = z__[j4 - 1];
+   10203      877724 :                 if(d__1<emin)
+   10204             :                   emin = d__1;
+   10205             :             }
+   10206             :         }
+   10207             : 
+   10208    12568622 :         *dnm2 = d__;
+   10209    12568622 :         *dmin2 = *dmin__;
+   10210    12568622 :         j4 = 4*(*n0 - 2) - *pp;
+   10211    12568622 :         j4p2 = j4 + (*pp << 1) - 1;
+   10212    12568622 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   10213    12568622 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10214    12568622 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   10215    12568622 :         if(*dnm1<*dmin__)
+   10216     9958506 :           *dmin__ = *dnm1;
+   10217             : 
+   10218    12568622 :         *dmin1 = *dmin__;
+   10219    12568622 :         j4 += 4;
+   10220    12568622 :         j4p2 = j4 + (*pp << 1) - 1;
+   10221    12568622 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   10222    12568622 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10223    12568622 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   10224    12568622 :         if(*dn<*dmin__)
+   10225    12019692 :           *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    12568622 :     z__[j4 + 2] = *dn;
+   10291    12568622 :     z__[(*n0 << 2) - *pp] = emin;
+   10292    12568622 :     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      557325 : 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      557325 :     --d__;
+   10717             : 
+   10718      557325 :     *info = 0;
+   10719             :     dir = -1;
+   10720      557325 :     if (*id=='D' || *id=='d') 
+   10721             :         dir = 0;
+   10722         678 :     else if (*id=='I' || *id=='i') 
+   10723             :         dir = 1;
+   10724             :    
+   10725             :     if (dir == -1) {
+   10726           0 :         *info = -1;
+   10727      557325 :     } else if (*n < 0) {
+   10728           0 :         *info = -2;
+   10729             :     }
+   10730      557325 :     if (*info != 0) {
+   10731             :         return;
+   10732             :     }
+   10733      557325 :     if (*n <= 1) {
+   10734             :         return;
+   10735             :     }
+   10736             : 
+   10737             :     stkpnt = 1;
+   10738      556656 :     stack[0] = 1;
+   10739      556656 :     stack[1] = *n;
+   10740      556774 : L10:
+   10741      556774 :     start = stack[(stkpnt << 1) - 2];
+   10742      556774 :     endd = stack[(stkpnt << 1) - 1];
+   10743      556774 :     --stkpnt;
+   10744      556774 :     if (endd - start <= 20 && endd - start > 0) {
+   10745             : 
+   10746             : 
+   10747      556715 :         if (dir == 0) {
+   10748             : 
+   10749             :             i__1 = endd;
+   10750     2227030 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10751             :                 i__2 = start + 1;
+   10752     1670327 :                 for (j = i__; j >= i__2; --j) {
+   10753     1670327 :                     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     1670327 :                         goto L30;
+   10759             :                     }
+   10760             :                 }
+   10761     1670327 : L30:
+   10762             :                 ;
+   10763             :             }
+   10764             : 
+   10765             :         } else {
+   10766             : 
+   10767             :             i__1 = endd;
+   10768         100 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10769             :                 i__2 = start + 1;
+   10770          88 :                 for (j = i__; j >= i__2; --j) {
+   10771          88 :                     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          88 :                         goto L50;
+   10777             :                     }
+   10778             :                 }
+   10779          88 : 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      556774 :     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          12 : 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          12 :     --key;
+   10916          12 :     --d__;
+   10917             : 
+   10918          12 :     *info = 0;
+   10919             :     dir = -1;
+   10920          12 :     if (*id=='D' || *id=='d')
+   10921             :         dir = 0;
+   10922          12 :     else if (*id=='I' || *id=='i')
+   10923             :         dir = 1;
+   10924             :     
+   10925             :     if (dir == -1) {
+   10926           0 :         *info = -1;
+   10927          12 :     } else if (*n < 0) {
+   10928           0 :         *info = -2;
+   10929             :     }
+   10930          12 :     if (*info != 0) {
+   10931             :         return;
+   10932             :     }
+   10933             : 
+   10934          12 :     if (*n <= 1) {
+   10935             :         return;
+   10936             :     }
+   10937             : 
+   10938             :     stkpnt = 1;
+   10939          12 :     stack[0] = 1;
+   10940          12 :     stack[1] = *n;
+   10941          12 : L10:
+   10942          12 :     start = stack[(stkpnt << 1) - 2];
+   10943          12 :     endd = stack[(stkpnt << 1) - 1];
+   10944          12 :     --stkpnt;
+   10945          12 :     if (endd - start > 0) {
+   10946             : 
+   10947          12 :         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         778 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10970             :                 i__2 = start + 1;
+   10971       17390 :                 for (j = i__; j >= i__2; --j) {
+   10972       17302 :                     if (d__[j] < d__[j - 1]) {
+   10973             :                         dmnmx = d__[j];
+   10974       16624 :                         d__[j] = d__[j - 1];
+   10975       16624 :                         d__[j - 1] = dmnmx;
+   10976       16624 :                         tmpkey = key[j];
+   10977       16624 :                         key[j] = key[j - 1];
+   10978       16624 :                         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          12 :     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      569952 : 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      569952 :     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      569952 :     a_dim1 = *lda;
+   12074      569952 :     a_offset = 1 + a_dim1;
+   12075      569952 :     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      569952 :     *info = 0;
+   12084      569952 :     left = (*side=='L' || *side=='l');
+   12085      569952 :     notran = (*trans=='N' || *trans=='n');
+   12086             : 
+   12087      569952 :     if (left) {
+   12088      569952 :         nq = *m;
+   12089             :     } else {
+   12090           0 :         nq = *n;
+   12091             :     }
+   12092             :     if (*info != 0) {
+   12093             :         return;
+   12094             :     }
+   12095             : 
+   12096      569952 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12097             :         return;
+   12098             :     }
+   12099             : 
+   12100      569952 :     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      569952 :     if (left) {
+   12111      569952 :         ni = *n;
+   12112             :     } else {
+   12113           0 :         mi = *m;
+   12114             :     }
+   12115             : 
+   12116             :     i__1 = i2;
+   12117             :     i__2 = i3;
+   12118     2252681 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12119     1682729 :         if (left) {
+   12120             : 
+   12121     1682729 :             mi = *m - *k + i__;
+   12122             :         } else {
+   12123             : 
+   12124           0 :             ni = *n - *k + i__;
+   12125             :         }
+   12126             : 
+   12127     1682729 :         aii = a[nq - *k + i__ + i__ * a_dim1];
+   12128     1682729 :         a[nq - *k + i__ + i__ * a_dim1] = 1.;
+   12129     1682729 :         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     1682729 :         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      569964 : 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      569964 :     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      569964 :     a_dim1 = *lda;
+   12607      569964 :     a_offset = 1 + a_dim1;
+   12608      569964 :     a -= a_offset;
+   12609             :     --tau;
+   12610             :     c_dim1 = *ldc;
+   12611             :     c_offset = 1 + c_dim1;
+   12612             :     c__ -= c_offset;
+   12613             :     --work;
+   12614             : 
+   12615      569964 :     *info = 0;
+   12616      569964 :     left = (*side=='L' || *side=='l');
+   12617      569964 :     notran = (*trans=='N' || *trans=='n');
+   12618      569964 :     lquery = *lwork == -1;
+   12619             : 
+   12620      569964 :     if (left) {
+   12621      569964 :         nq = *m;
+   12622      569964 :         nw = *n;
+   12623             :     } else {
+   12624           0 :         nq = *n;
+   12625           0 :         nw = *m;
+   12626             :     }
+   12627             : 
+   12628             :     nb = DORMQL_BLOCKSIZE;
+   12629      569964 :     lwkopt = nw * nb;
+   12630      569964 :     work[1] = (double) lwkopt;
+   12631             :     
+   12632      569964 :     if (*info != 0) {
+   12633             :         return;
+   12634      569964 :     } else if (lquery) {
+   12635             :         return;
+   12636             :     }
+   12637             : 
+   12638      569964 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12639           0 :         work[1] = 1.;
+   12640           0 :         return;
+   12641             :     }
+   12642             : 
+   12643             :     nbmin = 2;
+   12644      569964 :     ldwork = nw;
+   12645      569964 :     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      569964 :     if (nb < nbmin || nb >= *k) {
+   12654             : 
+   12655      569952 :         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      569964 :     work[1] = (double) lwkopt;
+   12698      569964 :     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      569964 : 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      569964 :     a_dim1 = *lda;
+   12877      569964 :     a_offset = 1 + a_dim1;
+   12878      569964 :     a -= a_offset;
+   12879             :     --tau;
+   12880      569964 :     c_dim1 = *ldc;
+   12881      569964 :     c_offset = 1 + c_dim1;
+   12882      569964 :     c__ -= c_offset;
+   12883             :     --work;
+   12884             : 
+   12885      569964 :     *info = 0;
+   12886      569964 :     left = (*side=='L' || *side=='l');
+   12887      569964 :     upper = (*uplo=='U' || *uplo=='u');
+   12888      569964 :     lquery = *lwork == -1;
+   12889             : 
+   12890      569964 :     if (left) {
+   12891      569964 :         nq = *m;
+   12892      569964 :         nw = *n;
+   12893             :     } else {
+   12894           0 :         nq = *n;
+   12895           0 :         nw = *m;
+   12896             :     }
+   12897             : 
+   12898             : 
+   12899             :     nb = DORMQL_BLOCKSIZE;
+   12900      569964 :     lwkopt = nw * nb;
+   12901      569964 :     work[1] = (double) lwkopt;
+   12902             :     
+   12903      569964 :     if (*info != 0) {
+   12904             :         i__2 = -(*info);
+   12905             :         return;
+   12906      569964 :     } else if (lquery) {
+   12907             :         return;
+   12908             :     }
+   12909             : 
+   12910      569964 :     if (*m == 0 || *n == 0 || nq == 1) {
+   12911           0 :         work[1] = 1.;
+   12912           0 :         return;
+   12913             :     }
+   12914             : 
+   12915      569964 :     if (left) {
+   12916      569964 :         mi = *m - 1;
+   12917      569964 :         ni = *n;
+   12918             :     } else {
+   12919           0 :         mi = *m;
+   12920           0 :         ni = *n - 1;
+   12921             :     }
+   12922             : 
+   12923      569964 :     if (upper) {
+   12924      569964 :         i__2 = nq - 1;
+   12925      569964 :         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      569964 :     work[1] = (double) lwkopt;
+   12940      569964 :     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      570008 : 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      570008 :     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      570008 :     --w;
+   13492      570008 :     z_dim1 = *ldz;
+   13493      570008 :     z_offset = 1 + z_dim1;
+   13494      570008 :     z__ -= z_offset;
+   13495      570008 :     --isuppz;
+   13496      570008 :     --work;
+   13497      570008 :     --iwork;
+   13498             : 
+   13499      570008 :     wantz = (*jobz=='V' || *jobz=='v');
+   13500      570008 :     alleig = (*range=='A' || *range=='a');
+   13501      570008 :     valeig = (*range=='V' || *range=='v');
+   13502      570008 :     indeig = (*range=='I' || *range=='i');
+   13503             : 
+   13504      570008 :     lquery = *lwork == -1 || *liwork == -1;
+   13505      570008 :     lwmin = *n * 17;
+   13506      570008 :     liwmin = *n * 10;
+   13507             : 
+   13508      570008 :     *info = 0;
+   13509      570008 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   13510           0 :         *info = -1;
+   13511      570008 :     } else if (! (alleig || valeig || indeig)) {
+   13512           0 :         *info = -2;
+   13513      570008 :     } else if (*n < 0) {
+   13514           0 :         *info = -3;
+   13515      570008 :     } else if (valeig && *n > 0 && *vu <= *vl) {
+   13516           0 :         *info = -7;
+   13517      570008 :     } else if (indeig && (*il < 1 || *il > *n)) {
+   13518           0 :         *info = -8;
+   13519      570008 :     } else if (indeig && (*iu < *il || *iu > *n)) {
+   13520           0 :         *info = -9;
+   13521      570008 :     } else if (*ldz < 1 || (wantz && *ldz < *n)) {
+   13522           0 :         *info = -14;
+   13523      570008 :     } else if (*lwork < lwmin && ! lquery) {
+   13524           0 :         *info = -17;
+   13525      570008 :     } else if (*liwork < liwmin && ! lquery) {
+   13526           0 :         *info = -19;
+   13527             :     }
+   13528      570008 :     if (*info == 0) {
+   13529      570008 :         work[1] = (double) lwmin;
+   13530      570008 :         iwork[1] = liwmin;
+   13531             :     }
+   13532             : 
+   13533      570008 :     if (*info != 0) {
+   13534             :         i__1 = -(*info);
+   13535             :         return;
+   13536      570008 :     } else if (lquery) {
+   13537             :         return;
+   13538             :     }
+   13539             : 
+   13540      570008 :     *m = 0;
+   13541      570008 :     if (*n == 0) {
+   13542             :         return;
+   13543             :     }
+   13544             : 
+   13545      570008 :     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      570008 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   13568             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   13569      570008 :     scale = 1.;
+   13570      570008 :     tnrm = PLUMED_BLAS_F77_FUNC(dlanst,DLANST)("M", n, &d__[1], &e[1]);
+   13571      570008 :     if (tnrm > 0. && tnrm < rmin) {
+   13572           0 :         scale = rmin / tnrm;
+   13573      570008 :     } else if (tnrm > rmax) {
+   13574           0 :         scale = rmax / tnrm;
+   13575             :     }
+   13576      570008 :     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      570008 :     indwrk = (*n << 1) + 1;
+   13584             : 
+   13585             :     iinspl = 1;
+   13586      570008 :     iindbl = *n + 1;
+   13587             :     iindw = (*n << 1) + 1;
+   13588      570008 :     iindwk = *n * 3 + 1;
+   13589             : 
+   13590      570008 :     thresh = eps * tnrm;
+   13591      570008 :     PLUMED_BLAS_F77_FUNC(dlarrex,DLARREX)(range, n, vl, vu, il, iu, &d__[1], &e[1], &thresh, &nsplit, &
+   13592      570008 :             iwork[iinspl], m, &w[1], &iwork[iindbl], &iwork[iindw], &work[
+   13593      570008 :             indgrs], &work[indwrk], &iwork[iindwk], &iinfo);
+   13594             :     
+   13595      570008 :     if (iinfo != 0) {
+   13596           0 :         *info = 1;
+   13597           0 :         return;
+   13598             :     }
+   13599             : 
+   13600      570008 :     if (wantz) {
+   13601      569964 :         d__1 = *abstol, d__2 = (double) (*n) * eps;
+   13602      569964 :         tol = (d__1>d__2) ? d__1 : d__2;
+   13603      569964 :         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      569964 :         if (iinfo != 0) {
+   13607           0 :             *info = 2;
+   13608           0 :             return;
+   13609             :         }
+   13610             :     }
+   13611             : 
+   13612      570008 :     i__1 = *m;
+   13613     1177671 :     for (j = 1; j <= i__1; ++j) {
+   13614      607663 :         itmp = iwork[iindbl + j - 1];
+   13615      607663 :         w[j] += e[iwork[iinspl + itmp - 1]];
+   13616             :     } 
+   13617             : 
+   13618      570008 :     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      570008 :     if (nsplit > 1) {
+   13623          18 :         i__1 = *m - 1;
+   13624         793 :         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      570008 :     work[1] = (double) lwmin;
+   13652      570008 :     iwork[1] = liwmin;
+   13653      570008 :     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      584795 : 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      584795 :     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      584795 :     a_dim1 = *lda;
+   14769      584795 :     a_offset = 1 + a_dim1;
+   14770      584795 :     a -= a_offset;
+   14771      584795 :     --w;
+   14772      584795 :     z_dim1 = *ldz;
+   14773      584795 :     z_offset = 1 + z_dim1;
+   14774      584795 :     z__ -= z_offset;
+   14775             :     --isuppz;
+   14776      584795 :     --work;
+   14777      584795 :     --iwork;
+   14778             : 
+   14779      584795 :     lower = (*uplo=='L' || *uplo=='l');
+   14780      584795 :     wantz = (*jobz=='V' || *jobz=='v');
+   14781      584795 :     alleig = (*range=='A' || *range=='a');
+   14782      584795 :     valeig = (*range=='V' || *range=='v');
+   14783      584795 :     indeig = (*range=='I' || *range=='i');
+   14784             : 
+   14785             :     indibl = 0;
+   14786      584795 :     lquery = *lwork == -1 || *liwork == -1;
+   14787             : 
+   14788             :     i__1 = 1;
+   14789      584795 :     i__2 = *n * 26;
+   14790             : 
+   14791      584795 :     if(*n>0) 
+   14792             :       lwmin = *n * 26;
+   14793             :     else
+   14794             :       lwmin = 1;
+   14795             : 
+   14796      584795 :     if(*n>0) 
+   14797      584795 :       liwmin = *n * 10;
+   14798             :     else
+   14799             :       liwmin = 1;
+   14800             : 
+   14801      584795 :     *info = 0;
+   14802      584795 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   14803           0 :         *info = -1;
+   14804      584795 :     } else if (! (alleig || valeig || indeig)) {
+   14805           0 :         *info = -2;
+   14806      584795 :     } else if (! (lower || (*uplo=='U' || *uplo=='u'))) {
+   14807           0 :         *info = -3;
+   14808      584795 :     } else if (*n < 0) {
+   14809           0 :         *info = -4;
+   14810      584795 :     } else if (*lda < ((*n>1) ? *n : 1) ) {
+   14811           0 :         *info = -6;
+   14812             :     } else {
+   14813      584795 :         if (valeig) {
+   14814           0 :             if (*n > 0 && *vu <= *vl) {
+   14815           0 :                 *info = -8;
+   14816             :             }
+   14817      584795 :         } else if (indeig) {
+   14818      577320 :           if (*il < 1 || *il > ((*n>1) ? *n : 1)) {
+   14819           0 :                 *info = -9;
+   14820      577320 :             } else if (*iu < ((*n<*il) ? *n : *il) || *iu > *n) {
+   14821           0 :                 *info = -10;
+   14822             :             }
+   14823             :         }
+   14824             :     }
+   14825      584795 :     if (*info == 0) {
+   14826      584795 :       if (*ldz < 1 || (wantz && *ldz < *n)) {
+   14827           0 :             *info = -15;
+   14828      584795 :         } else if (*lwork < lwmin && ! lquery) {
+   14829           0 :             *info = -18;
+   14830      584795 :         } else if (*liwork < liwmin && ! lquery) {
+   14831           0 :             *info = -20;
+   14832             :         }
+   14833             :     }
+   14834             : 
+   14835      584795 :     if (*info == 0) {
+   14836             :       nb = 32;
+   14837             :       /* Computing MAX */
+   14838      584795 :       i__1 = (nb + 1) * *n;
+   14839             :       lwkopt = (i__1>lwmin) ? i__1 : lwmin;
+   14840      584795 :       work[1] = (double) lwkopt;
+   14841      584795 :       iwork[1] = liwmin;
+   14842             :     } else 
+   14843             :       return;
+   14844             : 
+   14845      584795 :     if (lquery) 
+   14846             :         return;
+   14847             :     
+   14848      570596 :     *m = 0;
+   14849      570596 :     if (*n == 0) {
+   14850           0 :         work[1] = 1.;
+   14851           0 :         return;
+   14852             :     }
+   14853             : 
+   14854      570596 :     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      570008 :     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      570008 :     anrm = PLUMED_BLAS_F77_FUNC(dlansy,DLANSY)("M", uplo, n, &a[a_offset], lda, &work[1]);
+   14883      570008 :     if (anrm > 0. && anrm < rmin) {
+   14884             :         iscale = 1;
+   14885           0 :         sigma = rmin / anrm;
+   14886      570008 :     } 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      570008 :     inde = indtau + *n;
+   14908      570008 :     indd = inde + *n;
+   14909      570008 :     indee = indd + *n;
+   14910      570008 :     inddd = indee + *n;
+   14911      570008 :     indifl = inddd + *n;
+   14912      570008 :     indwk = indifl + *n;
+   14913      570008 :     llwork = *lwork - indwk + 1;
+   14914      570008 :     PLUMED_BLAS_F77_FUNC(dsytrd,DSYTRD)(uplo, n, &a[a_offset], lda, &work[indd], &work[inde], &work[
+   14915      570008 :             indtau], &work[indwk], &llwork, &iinfo);
+   14916             : 
+   14917      570008 :     i__1 = *n - 1;
+   14918      570008 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &work[inde], &c__1, &work[indee], &c__1);
+   14919      570008 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &work[indd], &c__1, &work[inddd], &c__1);
+   14920             : 
+   14921      570008 :     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      570008 :     if (wantz && *info == 0) {
+   14925             :       indwkn = inde;
+   14926      569964 :       llwrkn = *lwork - indwkn + 1;
+   14927      569964 :       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      570008 :     if (*info != 0) 
+   14932             :       return;
+   14933             : 
+   14934      570008 :     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      570008 :     if (wantz) {
+   14945      569964 :         i__1 = *m - 1;
+   14946             :         
+   14947      607531 :         for (j = 1; j <= i__1; ++j) {
+   14948             :             i__ = 0;
+   14949       37567 :             tmp1 = w[j];
+   14950       37567 :             i__2 = *m;
+   14951      291780 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   14952      254213 :                 if (w[jj] < tmp1) {
+   14953             :                     i__ = jj;
+   14954             :                     tmp1 = w[jj];
+   14955             :                 }
+   14956             :             }
+   14957             : 
+   14958       37567 :             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      570008 :     work[1] = (double) lwkopt;
+   14971      570008 :     iwork[1] = liwmin;
+   14972      570008 :     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      570008 : 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      570008 :   const char ch=std::toupper(*uplo);
+   15003             : 
+   15004      570008 :   zero = 0.0;
+   15005      570008 :   minusone = -1.0;
+   15006             : 
+   15007      570008 :   if(*n<=0)
+   15008             :     return;
+   15009             : 
+   15010      570008 :   if(ch=='U') {
+   15011     2253916 :     for(i=*n-1;i>=1;i--) {
+   15012             : 
+   15013     1683908 :       ti1 = 1;
+   15014     1683908 :       PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i,&(a[i*(*lda)+(i-1)]),&(a[i*(*lda)+0]),&ti1,&taui);
+   15015     1683908 :       e[i-1] = a[i*(*lda) + (i-1)];
+   15016     1683908 :       if(std::abs(taui)>PLUMED_GMX_DOUBLE_MIN) {
+   15017     1113895 :         a[i*(*lda)+(i-1)] = 1.0;
+   15018             :       
+   15019     1113895 :         ti1 = 1;
+   15020     1113895 :         PLUMED_BLAS_F77_FUNC(dsymv,DSYMV)("U",&i,&taui,a,lda,&(a[i*(*lda)+0]),&ti1,&zero,tau,&ti1);
+   15021             : 
+   15022     1113895 :         tmp = PLUMED_BLAS_F77_FUNC(ddot,DDOT)(&i,tau,&ti1,&(a[i*(*lda)+0]),&ti1);
+   15023             : 
+   15024     1113895 :         alpha = -0.5*taui*tmp;
+   15025             : 
+   15026     1113895 :         PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(&i,&alpha,&(a[i*(*lda)+0]),&ti1,tau,&ti1);
+   15027             : 
+   15028     1113895 :         PLUMED_BLAS_F77_FUNC(dsyr2,DSYR2)("U",&i,&minusone,&(a[i*(*lda)+0]),&ti1,tau,&ti1,a,lda);
+   15029             : 
+   15030     1113895 :         a[i*(*lda)+(i-1)] = e[i-1]; 
+   15031             : 
+   15032             :       }
+   15033     1683908 :       d[i] = a[i*(*lda)+i];
+   15034     1683908 :       tau[i-1] = taui;
+   15035             :     }
+   15036      570008 :     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      570008 : 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      570008 :     double c_b22 = -1.;
+   15103      570008 :     double c_b23 = 1.;
+   15104             : 
+   15105             : 
+   15106             :     /* Parameter adjustments */
+   15107      570008 :     a_dim1 = *lda;
+   15108      570008 :     a_offset = 1 + a_dim1;
+   15109      570008 :     a -= a_offset;
+   15110      570008 :     --d__;
+   15111      570008 :     --e;
+   15112      570008 :     --tau;
+   15113             :     --work;
+   15114             : 
+   15115             :     /* Function Body */
+   15116      570008 :     *info = 0;
+   15117      570008 :     upper = (*uplo=='U' || *uplo=='u');
+   15118      570008 :     lquery = (*lwork == -1);
+   15119             : 
+   15120      570008 :     if (! upper && ! (*uplo=='L' || *uplo=='l')) {
+   15121           0 :         *info = -1;
+   15122      570008 :     } else if (*n < 0) {
+   15123           0 :         *info = -2;
+   15124      570008 :     } else if (*lda < ((1>*n) ? 1 : *n)) {
+   15125           0 :         *info = -4;
+   15126      570008 :     } else if (*lwork < 1 && ! lquery) {
+   15127           0 :         *info = -9;
+   15128             :     }
+   15129             : 
+   15130      570008 :     if (*info == 0) {
+   15131             : 
+   15132      570008 :       nb = DSYTRD_BLOCKSIZE;
+   15133      570008 :       lwkopt = *n * nb;
+   15134      570008 :       work[1] = (double) lwkopt;
+   15135             :     } else
+   15136             :       return;
+   15137             : 
+   15138      570008 :     if (lquery) 
+   15139             :       return;
+   15140             :   
+   15141      570008 :     if (*n == 0) {
+   15142           0 :         work[1] = 1.;
+   15143           0 :         return;
+   15144             :     }
+   15145             : 
+   15146             :     nx = *n;
+   15147      570008 :     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      569996 :         nb = 1;
+   15168             :     }
+   15169             : 
+   15170      570008 :     if (upper) {
+   15171             : 
+   15172      570008 :         kk = *n - (*n - nx + nb - 1) / nb * nb;
+   15173      570008 :         i__1 = kk + 1;
+   15174             :         i__2 = -nb;
+   15175      570027 :         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      570008 :         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      570008 :     work[1] = (double) lwkopt;
+   15229      570008 :     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          12 : 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          12 :     --key;
+   15439          12 :     --d__;
+   15440             : 
+   15441          12 :     *info = 0;
+   15442             :     dir = -1;
+   15443          12 :     if (*id=='D' || *id=='d') 
+   15444             :         dir = 0;
+   15445          12 :     else if (*id=='I' || *id=='i') 
+   15446             :         dir = 1;
+   15447             :     
+   15448             :     if (dir == -1) {
+   15449           0 :         *info = -1;
+   15450          12 :     } else if (*n < 0) {
+   15451           0 :         *info = -2;
+   15452             :     }
+   15453          12 :     if (*info != 0) {
+   15454             :         return;
+   15455             :     }
+   15456             : 
+   15457          12 :     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       17379 :                 for (j = i__; j >= i__2; --j) {
+   15497       17291 :                     if (d__[j] < d__[j - 1]) {
+   15498             :                         dmnmx = d__[j];
+   15499       16622 :                         d__[j] = d__[j - 1];
+   15500       16622 :                         d__[j - 1] = dmnmx;
+   15501       16622 :                         tmpkey = key[j];
+   15502       16622 :                         key[j] = key[j - 1];
+   15503       16622 :                         key[j - 1] = tmpkey;
+   15504             :                     } else {
+   15505         669 :                         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.15
+
+ + + 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 0000000000..1f7d2e2e68 --- /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-06-10 08:19:15Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_0
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE12
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv70
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev525
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE1134
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE1134
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_1134
_ZN4PLMD6lepton18CompiledExpressionC2Ev1162
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE1422
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv1944
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev2296
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev2296
_ZN4PLMD6lepton18CompiledExpressionD2Ev2296
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3737
_ZN4PLMD6lepton9useAsmJitEv5865
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE8569
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE16004
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd10694844
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv12901514
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.func.html b/coverage-libs/lepton/CompiledExpression.cpp.func.html new file mode 100644 index 0000000000..36807bb533 --- /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-06-10 08:19:15Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev2296
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev2296
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE16004
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv1944
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE8569
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3737
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE1134
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE1134
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_0
_ZN4PLMD6lepton18CompiledExpressionC2Ev1162
_ZN4PLMD6lepton18CompiledExpressionD2Ev2296
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_1134
_ZN4PLMD6lepton9useAsmJitEv5865
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd10694844
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE12
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE1422
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev525
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv12901514
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv70
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.gcov.html b/coverage-libs/lepton/CompiledExpression.cpp.gcov.html new file mode 100644 index 0000000000..eab0cf965d --- /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-06-10 08:19:15Functions: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        5865 : bool lepton::useAsmJit() {
+      80             : #ifdef __PLUMED_HAS_ASMJIT
+      81          70 :   static const bool use=[](){
+      82          70 :     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        5865 :   }();
+      90        5865 :   return use;
+      91             : #else
+      92             :   return false;
+      93             : #endif
+      94             : }
+      95             : 
+      96        2296 : AsmJitRuntimePtr::AsmJitRuntimePtr()
+      97             : #ifdef __PLUMED_HAS_ASMJIT
+      98        2296 :   : ptr(useAsmJit()?new asmjit::JitRuntime:nullptr)
+      99             : #endif
+     100        2296 : {}
+     101             : 
+     102        2296 : AsmJitRuntimePtr::~AsmJitRuntimePtr()
+     103             : {
+     104             : #ifdef __PLUMED_HAS_ASMJIT
+     105        2296 :   if(useAsmJit()) delete static_cast<asmjit::JitRuntime*>(ptr);
+     106             : #endif
+     107        2296 : }
+     108             : 
+     109        1162 : CompiledExpression::CompiledExpression() : jitCode(NULL) {
+     110        1162 : }
+     111             : 
+     112        1134 : CompiledExpression::CompiledExpression(const ParsedExpression& expression) : jitCode(NULL) {
+     113        1134 :     ParsedExpression expr = expression.optimize(); // Just in case it wasn't already optimized.
+     114             :     vector<pair<ExpressionTreeNode, int> > temps;
+     115        1134 :     compileExpression(expr.getRootNode(), temps);
+     116             :     int maxArguments = 1;
+     117        6785 :     for (int i = 0; i < (int) operation.size(); i++)
+     118        5651 :         if (operation[i]->getNumArguments() > maxArguments)
+     119         615 :             maxArguments = operation[i]->getNumArguments();
+     120        1134 :     argValues.resize(maxArguments);
+     121             : #ifdef __PLUMED_HAS_ASMJIT
+     122        1134 :     if(useAsmJit()) generateJitCode();
+     123             : #endif
+     124        2268 : }
+     125             : 
+     126        2296 : CompiledExpression::~CompiledExpression() {
+     127       13598 :     for (int i = 0; i < (int) operation.size(); i++)
+     128       11302 :         if (operation[i] != NULL)
+     129       11302 :             delete operation[i];
+     130        4592 : }
+     131             : 
+     132           0 : CompiledExpression::CompiledExpression(const CompiledExpression& expression) : jitCode(NULL) {
+     133           0 :     *this = expression;
+     134           0 : }
+     135             : 
+     136        1134 : CompiledExpression& CompiledExpression::operator=(const CompiledExpression& expression) {
+     137        1134 :     arguments = expression.arguments;
+     138        1134 :     target = expression.target;
+     139             :     variableIndices = expression.variableIndices;
+     140             :     variableNames = expression.variableNames;
+     141        1134 :     workspace.resize(expression.workspace.size());
+     142        1134 :     argValues.resize(expression.argValues.size());
+     143        1134 :     operation.resize(expression.operation.size());
+     144        6785 :     for (int i = 0; i < (int) operation.size(); i++)
+     145        5651 :         operation[i] = expression.operation[i]->clone();
+     146        1134 :     setVariableLocations(variablePointers);
+     147        1134 :     return *this;
+     148             : }
+     149             : 
+     150        8569 : void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
+     151        8569 :     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       14237 :     for (int i = 0; i < node.getChildren().size(); i++) {
+     158        7435 :         compileExpression(node.getChildren()[i], temps);
+     159        7435 :         args.push_back(findTempIndex(node.getChildren()[i], temps));
+     160             :     }
+     161             :     
+     162             :     // Process this node.
+     163             :     
+     164        6802 :     if (node.getOperation().getId() == Operation::VARIABLE) {
+     165        1151 :         variableIndices[node.getOperation().getName()] = (int) workspace.size();
+     166        2302 :         variableNames.insert(node.getOperation().getName());
+     167             :     }
+     168             :     else {
+     169        5651 :         int stepIndex = (int) arguments.size();
+     170        5651 :         arguments.push_back(vector<int>());
+     171        5651 :         target.push_back((int) workspace.size());
+     172        5651 :         operation.push_back(node.getOperation().clone());
+     173        5651 :         if (args.size() == 0)
+     174         231 :             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        7435 :             for (int i = 1; i < args.size(); i++)
+     180        2015 :                 if (args[i] != args[i-1]+1)
+     181             :                     sequential = false;
+     182        5420 :             if (sequential)
+     183        4196 :                 arguments[stepIndex].push_back(args[0]);
+     184             :             else
+     185        1224 :                 arguments[stepIndex] = args;
+     186             :         }
+     187             :     }
+     188        6802 :     temps.push_back(make_pair(node, (int) workspace.size()));
+     189        6802 :     workspace.push_back(0.0);
+     190             : }
+     191             : 
+     192       16004 : int CompiledExpression::findTempIndex(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
+     193       64034 :     for (int i = 0; i < (int) temps.size(); i++)
+     194       57232 :         if (temps[i].first == node)
+     195             :             return i;
+     196             :     return -1;
+     197             : }
+     198             : 
+     199         525 : const set<string>& CompiledExpression::getVariables() const {
+     200         525 :     return variableNames;
+     201             : }
+     202             : 
+     203        3737 : double& CompiledExpression::getVariableReference(const string& name) {
+     204             :     map<string, double*>::iterator pointer = variablePointers.find(name);
+     205        3737 :     if (pointer != variablePointers.end())
+     206           0 :         return *pointer->second;
+     207             :     map<string, int>::iterator index = variableIndices.find(name);
+     208        3737 :     if (index == variableIndices.end())
+     209        1100 :         throw Exception("getVariableReference: Unknown variable '"+name+"'");
+     210        3187 :     return workspace[index->second];
+     211             : }
+     212             : 
+     213        1134 : void CompiledExpression::setVariableLocations(map<string, double*>& variableLocations) {
+     214             :   variablePointers = variableLocations;
+     215        1134 :   static const bool asmjit=useAsmJit();
+     216        1134 :   if(asmjit) {
+     217             : #ifdef __PLUMED_HAS_ASMJIT
+     218             :     // Rebuild the JIT code.
+     219             :     
+     220         972 :     if (workspace.size() > 0)
+     221         972 :         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        1134 : }
+     234             : 
+     235    12901514 : double CompiledExpression::evaluate() const {
+     236    12901514 :     static const bool asmjit=useAsmJit();
+     237             : #ifdef __PLUMED_HAS_ASMJIT
+     238    12901514 :     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       48480 :     for (int step = 0; step < operation.size(); step++) {
+     246             :         const vector<int>& args = arguments[step];
+     247       32118 :         if (args.size() == 1)
+     248       29290 :             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    10694844 : static double evaluateOperation(Operation* op, double* args) {
+     260    10694844 :     static map<string, double> dummyVariables;
+     261    10694844 :     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        1944 : void CompiledExpression::generateJitCode() {
+     268        1944 :     CodeHolder code;
+     269             :     auto & runtime(*static_cast<asmjit::JitRuntime*>(runtimeptr.get()));
+     270        1944 :     code.init(runtime.getCodeInfo());
+     271        1944 :     X86Compiler c(&code);
+     272        1944 :     c.addFunc(FuncSignature0<double>());
+     273        1944 :     vector<X86Xmm> workspaceVar(workspace.size());
+     274       14652 :     for (int i = 0; i < (int) workspaceVar.size(); i++)
+     275       12708 :         workspaceVar[i] = c.newXmmSd();
+     276             :     X86Gp argsPointer = c.newIntPtr();
+     277        1944 :     c.mov(argsPointer, imm_ptr(&argValues[0]));
+     278             :     
+     279             :     // Load the arguments into variables.
+     280             :     
+     281        3986 :     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        4084 :         c.mov(variablePointer, imm_ptr(&getVariableReference(index->first)));
+     285        2042 :         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        1944 :     vector<int> operationConstantIndex(operation.size(), -1);
+     291       12610 :     for (int step = 0; step < (int) operation.size(); step++) {
+     292             :         // Find the constant value (if any) used by this operation.
+     293             :         
+     294       10666 :         Operation& op = *operation[step];
+     295             :         double value;
+     296       10666 :         if (op.getId() == Operation::CONSTANT)
+     297         330 :             value = dynamic_cast<Operation::Constant&>(op).getValue();
+     298       10336 :         else if (op.getId() == Operation::ADD_CONSTANT)
+     299         850 :             value = dynamic_cast<Operation::AddConstant&>(op).getValue();
+     300        9486 :         else if (op.getId() == Operation::MULTIPLY_CONSTANT)
+     301        2884 :             value = dynamic_cast<Operation::MultiplyConstant&>(op).getValue();
+     302        6602 :         else if (op.getId() == Operation::RECIPROCAL)
+     303         148 :             value = 1.0;
+     304        6454 :         else if (op.getId() == Operation::STEP)
+     305          74 :             value = 1.0;
+     306        6380 :         else if (op.getId() == Operation::DELTA)
+     307          40 :             value = 1.0/0.0;
+     308        6340 :         else if (op.getId() == Operation::NANDELTA)
+     309           6 :             value = std::numeric_limits<double>::quiet_NaN();
+     310             :         else
+     311        6334 :             continue;
+     312             :         
+     313             :         // See if we already have a variable for this constant.
+     314             :         
+     315        9206 :         for (int i = 0; i < (int) constants.size(); i++)
+     316        5422 :             if (value == constants[i]) {
+     317         548 :                 operationConstantIndex[step] = i;
+     318         548 :                 break;
+     319             :             }
+     320        4332 :         if (operationConstantIndex[step] == -1) {
+     321        3784 :             operationConstantIndex[step] = constants.size();
+     322        3784 :             constants.push_back(value);
+     323             :         }
+     324             :     }
+     325             :     
+     326             :     // Load constants into variables.
+     327             :     
+     328        1944 :     vector<X86Xmm> constantVar(constants.size());
+     329        1944 :     if (constants.size() > 0) {
+     330             :         X86Gp constantsPointer = c.newIntPtr();
+     331        1626 :         c.mov(constantsPointer, imm_ptr(&constants[0]));
+     332        5410 :         for (int i = 0; i < (int) constants.size(); i++) {
+     333        3784 :             constantVar[i] = c.newXmmSd();
+     334        3784 :             c.movsd(constantVar[i], x86::ptr(constantsPointer, 8*i, 0));
+     335             :         }
+     336             :     }
+     337             :     
+     338             :     // Evaluate the operations.
+     339             :     
+     340       12610 :     for (int step = 0; step < (int) operation.size(); step++) {
+     341       10666 :         Operation& op = *operation[step];
+     342       10666 :         vector<int> args = arguments[step];
+     343       10666 :         if (args.size() == 1) {
+     344             :             // One or more sequential arguments.  Fill out the list.
+     345             :             
+     346        9786 :             for (int i = 1; i < op.getNumArguments(); i++)
+     347        1512 :                 args.push_back(args[0]+i);
+     348             :         }
+     349             :         
+     350             :         // Generate instructions to execute this operation.
+     351             :         
+     352       10666 :         switch (op.getId()) {
+     353         330 :             case Operation::CONSTANT:
+     354         330 :                 c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     355       10464 :                 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         132 :             case Operation::NEGATE:
+     376         132 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     377         132 :                 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         506 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sin);
+     390             :                 break;
+     391             :             case Operation::COS:
+     392         798 :                 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         850 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     457         850 :                 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         444 :                 for (int i = 0; i < (int) args.size(); i++)
+     476         242 :                     c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]);
+     477             :                 X86Gp fn = c.newIntPtr();
+     478         202 :                 c.mov(fn, imm_ptr((void*) evaluateOperation));
+     479         202 :                 CCFuncCall* call = c.call(fn, FuncSignature2<double, Operation*, double*>());
+     480         202 :                 call->setArg(0, imm_ptr(&op));
+     481         202 :                 call->setArg(1, imm_ptr(&argValues[0]));
+     482         202 :                 call->setRet(0, workspaceVar[target[step]]);
+     483             :         }
+     484             :     }
+     485        1944 :     c.ret(workspaceVar[workspace.size()-1]);
+     486        1944 :     c.endFunc();
+     487        1944 :     c.finalize();
+     488        1944 :     runtime.add(&jitCode, &code);
+     489        1944 : }
+     490             : 
+     491        1422 : void generateSingleArgCall(X86Compiler& c, X86Xmm& dest, X86Xmm& arg, double (*function)(double)) {
+     492             :     X86Gp fn = c.newIntPtr();
+     493        1422 :     c.mov(fn, imm_ptr((void*) function));
+     494        1422 :     CCFuncCall* call = c.call(fn, FuncSignature1<double, double>());
+     495             :     call->setArg(0, arg);
+     496             :     call->setRet(0, dest);
+     497        1422 : }
+     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.15
+
+ + + 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 0000000000..1d2fea6d35 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.h.func.html b/coverage-libs/lepton/CompiledExpression.h.func.html new file mode 100644 index 0000000000..6e7fd92345 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.h.gcov.html b/coverage-libs/lepton/CompiledExpression.h.gcov.html new file mode 100644 index 0000000000..00cfec006c --- /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-06-10 08:19:15Functions: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        1944 :     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.15
+
+ + + 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 0000000000..dd599553bf --- /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-06-10 08:19:15Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZNK4PLMD6lepton9Exception4whatEv20
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE601
_ZN4PLMD6lepton9ExceptionD2Ev601
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.func.html b/coverage-libs/lepton/Exception.h.func.html new file mode 100644 index 0000000000..375dc08828 --- /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-06-10 08:19:15Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE601
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZN4PLMD6lepton9ExceptionD2Ev601
_ZNK4PLMD6lepton9Exception4whatEv20
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.gcov.html b/coverage-libs/lepton/Exception.h.gcov.html new file mode 100644 index 0000000000..7960456697 --- /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-06-10 08:19:15Functions: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         601 :     Exception(const std::string& message) : message(message) {
+      80         601 :     }
+      81         601 :     ~Exception() throw() {
+      82         601 :     }
+      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.15
+
+ + + 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 0000000000..c77aa6932b --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/lepton/ExpressionProgram.cpp.func.html b/coverage-libs/lepton/ExpressionProgram.cpp.func.html new file mode 100644 index 0000000000..43efeeba1f --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/lepton/ExpressionProgram.cpp.gcov.html b/coverage-libs/lepton/ExpressionProgram.cpp.gcov.html new file mode 100644 index 0000000000..185e57ac06 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..8fc1fdb232 --- /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-06-10 08:19:15Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_4115
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_8451
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_31663
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE57717
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_64616
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE79774
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_85904
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_119242
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2021146
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2094686
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev2136904
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_2754375
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv4894397
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv5838400
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev7014371
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html b/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html new file mode 100644 index 0000000000..c34fee36e0 --- /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-06-10 08:19:15Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_31663
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2021146
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_4115
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_8451
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE57717
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_2754375
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev2136904
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev7014371
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2094686
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_64616
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE79774
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv5838400
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv4894397
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_85904
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_119242
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html b/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html new file mode 100644 index 0000000000..7617f0392d --- /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-06-10 08:19:15Functions: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       57717 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const vector<ExpressionTreeNode>& children) : operation(operation), children(children) {
+      74       57717 :     if (operation->getNumArguments() != children.size())
+      75           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      76       57717 : }
+      77             : 
+      78        8451 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child1, const ExpressionTreeNode& child2) : operation(operation) {
+      79        8451 :     children.push_back(child1);
+      80        8451 :     children.push_back(child2);
+      81        8451 :     if (operation->getNumArguments() != children.size())
+      82           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      83        8451 : }
+      84             : 
+      85        4115 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child) : operation(operation) {
+      86        4115 :     children.push_back(child);
+      87        4115 :     if (operation->getNumArguments() != children.size())
+      88           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      89        4115 : }
+      90             : 
+      91     2021146 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation) : operation(operation) {
+      92     2021146 :     if (operation->getNumArguments() != children.size())
+      93           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      94     2021146 : }
+      95             : 
+      96     2754375 : ExpressionTreeNode::ExpressionTreeNode(const ExpressionTreeNode& node) : operation(node.operation == NULL ? NULL : node.operation->clone()), children(node.getChildren()) {
+      97     2754375 : }
+      98             : 
+      99       31663 : ExpressionTreeNode::ExpressionTreeNode(ExpressionTreeNode&& node) : operation(node.operation), children(move(node.children)) {
+     100       31663 :     node.operation = NULL;
+     101             :     node.children.clear();
+     102       31663 : }
+     103             : 
+     104     2136904 : ExpressionTreeNode::ExpressionTreeNode() : operation(NULL) {
+     105     2136904 : }
+     106             : 
+     107     7014371 : ExpressionTreeNode::~ExpressionTreeNode() {
+     108     7014371 :     if (operation != NULL)
+     109     4887954 :         delete operation;
+     110     7014371 : }
+     111             : 
+     112      119242 : bool ExpressionTreeNode::operator!=(const ExpressionTreeNode& node) const {
+     113      119242 :     if (node.getOperation() != getOperation())
+     114             :         return true;
+     115       61635 :     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       82810 :     for (int i = 0; i < (int) getChildren().size(); i++)
+     123       33338 :         if (getChildren()[i] != node.getChildren()[i])
+     124             :             return true;
+     125             :     return false;
+     126             : }
+     127             : 
+     128       85904 : bool ExpressionTreeNode::operator==(const ExpressionTreeNode& node) const {
+     129       85904 :     return !(*this != node);
+     130             : }
+     131             : 
+     132       64616 : ExpressionTreeNode& ExpressionTreeNode::operator=(const ExpressionTreeNode& node) {
+     133       64616 :     if (operation != NULL)
+     134       11673 :         delete operation;
+     135       64616 :     operation = node.getOperation().clone();
+     136       64616 :     children = node.getChildren();
+     137       64616 :     return *this;
+     138             : }
+     139             : 
+     140     2094686 : ExpressionTreeNode& ExpressionTreeNode::operator=(ExpressionTreeNode&& node) {
+     141     2094686 :     if (operation != NULL)
+     142       10793 :         delete operation;
+     143     2094686 :     operation = node.operation;
+     144     2094686 :     children = move(node.children);
+     145     2094686 :     node.operation = NULL;
+     146             :     node.children.clear();
+     147     2094686 :     return *this;
+     148             : }
+     149             : 
+     150     4894397 : const Operation& ExpressionTreeNode::getOperation() const {
+     151     4894397 :     return *operation;
+     152             : }
+     153             : 
+     154     5838400 : const vector<ExpressionTreeNode>& ExpressionTreeNode::getChildren() const {
+     155     5838400 :     return children;
+     156             : }
+     157             : 
+     158       79774 : 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       79774 :     int numTags = examples.size();
+     164      153407 :     for (const ExpressionTreeNode& child : getChildren())
+     165       73633 :         child.assignTags(examples);
+     166       79774 :     if (numTags == examples.size()) {
+     167             :         // All the children matched existing tags, so possibly this node does too.
+     168             :         
+     169      226762 :         for (int i = 0; i < examples.size(); i++) {
+     170      206936 :             const ExpressionTreeNode& example = *examples[i];
+     171      206936 :             bool matches = (getChildren().size() == example.getChildren().size() && getOperation() == example.getOperation());
+     172      232985 :             for (int j = 0; matches && j < getChildren().size(); j++)
+     173       26049 :                 if (getChildren()[j].tag != example.getChildren()[j].tag)
+     174             :                     matches = false;
+     175      206936 :             if (matches) {
+     176       30799 :                 tag = i;
+     177       30799 :                 return;
+     178             :             }
+     179             :         }
+     180             :     }
+     181             :     
+     182             :     // This node does not match any previous node, so assign a new tag.
+     183             :     
+     184       48975 :     tag = examples.size();
+     185       48975 :     examples.push_back(this);
+     186             : }
+     187             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b3e7dd7a62 --- /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:27332185.0 %
Date:2024-06-10 08:19:15Functions: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_traitsIcESaIcEEE55
_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_traitsIcESaIcEEE1119
_ZNK4PLMD6lepton9Operation8Multiply13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1226
_ZN4PLMDL6isZeroERKNS_6lepton18ExpressionTreeNodeE4761
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/Operation.cpp.func.html b/coverage-libs/lepton/Operation.cpp.func.html new file mode 100644 index 0000000000..408e185779 --- /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:27332185.0 %
Date:2024-06-10 08:19:15Functions:535793.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDL6isZeroERKNS_6lepton18ExpressionTreeNodeE4761
_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_traitsIcESaIcEEE55
_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_traitsIcESaIcEEE1119
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/Operation.cpp.gcov.html b/coverage-libs/lepton/Operation.cpp.gcov.html new file mode 100644 index 0000000000..baa2ea51c8 --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.gcov.html @@ -0,0 +1,753 @@ + + + + + + + + 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:27332185.0 %
Date:2024-06-10 08:19:15Functions: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-2019 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        4761 : static bool isZero(const ExpressionTreeNode& node) {
+      74        4761 :     if (node.getOperation().getId() != Operation::CONSTANT)
+      75             :         return false;
+      76        2790 :     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        1119 : ExpressionTreeNode Operation::Variable::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+      92        1119 :     if (variable == name)
+      93         594 :         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          55 : ExpressionTreeNode Operation::Sin::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     215          55 :     if (isZero(childDerivs[0]))
+     216           2 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     217          53 :     return ExpressionTreeNode(new Operation::Multiply(),
+     218         106 :                               ExpressionTreeNode(new Operation::Cos(), children[0]),
+     219          53 :                               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           4 :     return ExpressionTreeNode(new Operation::Subtract(),
+     434           8 :                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[1], step),
+     435           8 :                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[0],
+     436          16 :                                                  ExpressionTreeNode(new Operation::AddConstant(-1), step)));
+     437           4 : }
+     438             : 
+     439           4 : ExpressionTreeNode Operation::Max::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     440           4 :     ExpressionTreeNode step(new Operation::Step(),
+     441           8 :                             ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
+     442           4 :     return ExpressionTreeNode(new Operation::Subtract(),
+     443           8 :                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[0], step),
+     444           8 :                               ExpressionTreeNode(new Operation::Multiply(), childDerivs[1],
+     445          16 :                                                  ExpressionTreeNode(new Operation::AddConstant(-1), step)));
+     446           4 : }
+     447             : 
+     448           3 : ExpressionTreeNode Operation::Abs::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     449           3 :     if (isZero(childDerivs[0]))
+     450           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     451           3 :     ExpressionTreeNode step(new Operation::Step(), children[0]);
+     452           3 :     return ExpressionTreeNode(new Operation::Multiply(),
+     453             :                               childDerivs[0],
+     454           6 :                               ExpressionTreeNode(new Operation::AddConstant(-1),
+     455           9 :                                                  ExpressionTreeNode(new Operation::MultiplyConstant(2), step)));
+     456           3 : }
+     457             : 
+     458           2 : ExpressionTreeNode Operation::Floor::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     459           2 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+     460             : }
+     461             : 
+     462           2 : ExpressionTreeNode Operation::Ceil::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     463           2 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+     464             : }
+     465             : 
+     466          12 : ExpressionTreeNode Operation::Select::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     467             :     vector<ExpressionTreeNode> derivChildren;
+     468          12 :     derivChildren.push_back(children[0]);
+     469          12 :     derivChildren.push_back(childDerivs[1]);
+     470          12 :     derivChildren.push_back(childDerivs[2]);
+     471          24 :     return ExpressionTreeNode(new Operation::Select(), derivChildren);
+     472          12 : }
+     473             : 
+     474             : #define LEPTON_CONST(x) ExpressionTreeNode(new Operation::Constant(x))
+     475             : #define LEPTON_OP1(name,x) ExpressionTreeNode(new Operation::name(),x)
+     476             : #define LEPTON_OP2(name,x,y) ExpressionTreeNode(new Operation::name(),x,y)
+     477             : #define LEPTON_ADD_CONST(x,y) ExpressionTreeNode(new Operation::AddConstant(x),y)
+     478             : 
+     479           2 : ExpressionTreeNode Operation::Acot::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     480             :     return
+     481           2 :       LEPTON_OP2(Multiply,
+     482             :         LEPTON_OP1(Negate,
+     483             :           LEPTON_OP1(Reciprocal,
+     484             :             LEPTON_ADD_CONST(1.0,
+     485             :               LEPTON_OP1(Square,children[0])
+     486             :             )
+     487             :           )
+     488             :         ),
+     489             :         childDerivs[0]
+     490             :       );
+     491             : }
+     492             : 
+     493           2 : ExpressionTreeNode Operation::Asec::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     494             :     return
+     495           2 :       LEPTON_OP2(Multiply,
+     496             :         LEPTON_OP1(Reciprocal,
+     497             :           LEPTON_OP2(Multiply,
+     498             :             LEPTON_OP1(Abs,children[0]),
+     499             :             LEPTON_OP1(Sqrt,
+     500             :               LEPTON_OP2(Subtract,
+     501             :                 LEPTON_OP1(Square,children[0]),
+     502             :                 LEPTON_CONST(1.0)
+     503             :               )
+     504             :             )
+     505             :           )
+     506             :         ),
+     507             :         childDerivs[0]
+     508             :       );
+     509             : }
+     510             : 
+     511           2 : ExpressionTreeNode Operation::Acsc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     512             :     return
+     513           2 :     LEPTON_OP2(Multiply,
+     514             :       LEPTON_OP1(Negate,
+     515             :         LEPTON_OP1(Reciprocal,
+     516             :           LEPTON_OP2(Multiply,
+     517             :             LEPTON_OP1(Abs,children[0]),
+     518             :             LEPTON_OP1(Sqrt,
+     519             :               LEPTON_OP2(Subtract,
+     520             :                 LEPTON_OP1(Square,children[0]),
+     521             :                 LEPTON_CONST(1.0)
+     522             :               )
+     523             :             )
+     524             :           )
+     525             :         )
+     526             :       ),
+     527             :       childDerivs[0]
+     528             :     );
+     529             : }
+     530             : 
+     531           2 : ExpressionTreeNode Operation::Coth::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     532             :     return
+     533           2 :     LEPTON_OP2(Multiply,
+     534             :       LEPTON_OP2(Subtract,
+     535             :         LEPTON_CONST(1.0),
+     536             :         LEPTON_OP1(Square,
+     537             :           LEPTON_OP1(Coth,children[0])
+     538             :         )
+     539             :       ),
+     540             :       childDerivs[0]
+     541             :     );
+     542             : }
+     543             : 
+     544           2 : ExpressionTreeNode Operation::Sech::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     545             :     return
+     546           2 :     LEPTON_OP2(Multiply,
+     547             :       LEPTON_OP1(Negate,
+     548             :         LEPTON_OP2(Multiply,
+     549             :           LEPTON_OP1(Tanh,children[0]),
+     550             :           LEPTON_OP1(Sech,children[0])
+     551             :         )
+     552             :       ),
+     553             :       childDerivs[0]
+     554             :     );
+     555             : }
+     556             : 
+     557           2 : ExpressionTreeNode Operation::Csch::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     558             :     return
+     559           2 :     LEPTON_OP2(Multiply,
+     560             :       LEPTON_OP1(Negate,
+     561             :         LEPTON_OP2(Multiply,
+     562             :           LEPTON_OP1(Coth,children[0]),
+     563             :           LEPTON_OP1(Csch,children[0])
+     564             :         )
+     565             :       ),
+     566             :       childDerivs[0]
+     567             :     );
+     568             : }
+     569             : 
+     570           2 : ExpressionTreeNode Operation::Acosh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     571             :     return
+     572           2 :     LEPTON_OP2(Multiply,
+     573             :       LEPTON_OP1(Reciprocal,
+     574             :         LEPTON_OP1(Sqrt,
+     575             :           LEPTON_OP2(Subtract,
+     576             :             LEPTON_OP1(Square,children[0]),
+     577             :             LEPTON_CONST(1.0)
+     578             :           )
+     579             :         )
+     580             :       ),
+     581             :       childDerivs[0]
+     582             :     );
+     583             : }
+     584             : 
+     585           2 : ExpressionTreeNode Operation::Atanh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     586             :     return
+     587           2 :     LEPTON_OP2(Multiply,
+     588             :       LEPTON_OP1(Reciprocal,
+     589             :         LEPTON_OP2(Subtract,
+     590             :           LEPTON_CONST(1.0),
+     591             :           LEPTON_OP1(Square,children[0])
+     592             :         )
+     593             :       ),
+     594             :       childDerivs[0]
+     595             :     );
+     596             : }
+     597             : 
+     598           2 : ExpressionTreeNode Operation::Asinh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     599             :     return
+     600           2 :     LEPTON_OP2(Multiply,
+     601             :       LEPTON_OP1(Reciprocal,
+     602             :         LEPTON_OP1(Sqrt,
+     603             :           LEPTON_ADD_CONST(1.0,
+     604             :             LEPTON_OP1(Square,children[0])
+     605             :           )
+     606             :         )
+     607             :       ),
+     608             :       childDerivs[0]
+     609             :     );
+     610             : }
+     611             : 
+     612           2 : ExpressionTreeNode Operation::Acoth::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     613             :     return
+     614           2 :     LEPTON_OP2(Multiply,
+     615             :       LEPTON_OP1(Reciprocal,
+     616             :         LEPTON_OP2(Subtract,
+     617             :           LEPTON_CONST(1.0),
+     618             :           LEPTON_OP1(Square,children[0])
+     619             :         )
+     620             :       ),
+     621             :       childDerivs[0]
+     622             :     );
+     623             : }
+     624             : 
+     625           2 : ExpressionTreeNode Operation::Asech::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     626             :     return
+     627           2 :     LEPTON_OP2(Multiply,
+     628             :       LEPTON_OP1(Negate,
+     629             :         LEPTON_OP1(Reciprocal,
+     630             :           LEPTON_OP2(Multiply,
+     631             :             children[0],
+     632             :             LEPTON_OP2(Multiply,
+     633             :               LEPTON_ADD_CONST(1.0,
+     634             :                 children[0]
+     635             :               ),
+     636             :               LEPTON_OP1(Sqrt,
+     637             :                 LEPTON_OP2(Divide,
+     638             :                   LEPTON_OP2(Subtract,
+     639             :                     LEPTON_CONST(1.0),
+     640             :                     children[0]
+     641             :                   ),
+     642             :                   LEPTON_ADD_CONST(1.0,
+     643             :                     children[0]
+     644             :                   )
+     645             :                 )
+     646             :               )
+     647             :             )
+     648             :           )
+     649             :         )
+     650             :       ),
+     651             :       childDerivs[0]
+     652             :     );
+     653             : }
+     654             : 
+     655           2 : ExpressionTreeNode Operation::Acsch::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     656             :     return
+     657           2 :     LEPTON_OP2(Multiply,
+     658             :       LEPTON_OP1(Negate,
+     659             :         LEPTON_OP1(Reciprocal,
+     660             :           LEPTON_OP2(Multiply,
+     661             :             LEPTON_OP1(Square,children[0]),
+     662             :             LEPTON_OP1(Sqrt,
+     663             :               LEPTON_ADD_CONST(1.0,
+     664             :                 LEPTON_OP1(Reciprocal,
+     665             :                   LEPTON_OP1(Square,children[0])
+     666             :                 )
+     667             :               )
+     668             :             )
+     669             :           )
+     670             :         )
+     671             :       ),
+     672             :       childDerivs[0]
+     673             :     );
+     674             : }
+     675             : 
+     676             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..80c1eb248c --- /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-06-10 08:19:15Functions: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
_ZNK4PLMD6lepton9Operation6Select7getNameB5cxx11Ev16
_ZNK4PLMD6lepton9Operation4Step7getNameB5cxx11Ev17
_ZNK4PLMD6lepton9Operation3Abs7getNameB5cxx11Ev18
_ZNK4PLMD6lepton9Operation3Erf15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Acot15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Acsc15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Asec15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Ceil15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Erfc15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Acosh15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Acoth15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Acsch15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Asech15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Asinh15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Atanh15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Floor15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Acos15getNumArgumentsEv20
_ZNK4PLMD6lepton9Operation4Asin15getNumArgumentsEv20
_ZNK4PLMD6lepton9Operation4Atan15getNumArgumentsEv20
_ZNK4PLMD6lepton9Operation8Variable8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE20
_ZNK4PLMD6lepton9Operation4Cube7getNameB5cxx11Ev23
_ZNK4PLMD6lepton9Operation3Exp7getNameB5cxx11Ev28
_ZNK4PLMD6lepton9Operation3Erf5cloneEv30
_ZNK4PLMD6lepton9Operation4Acot5cloneEv30
_ZNK4PLMD6lepton9Operation4Acsc5cloneEv30
_ZNK4PLMD6lepton9Operation4Asec5cloneEv30
_ZNK4PLMD6lepton9Operation4Ceil5cloneEv30
_ZNK4PLMD6lepton9Operation4Erfc5cloneEv30
_ZNK4PLMD6lepton9Operation5Acosh5cloneEv30
_ZNK4PLMD6lepton9Operation5Acoth5cloneEv30
_ZNK4PLMD6lepton9Operation5Acsch5cloneEv30
_ZNK4PLMD6lepton9Operation5Asech5cloneEv30
_ZNK4PLMD6lepton9Operation5Asinh5cloneEv30
_ZNK4PLMD6lepton9Operation5Atanh5cloneEv30
_ZNK4PLMD6lepton9Operation5Floor5cloneEv30
_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
_ZNK4PLMD6lepton9Operation13PowerConstant15isInfixOperatorEv74
_ZNK4PLMD6lepton9Operation6Negate7getNameB5cxx11Ev74
_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
_ZNK4PLMD6lepton9Operation6Select15getNumArgumentsEv188
_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
_ZNK4PLMD6lepton9Operation8Constant7getNameB5cxx11Ev227
_ZNK4PLMD6lepton9Operation4Coth5getIdEv228
_ZNK4PLMD6lepton9Operation4Tanh5getIdEv228
_ZNK4PLMD6lepton9Operation3Csc5cloneEv240
_ZNK4PLMD6lepton9Operation4Coth5cloneEv242
_ZNK4PLMD6lepton9Operation4Tanh5cloneEv242
_ZNK4PLMD6lepton9Operation4Cube15getNumArgumentsEv256
_ZNK4PLMD6lepton9Operation6Select5cloneEv272
_ZNK4PLMD6lepton9Operation4Tanh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE303
_ZNK4PLMD6lepton9Operation8Nandelta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE303
_ZNK4PLMD6lepton9Operation3Exp15getNumArgumentsEv308
_ZNK4PLMD6lepton9Operation6Select5getIdEv344
_ZNK4PLMD6lepton9Operation4Step15getNumArgumentsEv373
_ZNK4PLMD6lepton9Operation6Square7getNameB5cxx11Ev374
_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
_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
_ZNK4PLMD6lepton9Operation3Sin7getNameB5cxx11Ev733
_ZNK4PLMD6lepton9Operation11AddConstant7getNameB5cxx11Ev796
_ZNK4PLMD6lepton9Operation4Sqrt15getNumArgumentsEv797
_ZNK4PLMD6lepton9Operation10Reciprocal15getNumArgumentsEv834
_ZNK4PLMD6lepton9Operation8Multiply15isInfixOperatorEv838
_ZNK4PLMD6lepton9Operation8Multiply7getNameB5cxx11Ev838
_ZNK4PLMD6lepton9Operation3Abs5getIdEv846
_ZNK4PLMD6lepton9Operation3Exp5cloneEv924
_ZNK4PLMD6lepton9Operation3Abs5cloneEv976
_ZNK4PLMD6lepton9Operation4Cube5cloneEv1055
_ZNK4PLMD6lepton9Operation5Delta5cloneEv1107
_ZNK4PLMD6lepton9Operation4Sqrt8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1111
_ZNK4PLMD6lepton9Operation3Cos7getNameB5cxx11Ev1117
_ZNK4PLMD6lepton9Operation5Power15getNumArgumentsEv1168
_ZNK4PLMD6lepton9Operation8Subtract8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1284
_ZNK4PLMD6lepton9Operation4Cube5getIdEv1405
_ZNK4PLMD6lepton9Operation16MultiplyConstant7getNameB5cxx11Ev1412
_ZNK4PLMD6lepton9Operation8Multiply8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1441
_ZNK4PLMD6lepton9Operation3Exp5getIdEv1495
_ZNK4PLMD6lepton9Operation6Select8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1624
_ZNK4PLMD6lepton9Operation6Negate8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1641
_ZNK4PLMD6lepton9Operation6Divide15getNumArgumentsEv1721
_ZNK4PLMD6lepton9Operation3Log5getIdEv1832
_ZNK4PLMD6lepton9Operation13PowerConstant5getIdEv2047
_ZNK4PLMD6lepton9Operation10Reciprocal8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2121
_ZNK4PLMD6lepton9Operation13PowerConstant5cloneEv2229
_ZNK4PLMD6lepton9Operation6Square15getNumArgumentsEv2333
_ZNK4PLMD6lepton9Operation6Negate15getNumArgumentsEv2360
_ZNK4PLMD6lepton9Operation5Delta5getIdEv2395
_ZNK4PLMD6lepton9Operation16MultiplyConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2626
_ZNK4PLMD6lepton9Operation4Step5cloneEv2628
_ZNK4PLMD6lepton9Operation11AddConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2907
_ZNK4PLMD6lepton9Operation6Square8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3155
_ZNK4PLMD6lepton9Operation3Sin15getNumArgumentsEv3276
_ZNK4PLMD6lepton9Operation11AddConstant15getNumArgumentsEv3513
_ZNK4PLMD6lepton9Operation3Add11isSymmetricEv3592
_ZNK4PLMD6lepton9Operation3Log5cloneEv3637
_ZNK4PLMD6lepton9Operation10Reciprocal5getIdEv4059
_ZNK4PLMD6lepton9Operation4Step5getIdEv4303
_ZNK4PLMD6lepton9Operation10Reciprocal5cloneEv4372
_ZNK4PLMD6lepton9Operation5Power5getIdEv4509
_ZNK4PLMD6lepton9Operation4Sqrt5getIdEv4653
_ZNK4PLMD6lepton9Operation4Sqrt5cloneEv5491
_ZNK4PLMD6lepton9Operation6Divide5getIdEv5521
_ZNK4PLMD6lepton9Operation3Cos15getNumArgumentsEv5825
_ZNK4PLMD6lepton9Operation8Multiply11isSymmetricEv6290
_ZNK4PLMD6lepton9Operation8Subtract15getNumArgumentsEv6688
_ZNK4PLMD6lepton9Operation3Add15getNumArgumentsEv7429
_ZNK4PLMD6lepton9Operation8Variable7getNameB5cxx11Ev9018
_ZNK4PLMD6lepton9Operation8Variable15getNumArgumentsEv9120
_ZNK4PLMD6lepton9Operation5Power5cloneEv9169
_ZNK4PLMD6lepton9Operation11AddConstantneERKS1_10085
_ZNK4PLMD6lepton9Operation16MultiplyConstant15getNumArgumentsEv11256
_ZNK4PLMD6lepton9Operation6Divide5cloneEv11742
_ZNK4PLMD6lepton9Operation11AddConstant5getIdEv12010
_ZNK4PLMD6lepton9Operation6Negate5getIdEv12926
_ZNK4PLMD6lepton9Operation15isInfixOperatorEv15910
_ZNK4PLMD6lepton9Operation8Multiply15getNumArgumentsEv18860
_ZNK4PLMD6lepton9Operation6Square5getIdEv19443
_ZNK4PLMD6lepton9Operation6Square5cloneEv20360
_ZNK4PLMD6lepton9Operation6Negate5cloneEv23206
_ZNK4PLMD6lepton9Operation8Subtract5getIdEv25483
_ZNK4PLMD6lepton9Operation8Constant5getIdEv27150
_ZNK4PLMD6lepton9Operation8Variable5getIdEv30572
_ZNK4PLMD6lepton9Operation8ConstantneERKS1_31324
_ZNK4PLMD6lepton9Operation8Subtract5cloneEv31562
_ZNK4PLMD6lepton9Operation16MultiplyConstantneERKS1_35217
_ZNK4PLMD6lepton9Operation11AddConstant5cloneEv37351
_ZNK4PLMD6lepton9Operation3Add5getIdEv40244
_ZNK4PLMD6lepton9Operation3Add5cloneEv41274
_ZNK4PLMD6lepton9Operation8VariableneERKS1_45647
_ZNK4PLMD6lepton9Operation3Sin5getIdEv49089
_ZNK4PLMD6lepton9Operation11isSymmetricEv51753
_ZNK4PLMD6lepton9Operation3Sin5cloneEv52623
_ZNK4PLMD6lepton9Operation16MultiplyConstant5getIdEv54125
_ZNK4PLMD6lepton9Operation16MultiplyConstant5cloneEv55327
_ZNK4PLMD6lepton9Operation3Cos5getIdEv64840
_ZNK4PLMD6lepton9Operation3Cos5cloneEv76519
_ZNK4PLMD6lepton9Operation8Multiply5getIdEv83422
_ZNK4PLMD6lepton9OperationneERKS1_101645
_ZNK4PLMD6lepton9OperationeqERKS1_105248
_ZNK4PLMD6lepton9Operation8Multiply5cloneEv115973
_ZNK4PLMD6lepton9Operation8Variable5cloneEv240337
_ZNK4PLMD6lepton9Operation8Constant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2018722
_ZNK4PLMD6lepton9Operation8Constant15getNumArgumentsEv2028986
_ZNK4PLMD6lepton9Operation8Constant5cloneEv2145781
_ZNK4PLMD6lepton9Operation13PowerConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE10691410
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/Operation.h.func.html b/coverage-libs/lepton/Operation.h.func.html new file mode 100644 index 0000000000..3ab5d54374 --- /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-06-10 08:19:15Functions: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
_ZNK4PLMD6lepton9Operation11AddConstant15getNumArgumentsEv3513
_ZNK4PLMD6lepton9Operation11AddConstant5cloneEv37351
_ZNK4PLMD6lepton9Operation11AddConstant5getIdEv12010
_ZNK4PLMD6lepton9Operation11AddConstant7getNameB5cxx11Ev796
_ZNK4PLMD6lepton9Operation11AddConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2907
_ZNK4PLMD6lepton9Operation11AddConstantneERKS1_10085
_ZNK4PLMD6lepton9Operation11isSymmetricEv51753
_ZNK4PLMD6lepton9Operation13PowerConstant15getNumArgumentsEv454
_ZNK4PLMD6lepton9Operation13PowerConstant15isInfixOperatorEv74
_ZNK4PLMD6lepton9Operation13PowerConstant5cloneEv2229
_ZNK4PLMD6lepton9Operation13PowerConstant5getIdEv2047
_ZNK4PLMD6lepton9Operation13PowerConstant7getNameB5cxx11Ev37
_ZNK4PLMD6lepton9Operation13PowerConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE10691410
_ZNK4PLMD6lepton9Operation13PowerConstantneERKS1_572
_ZNK4PLMD6lepton9Operation15isInfixOperatorEv15910
_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
_ZNK4PLMD6lepton9Operation3Cos15getNumArgumentsEv5825
_ZNK4PLMD6lepton9Operation3Cos5cloneEv76519
_ZNK4PLMD6lepton9Operation3Cos5getIdEv64840
_ZNK4PLMD6lepton9Operation3Cos7getNameB5cxx11Ev1117
_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
_ZNK4PLMD6lepton9Operation3Sin15getNumArgumentsEv3276
_ZNK4PLMD6lepton9Operation3Sin5cloneEv52623
_ZNK4PLMD6lepton9Operation3Sin5getIdEv49089
_ZNK4PLMD6lepton9Operation3Sin7getNameB5cxx11Ev733
_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
_ZNK4PLMD6lepton9Operation4Step15getNumArgumentsEv373
_ZNK4PLMD6lepton9Operation4Step5cloneEv2628
_ZNK4PLMD6lepton9Operation4Step5getIdEv4303
_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
_ZNK4PLMD6lepton9Operation6Negate15getNumArgumentsEv2360
_ZNK4PLMD6lepton9Operation6Negate5cloneEv23206
_ZNK4PLMD6lepton9Operation6Negate5getIdEv12926
_ZNK4PLMD6lepton9Operation6Negate7getNameB5cxx11Ev74
_ZNK4PLMD6lepton9Operation6Negate8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1641
_ZNK4PLMD6lepton9Operation6Select15getNumArgumentsEv188
_ZNK4PLMD6lepton9Operation6Select5cloneEv272
_ZNK4PLMD6lepton9Operation6Select5getIdEv344
_ZNK4PLMD6lepton9Operation6Select7getNameB5cxx11Ev16
_ZNK4PLMD6lepton9Operation6Select8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1624
_ZNK4PLMD6lepton9Operation6Square15getNumArgumentsEv2333
_ZNK4PLMD6lepton9Operation6Square5cloneEv20360
_ZNK4PLMD6lepton9Operation6Square5getIdEv19443
_ZNK4PLMD6lepton9Operation6Square7getNameB5cxx11Ev374
_ZNK4PLMD6lepton9Operation6Square8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3155
_ZNK4PLMD6lepton9Operation8Constant15getNumArgumentsEv2028986
_ZNK4PLMD6lepton9Operation8Constant5cloneEv2145781
_ZNK4PLMD6lepton9Operation8Constant5getIdEv27150
_ZNK4PLMD6lepton9Operation8Constant7getNameB5cxx11Ev227
_ZNK4PLMD6lepton9Operation8Constant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2018722
_ZNK4PLMD6lepton9Operation8ConstantneERKS1_31324
_ZNK4PLMD6lepton9Operation8Multiply11isSymmetricEv6290
_ZNK4PLMD6lepton9Operation8Multiply15getNumArgumentsEv18860
_ZNK4PLMD6lepton9Operation8Multiply15isInfixOperatorEv838
_ZNK4PLMD6lepton9Operation8Multiply5cloneEv115973
_ZNK4PLMD6lepton9Operation8Multiply5getIdEv83422
_ZNK4PLMD6lepton9Operation8Multiply7getNameB5cxx11Ev838
_ZNK4PLMD6lepton9Operation8Multiply8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1441
_ZNK4PLMD6lepton9Operation8Nandelta15getNumArgumentsEv50
_ZNK4PLMD6lepton9Operation8Nandelta5cloneEv90
_ZNK4PLMD6lepton9Operation8Nandelta5getIdEv120
_ZNK4PLMD6lepton9Operation8Nandelta7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation8Nandelta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE303
_ZNK4PLMD6lepton9Operation8Subtract15getNumArgumentsEv6688
_ZNK4PLMD6lepton9Operation8Subtract15isInfixOperatorEv431
_ZNK4PLMD6lepton9Operation8Subtract5cloneEv31562
_ZNK4PLMD6lepton9Operation8Subtract5getIdEv25483
_ZNK4PLMD6lepton9Operation8Subtract7getNameB5cxx11Ev431
_ZNK4PLMD6lepton9Operation8Subtract8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1284
_ZNK4PLMD6lepton9Operation8Variable15getNumArgumentsEv9120
_ZNK4PLMD6lepton9Operation8Variable5cloneEv240337
_ZNK4PLMD6lepton9Operation8Variable5getIdEv30572
_ZNK4PLMD6lepton9Operation8Variable7getNameB5cxx11Ev9018
_ZNK4PLMD6lepton9Operation8Variable8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE20
_ZNK4PLMD6lepton9Operation8VariableneERKS1_45647
_ZNK4PLMD6lepton9OperationeqERKS1_105248
_ZNK4PLMD6lepton9OperationneERKS1_101645
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/Operation.h.gcov.html b/coverage-libs/lepton/Operation.h.gcov.html new file mode 100644 index 0000000000..d8eaa75d7d --- /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-06-10 08:19:15Functions: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       15910 :     virtual bool isInfixOperator() const {
+     139       15910 :         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       51753 :     virtual bool isSymmetric() const {
+     146       51753 :         return false;
+     147             :     }
+     148      101645 :     virtual bool operator!=(const Operation& op) const {
+     149      101645 :         return op.getId() != getId();
+     150             :     }
+     151      105248 :     virtual bool operator==(const Operation& op) const {
+     152      105248 :         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     2017858 :     Constant(double value) : value(value) {
+     213             :     }
+     214         227 :     std::string getName() const {
+     215         227 :         std::stringstream name;
+     216         227 :         name << value;
+     217         227 :         return name.str();
+     218         227 :     }
+     219       27150 :     Id getId() const {
+     220       27150 :         return CONSTANT;
+     221             :     }
+     222     2028986 :     int getNumArguments() const {
+     223     2028986 :         return 0;
+     224             :     }
+     225     2145781 :     Operation* clone() const {
+     226     2145781 :         return new Constant(value);
+     227             :     }
+     228     2018722 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     229     2018722 :         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        6447 :         return value;
+     234             :     }
+     235       31324 :     bool operator!=(const Operation& op) const {
+     236       31324 :         const Constant* o = dynamic_cast<const Constant*>(&op);
+     237       31324 :         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      243625 :     Variable(const std::string& name) : name(name) {
+     246      243625 :     }
+     247        9018 :     std::string getName() const {
+     248        9018 :         return name;
+     249             :     }
+     250       30572 :     Id getId() const {
+     251       30572 :         return VARIABLE;
+     252             :     }
+     253        9120 :     int getNumArguments() const {
+     254        9120 :         return 0;
+     255             :     }
+     256      240337 :     Operation* clone() const {
+     257      480674 :         return new Variable(name);
+     258             :     }
+     259          20 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     260          20 :         std::map<std::string, double>::const_iterator iter = variables.find(name);
+     261          20 :         if (iter == variables.end())
+     262          24 :             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       45647 :     bool operator!=(const Operation& op) const {
+     267       45647 :         const Variable* o = dynamic_cast<const Variable*>(&op);
+     268       45647 :         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        1137 :     Subtract() {
+     355             :     }
+     356         431 :     std::string getName() const {
+     357         431 :         return "-";
+     358             :     }
+     359       25483 :     Id getId() const {
+     360       25483 :         return SUBTRACT;
+     361             :     }
+     362        6688 :     int getNumArguments() const {
+     363        6688 :         return 2;
+     364             :     }
+     365       31562 :     Operation* clone() const {
+     366       31562 :         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        4727 :     Multiply() {
+     380             :     }
+     381         838 :     std::string getName() const {
+     382         838 :         return "*";
+     383             :     }
+     384       83422 :     Id getId() const {
+     385       83422 :         return MULTIPLY;
+     386             :     }
+     387       18860 :     int getNumArguments() const {
+     388       18860 :         return 2;
+     389             :     }
+     390      115973 :     Operation* clone() const {
+     391      115973 :         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         361 :     Negate() {
+     458             :     }
+     459          74 :     std::string getName() const {
+     460          74 :         return "-";
+     461             :     }
+     462       12926 :     Id getId() const {
+     463       12926 :         return NEGATE;
+     464             :     }
+     465        2360 :     int getNumArguments() const {
+     466        2360 :         return 1;
+     467             :     }
+     468       23206 :     Operation* clone() const {
+     469       23206 :         return new Negate();
+     470             :     }
+     471        1641 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     472        1641 :         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         313 :     Sin() {
+     546             :     }
+     547         733 :     std::string getName() const {
+     548         733 :         return "sin";
+     549             :     }
+     550       49089 :     Id getId() const {
+     551       49089 :         return SIN;
+     552             :     }
+     553        3276 :     int getNumArguments() const {
+     554        3276 :         return 1;
+     555             :     }
+     556       52623 :     Operation* clone() const {
+     557       52623 :         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        1318 :     Cos() {
+     568             :     }
+     569        1117 :     std::string getName() const {
+     570        1117 :         return "cos";
+     571             :     }
+     572       64840 :     Id getId() const {
+     573       64840 :         return COS;
+     574             :     }
+     575        5825 :     int getNumArguments() const {
+     576        5825 :         return 1;
+     577             :     }
+     578       76519 :     Operation* clone() const {
+     579       76519 :         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        4303 :     Id getId() const {
+     877        4303 :         return STEP;
+     878             :     }
+     879         373 :     int getNumArguments() const {
+     880         373 :         return 1;
+     881             :     }
+     882        2628 :     Operation* clone() const {
+     883        2628 :         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         542 :     AddConstant(double value) : value(value) {
+    1004             :     }
+    1005         796 :     std::string getName() const {
+    1006         796 :         std::stringstream name;
+    1007         796 :         name << value << "+";
+    1008         796 :         return name.str();
+    1009         796 :     }
+    1010       12010 :     Id getId() const {
+    1011       12010 :         return ADD_CONSTANT;
+    1012             :     }
+    1013        3513 :     int getNumArguments() const {
+    1014        3513 :         return 1;
+    1015             :     }
+    1016       37351 :     Operation* clone() const {
+    1017       37351 :         return new AddConstant(value);
+    1018             :     }
+    1019        2907 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1020        2907 :         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         850 :         return value;
+    1025             :     }
+    1026       10085 :     bool operator!=(const Operation& op) const {
+    1027       10085 :         const AddConstant* o = dynamic_cast<const AddConstant*>(&op);
+    1028       10085 :         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          36 :     Select() {
+    1242             :     }
+    1243          16 :     std::string getName() const {
+    1244          16 :         return "select";
+    1245             :     }
+    1246         344 :     Id getId() const {
+    1247         344 :         return SELECT;
+    1248             :     }
+    1249         188 :     int getNumArguments() const {
+    1250         188 :         return 3;
+    1251             :     }
+    1252         272 :     Operation* clone() const {
+    1253         272 :         return new Select();
+    1254             :     }
+    1255        1624 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1256        1624 :         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.15
+
+ + + 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 0000000000..1e308af3e9 --- /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-06-10 08:19:15Functions: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_traitsIcESaIcEEE596
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE1086
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE1110
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv1134
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv1134
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE3327
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE5816
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE9929
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE19862
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE22795
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE25885
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE29817
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008067
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2012017
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2012701
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2013723
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.func.html b/coverage-libs/lepton/ParsedExpression.cpp.func.html new file mode 100644 index 0000000000..b2d4b1b5ee --- /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-06-10 08:19:15Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE29817
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE5816
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE3327
_ZN4PLMD6lepton16ParsedExpression19renameNodeVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_St4lessISB_ESaISt4pairIKSB_SB_EEE0
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE19862
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE25885
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE22795
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2012701
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2012017
_ZN4PLMD6lepton16ParsedExpressionC2Ev0
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE1086
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE9929
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2013723
_ZNK4PLMD6lepton16ParsedExpression13createProgramEv0
_ZNK4PLMD6lepton16ParsedExpression13differentiateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE596
_ZNK4PLMD6lepton16ParsedExpression15renameVariablesERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEE0
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv1134
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008067
_ZNK4PLMD6lepton16ParsedExpression8evaluateEv0
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE1110
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv1134
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.gcov.html b/coverage-libs/lepton/ParsedExpression.cpp.gcov.html new file mode 100644 index 0000000000..8d687816e6 --- /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-06-10 08:19:15Functions: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     2012017 : ParsedExpression::ParsedExpression(const ExpressionTreeNode& rootNode) : rootNode(rootNode) {
+      79     2012017 : }
+      80             : 
+      81     2013723 : const ExpressionTreeNode& ParsedExpression::getRootNode() const {
+      82     2013723 :     if (&rootNode.getOperation() == NULL)
+      83           0 :         throw Exception("Illegal call to an initialized ParsedExpression");
+      84     2013723 :     return rootNode;
+      85             : }
+      86             : 
+      87           0 : double ParsedExpression::evaluate() const {
+      88           0 :     return evaluate(getRootNode(), map<string, double>());
+      89             : }
+      90             : 
+      91     2008067 : double ParsedExpression::evaluate(const map<string, double>& variables) const {
+      92     2008067 :     return evaluate(getRootNode(), variables);
+      93             : }
+      94             : 
+      95     2012701 : double ParsedExpression::evaluate(const ExpressionTreeNode& node, const map<string, double>& variables) {
+      96     2012701 :     int numArgs = (int) node.getChildren().size();
+      97     4024777 :     vector<double> args(max(numArgs, 1));
+      98     2013817 :     for (int i = 0; i < numArgs; i++)
+      99        1116 :         args[i] = evaluate(node.getChildren()[i], variables);
+     100     4025390 :     return node.getOperation().evaluate(&args[0], variables);
+     101             : }
+     102             : 
+     103        1134 : ParsedExpression ParsedExpression::optimize() const {
+     104        1134 :     ExpressionTreeNode result = getRootNode();
+     105             :     vector<const ExpressionTreeNode*> examples;
+     106        1134 :     result.assignTags(examples);
+     107             :     map<int, ExpressionTreeNode> nodeCache;
+     108        1134 :     result = precalculateConstantSubexpressions(result, nodeCache);
+     109             :     while (true) {
+     110             :         examples.clear();
+     111        1134 :         result.assignTags(examples);
+     112             :         nodeCache.clear();
+     113        1134 :         ExpressionTreeNode simplified = substituteSimplerExpression(result, nodeCache);
+     114        1134 :         if (simplified == result)
+     115             :             break;
+     116           0 :         result = simplified;
+     117        1134 :     }
+     118        2268 :     return ParsedExpression(result);
+     119        1134 : }
+     120             : 
+     121        1110 : ParsedExpression ParsedExpression::optimize(const map<string, double>& variables) const {
+     122        1110 :     ExpressionTreeNode result = preevaluateVariables(getRootNode(), variables);
+     123             :     vector<const ExpressionTreeNode*> examples;
+     124        1110 :     result.assignTags(examples);
+     125             :     map<int, ExpressionTreeNode> nodeCache;
+     126        1110 :     result = precalculateConstantSubexpressions(result, nodeCache);
+     127             :     while (true) {
+     128             :         examples.clear();
+     129        2167 :         result.assignTags(examples);
+     130             :         nodeCache.clear();
+     131        2167 :         ExpressionTreeNode simplified = substituteSimplerExpression(result, nodeCache);
+     132        2167 :         if (simplified == result)
+     133             :             break;
+     134        1057 :         result = simplified;
+     135        2167 :     }
+     136        2220 :     return ParsedExpression(result);
+     137        1110 : }
+     138             : 
+     139       19862 : ExpressionTreeNode ParsedExpression::preevaluateVariables(const ExpressionTreeNode& node, const map<string, double>& variables) {
+     140       19862 :     if (node.getOperation().getId() == Operation::VARIABLE) {
+     141        3872 :         const Operation::Variable& var = dynamic_cast<const Operation::Variable&>(node.getOperation());
+     142        7744 :         map<string, double>::const_iterator iter = variables.find(var.getName());
+     143        3872 :         if (iter == variables.end())
+     144        3466 :             return node;
+     145         406 :         return ExpressionTreeNode(new Operation::Constant(iter->second));
+     146             :     }
+     147       15990 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     148       34742 :     for (int i = 0; i < (int) children.size(); i++)
+     149       18752 :         children[i] = preevaluateVariables(node.getChildren()[i], variables);
+     150       15990 :     return ExpressionTreeNode(node.getOperation().clone(), children);
+     151       15990 : }
+     152             : 
+     153       22795 : ExpressionTreeNode ParsedExpression::precalculateConstantSubexpressions(const ExpressionTreeNode& node, map<int, ExpressionTreeNode>& nodeCache) {
+     154       22795 :     auto cached = nodeCache.find(node.tag);
+     155       22795 :     if (cached != nodeCache.end())
+     156        4736 :         return cached->second;
+     157       18059 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     158       38610 :     for (int i = 0; i < (int) children.size(); i++)
+     159       20551 :         children[i] = precalculateConstantSubexpressions(node.getChildren()[i], nodeCache);
+     160       18059 :     ExpressionTreeNode result = ExpressionTreeNode(node.getOperation().clone(), children);
+     161       18059 :     if (node.getOperation().getId() == Operation::VARIABLE || node.getOperation().getId() == Operation::CUSTOM) {
+     162        2322 :         nodeCache[node.tag] = result;
+     163        2322 :         return result;
+     164             :     }
+     165       18388 :     for (int i = 0; i < (int) children.size(); i++)
+     166       14870 :         if (children[i].getOperation().getId() != Operation::CONSTANT) {
+     167       12219 :             nodeCache[node.tag] = result;
+     168       12219 :             return result;
+     169             :         }
+     170        3518 :     result = ExpressionTreeNode(new Operation::Constant(evaluate(result, map<string, double>())));
+     171        3518 :     nodeCache[node.tag] = result;
+     172        3518 :     return result;
+     173       18059 : }
+     174             : 
+     175       25885 : ExpressionTreeNode ParsedExpression::substituteSimplerExpression(const ExpressionTreeNode& node, map<int, ExpressionTreeNode>& nodeCache) {
+     176       25885 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     177       55734 :     for (int i = 0; i < (int) children.size(); i++) {
+     178       29849 :         const ExpressionTreeNode& child = node.getChildren()[i];
+     179       29849 :         auto cached = nodeCache.find(child.tag);
+     180       29849 :         if (cached == nodeCache.end()) {
+     181       22584 :             children[i] = substituteSimplerExpression(child, nodeCache);
+     182       22584 :             nodeCache[child.tag] = children[i];
+     183             :         }
+     184             :         else
+     185        7265 :             children[i] = cached->second;
+     186             :     }
+     187             :     
+     188             :     // Collect some info on constant expressions in children
+     189       25885 :     bool first_const = children.size() > 0 && isConstant(children[0]); // is first child constant?
+     190       25885 :     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       25885 :     if (first_const)
+     193        1723 :         first = getConstantValue(children[0]);
+     194       25885 :     if (second_const)
+     195        1604 :         second = getConstantValue(children[1]);
+     196             : 
+     197       25885 :     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        1661 :             if (children[0] == children[1])
+     223           2 :                 return ExpressionTreeNode(new Operation::Constant(0.0)); // Subtracting anything from itself is 0
+     224        1659 :             if (first_const) {
+     225          92 :                 if (first == 0.0) // Subtract from 0
+     226           8 :                     return ExpressionTreeNode(new Operation::Negate(), children[1]);
+     227             :             }
+     228        1651 :             if (second_const) {
+     229         147 :                 if (second == 0.0) { // Subtract 0
+     230           9 :                     return children[0];
+     231             :                 } else { // Subtract a constant
+     232         138 :                     return ExpressionTreeNode(new Operation::AddConstant(-second), children[0]);
+     233             :                 }
+     234             :             }
+     235        1504 :             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        5436 :         case Operation::MULTIPLY:
+     240             :         {   
+     241        5436 :             if ((first_const && first == 0.0) || (second_const && second == 0.0)) // Multiply by 0
+     242         190 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     243        5246 :             if (first_const && first == 1.0) // Multiply by 1
+     244          26 :                 return children[1];
+     245        5220 :             if (second_const && second == 1.0) // Multiply by 1
+     246         488 :                 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         648 :             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         638 :             if (first_const) // Negate a constant
+     335           0 :                 return ExpressionTreeNode(new Operation::Constant(-first));
+     336         638 :             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       21965 :     return ExpressionTreeNode(node.getOperation().clone(), children);
+     369       25885 : }
+     370             : 
+     371         596 : ParsedExpression ParsedExpression::differentiate(const string& variable) const {
+     372             :     vector<const ExpressionTreeNode*> examples;
+     373         596 :     getRootNode().assignTags(examples);
+     374             :     map<int, ExpressionTreeNode> nodeCache;
+     375        1192 :     return differentiate(getRootNode(), variable, nodeCache);
+     376             : }
+     377             : 
+     378        5816 : ExpressionTreeNode ParsedExpression::differentiate(const ExpressionTreeNode& node, const string& variable, map<int, ExpressionTreeNode>& nodeCache) {
+     379        5816 :     auto cached = nodeCache.find(node.tag);
+     380        5816 :     if (cached != nodeCache.end())
+     381         785 :         return cached->second;
+     382        5031 :     vector<ExpressionTreeNode> childDerivs(node.getChildren().size());
+     383       10251 :     for (int i = 0; i < (int) childDerivs.size(); i++)
+     384        5220 :         childDerivs[i] = differentiate(node.getChildren()[i], variable, nodeCache);
+     385        5031 :     ExpressionTreeNode result = node.getOperation().differentiate(node.getChildren(), childDerivs, variable);
+     386        5031 :     nodeCache[node.tag] = result;
+     387        5031 :     return result;
+     388        5031 : }
+     389             : 
+     390       29817 : bool ParsedExpression::isConstant(const ExpressionTreeNode& node) {
+     391       29817 :     return (node.getOperation().getId() == Operation::CONSTANT);
+     392             : }
+     393             : 
+     394        3327 : double ParsedExpression::getConstantValue(const ExpressionTreeNode& node) {
+     395        3327 :     if (node.getOperation().getId() != Operation::CONSTANT) {
+     396           0 :         throw Exception("getConstantValue called on a non-constant ExpressionNode");
+     397             :     }
+     398        3327 :     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        1134 : CompiledExpression ParsedExpression::createCompiledExpression() const {
+     406        1134 :     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        9929 : ostream& lepton::operator<<(ostream& out, const ExpressionTreeNode& node) {
+     426        9929 :     if (node.getOperation().isInfixOperator() && node.getChildren().size() == 2) {
+     427        5811 :         out << "(" << node.getChildren()[0] << ")" << node.getOperation().getName() << "(" << node.getChildren()[1] << ")";
+     428             :     }
+     429        7992 :     else if (node.getOperation().isInfixOperator() && node.getChildren().size() == 1) {
+     430          74 :         out << "(" << node.getChildren()[0] << ")" << node.getOperation().getName();
+     431             :     }
+     432             :     else {
+     433        7955 :         out << node.getOperation().getName();
+     434        7955 :         if (node.getChildren().size() > 0) {
+     435        4884 :             out << "(";
+     436        9816 :             for (int i = 0; i < (int) node.getChildren().size(); i++) {
+     437        4932 :                 if (i > 0)
+     438          48 :                     out << ", ";
+     439        4932 :                 out << node.getChildren()[i];
+     440             :             }
+     441        4884 :             out << ")";
+     442             :         }
+     443             :     }
+     444        9929 :     return out;
+     445             : }
+     446             : 
+     447        1086 : ostream& lepton::operator<<(ostream& out, const ParsedExpression& exp) {
+     448        1086 :     out << exp.getRootNode();
+     449        1086 :     return out;
+     450             : }
+     451             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..d6638dbea2 --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.h.func.html b/coverage-libs/lepton/ParsedExpression.h.func.html new file mode 100644 index 0000000000..cf6dec02cc --- /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-06-10 08:19:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.h.gcov.html b/coverage-libs/lepton/ParsedExpression.h.gcov.html new file mode 100644 index 0000000000..a3497740f3 --- /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-06-10 08:19:15Functions: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     2011410 : 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.15
+
+ + + 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 0000000000..a555354bdf --- /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-06-10 08:19:15Functions: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_clEv39
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE1691
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5031
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2009177
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009196
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2009196
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009200
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2016730
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2024246
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.func.html b/coverage-libs/lepton/Parser.cpp.func.html new file mode 100644 index 0000000000..7625a99383 --- /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-06-10 08:19:15Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2024246
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2016730
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE1691
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5031
_ZN4PLMD6lepton6Parser4trimERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009196
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2009196
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009200
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2009177
_ZZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEEENKUlvE_clEv39
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.gcov.html b/coverage-libs/lepton/Parser.cpp.gcov.html new file mode 100644 index 0000000000..f4cc3068b8 --- /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-06-10 08:19:15Functions: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     2009177 : 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     2010189 :   };
+     101     2009177 :   return constants;
+     102             : }
+     103             : 
+     104             : }
+     105             : 
+     106             : 
+     107     6111859 : class lepton::ParseToken {
+     108             : public:
+     109             :     enum Type {Number, Operator, Variable, Function, LeftParen, RightParen, Comma, Whitespace};
+     110             : 
+     111     2024246 :     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       13158 :         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     2024246 : ParseToken Parser::getNextToken(const string& expression, int start) {
+     138     2024246 :     char c = expression[start];
+     139     2024246 :     if (c == '(')
+     140        1350 :         return ParseToken("(", ParseToken::LeftParen);
+     141     2023571 :     if (c == ')')
+     142        4732 :         return ParseToken(")", ParseToken::RightParen);
+     143     2021205 :     if (c == ',')
+     144         160 :         return ParseToken(",", ParseToken::Comma);
+     145     2021125 :     if (Operators.find(c) != string::npos)
+     146        5084 :         return ParseToken(string(1, c), ParseToken::Operator);
+     147     2016041 :     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     2016013 :     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       14745 :     for (int pos = start; pos < (int) expression.size(); pos++) {
+     184       14532 :         c = expression[pos];
+     185       14532 :         if (c == '(')
+     186        3382 :             return ParseToken(expression.substr(start, pos-start+1), ParseToken::Function);
+     187       12841 :         if (Operators.find(c) != string::npos || c == ',' || c == ')' || isspace(c))
+     188        6188 :             return ParseToken(expression.substr(start, pos-start), ParseToken::Variable);
+     189             :     }
+     190         426 :     return ParseToken(expression.substr(start, string::npos), ParseToken::Variable);
+     191             : }
+     192             : 
+     193     2009200 : vector<ParseToken> Parser::tokenize(const string& expression) {
+     194             :     vector<ParseToken> tokens;
+     195             :     int pos = 0;
+     196     4033446 :     while (pos < (int) expression.size()) {
+     197     2024246 :         ParseToken token = getNextToken(expression, pos);
+     198     2024246 :         if (token.getType() != ParseToken::Whitespace)
+     199     2024218 :             tokens.push_back(token);
+     200     2024246 :         pos += (int) token.getText().size();
+     201             :     }
+     202     2009200 :     return tokens;
+     203           0 : }
+     204             : 
+     205     2009196 : ParsedExpression Parser::parse(const string& expression) {
+     206     4018373 :     return parse(expression, map<string, CustomFunction*>());
+     207             : }
+     208             : 
+     209     2009196 : ParsedExpression Parser::parse(const string& expression, const map<string, CustomFunction*>& customFunctions) {
+     210             :     try {
+     211             :         // First split the expression into subexpressions.
+     212             : 
+     213     2009196 :         string primaryExpression = expression;
+     214             :         vector<string> subexpressions;
+     215             :         while (true) {
+     216             :             string::size_type pos = primaryExpression.find_last_of(';');
+     217     2009200 :             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     2009200 :         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     2009196 :         vector<ParseToken> tokens = tokenize(primaryExpression);
+     245     2009196 :         int pos = 0;
+     246     2009196 :         ExpressionTreeNode result = parsePrecedence(tokens, pos, customFunctions, subexpDefs, 0);
+     247     2009192 :         if (pos != tokens.size())
+     248          30 :             throw Exception("unexpected text at end of expression: "+tokens[pos].getText());
+     249     4018354 :         return ParsedExpression(result);
+     250     4018407 :     }
+     251          19 :     catch (Exception& ex) {
+     252          38 :         throw Exception("Parse error in expression \""+expression+"\": "+ex.what());
+     253          19 :     }
+     254             : }
+     255             : 
+     256     2016730 : ExpressionTreeNode Parser::parsePrecedence(const vector<ParseToken>& tokens, int& pos, const map<string, CustomFunction*>& customFunctions,
+     257             :             const map<string, ExpressionTreeNode>& subexpressionDefs, int precedence) {
+     258     2016730 :     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     2016726 :     ExpressionTreeNode result;
+     265     2016726 :     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        5711 :     else if (token.getType() == ParseToken::Variable) {
+     272             :         map<string, ExpressionTreeNode>::const_iterator subexp = subexpressionDefs.find(token.getText());
+     273        3292 :         if (subexp == subexpressionDefs.end()) {
+     274        3288 :             Operation* op = new Operation::Variable(token.getText());
+     275        3288 :             result = ExpressionTreeNode(op);
+     276             :         }
+     277             :         else
+     278           4 :             result = subexp->second;
+     279        3292 :         pos++;
+     280             :     }
+     281        2419 :     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        1744 :     else if (token.getType() == ParseToken::Function) {
+     289        1691 :         pos++;
+     290             :         vector<ExpressionTreeNode> args;
+     291             :         bool moreArgs;
+     292        1771 :         do {
+     293        3542 :             args.push_back(parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0));
+     294        1771 :             moreArgs = (pos < (int) tokens.size() && tokens[pos].getType() == ParseToken::Comma);
+     295             :             if (moreArgs)
+     296          80 :                 pos++;
+     297             :         } while (moreArgs);
+     298        1691 :         if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen)
+     299           0 :             throw Exception("unbalanced parentheses");
+     300        1691 :         pos++;
+     301        1691 :         Operation* op = getFunctionOperation(token.getText(), customFunctions);
+     302             :         try {
+     303        1691 :             result = ExpressionTreeNode(op, args);
+     304             :         }
+     305           0 :         catch (...) {
+     306           0 :             delete op;
+     307           0 :             throw;
+     308           0 :         }
+     309        1691 :     }
+     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     2021757 :     while (pos < (int) tokens.size() && tokens[pos].getType() == ParseToken::Operator) {
+     321             :         token = tokens[pos];
+     322        7331 :         int opIndex = (int) Operators.find(token.getText());
+     323        7331 :         int opPrecedence = Precedence[opIndex];
+     324        7331 :         if (opPrecedence < precedence)
+     325        2300 :             return result;
+     326        5031 :         pos++;
+     327        5031 :         ExpressionTreeNode arg = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, LeftAssociative[opIndex] ? opPrecedence+1 : opPrecedence);
+     328        5031 :         Operation* op = getOperatorOperation(token.getText());
+     329             :         try {
+     330        5031 :             result = ExpressionTreeNode(op, result, arg);
+     331             :         }
+     332           0 :         catch (...) {
+     333           0 :             delete op;
+     334           0 :             throw;
+     335           0 :         }
+     336        5031 :     }
+     337             :     return result;
+     338           0 : }
+     339             : 
+     340        5031 : Operation* Parser::getOperatorOperation(const std::string& name) {
+     341        5031 :     switch (OperationId[Operators.find(name)]) {
+     342        1081 :         case Operation::ADD:
+     343        1081 :             return new Operation::Add();
+     344         877 :         case Operation::SUBTRACT:
+     345         877 :             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        1691 : Operation* Parser::getFunctionOperation(const std::string& name, const map<string, CustomFunction*>& customFunctions) {
+     358             : 
+     359          39 :     const static map<string, Operation::Id> opMap = []() {
+     360             :         map<string, Operation::Id> opMap;
+     361          39 :         opMap["sqrt"] = Operation::SQRT;
+     362          39 :         opMap["exp"] = Operation::EXP;
+     363          39 :         opMap["log"] = Operation::LOG;
+     364          39 :         opMap["sin"] = Operation::SIN;
+     365          39 :         opMap["cos"] = Operation::COS;
+     366          39 :         opMap["sec"] = Operation::SEC;
+     367          39 :         opMap["csc"] = Operation::CSC;
+     368          39 :         opMap["tan"] = Operation::TAN;
+     369          39 :         opMap["cot"] = Operation::COT;
+     370          39 :         opMap["asin"] = Operation::ASIN;
+     371          39 :         opMap["acos"] = Operation::ACOS;
+     372          39 :         opMap["atan"] = Operation::ATAN;
+     373          39 :         opMap["atan2"] = Operation::ATAN2;
+     374          39 :         opMap["sinh"] = Operation::SINH;
+     375          39 :         opMap["cosh"] = Operation::COSH;
+     376          39 :         opMap["tanh"] = Operation::TANH;
+     377          39 :         opMap["erf"] = Operation::ERF;
+     378          39 :         opMap["erfc"] = Operation::ERFC;
+     379          39 :         opMap["step"] = Operation::STEP;
+     380          39 :         opMap["delta"] = Operation::DELTA;
+     381          39 :         opMap["nandelta"] = Operation::NANDELTA;
+     382          39 :         opMap["square"] = Operation::SQUARE;
+     383          39 :         opMap["cube"] = Operation::CUBE;
+     384          39 :         opMap["recip"] = Operation::RECIPROCAL;
+     385          39 :         opMap["min"] = Operation::MIN;
+     386          39 :         opMap["max"] = Operation::MAX;
+     387          39 :         opMap["abs"] = Operation::ABS;
+     388          39 :         opMap["floor"] = Operation::FLOOR;
+     389          39 :         opMap["ceil"] = Operation::CEIL;
+     390          39 :         opMap["select"] = Operation::SELECT;
+     391          39 :         opMap["acot"] = Operation::ACOT;
+     392          39 :         opMap["asec"] = Operation::ASEC;
+     393          39 :         opMap["acsc"] = Operation::ACSC;
+     394          39 :         opMap["coth"] = Operation::COTH;
+     395          39 :         opMap["sech"] = Operation::SECH;
+     396          39 :         opMap["csch"] = Operation::CSCH;
+     397          39 :         opMap["asinh"] = Operation::ASINH;
+     398          39 :         opMap["acosh"] = Operation::ACOSH;
+     399          39 :         opMap["atanh"] = Operation::ATANH;
+     400          39 :         opMap["acoth"] = Operation::ACOTH;
+     401          39 :         opMap["asech"] = Operation::ASECH;
+     402          39 :         opMap["acsch"] = Operation::ACSCH;
+     403          39 :         opMap["atan2"] = Operation::ATAN2;
+     404          39 :         return opMap;
+     405        1691 :     }();
+     406        1691 :     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        1691 :     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        1691 :     if (iter == opMap.end())
+     418           0 :         throw Exception("unknown function: "+trimmed);
+     419        1691 :     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         115 :         case Operation::SIN:
+     427         115 :             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.15
+
+ + + diff --git a/coverage-libs/lepton/index-sort-f.html b/coverage-libs/lepton/index-sort-f.html new file mode 100644 index 0000000000..ef93796418 --- /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:1599179589.1 %
Date:2024-06-10 08:19:15Functions: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 +
85.0%85.0%
+
85.0 %273 / 32193.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
CompiledExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
ParsedExpression.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.15
+
+ + + diff --git a/coverage-libs/lepton/index-sort-l.html b/coverage-libs/lepton/index-sort-l.html new file mode 100644 index 0000000000..a8ea38b98c --- /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:1599179589.1 %
Date:2024-06-10 08:19:15Functions: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 +
85.0%85.0%
+
85.0 %273 / 32193.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
CompiledExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
ParsedExpression.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.15
+
+ + + diff --git a/coverage-libs/lepton/index.html b/coverage-libs/lepton/index.html new file mode 100644 index 0000000000..f1f6f87360 --- /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:1599179589.1 %
Date:2024-06-10 08:19:15Functions: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 +
85.0%85.0%
+
85.0 %273 / 32193.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.15
+
+ + + 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 0000000000..26304f6e16 --- /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:34274945.7 %
Date:2024-06-10 08:19:15Functions: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
_ZN4PLMD7molfileL10mdio_closeEPNS0_7md_fileE108
_ZN4PLMD7molfileL10mdio_errnoEv108
_ZN4PLMD7molfileL11mdio_headerEPNS0_7md_fileEPNS0_9md_headerE108
_ZN4PLMD7molfileL9mdio_openEPKcii108
_ZN4PLMD7molfileL10trx_stringEPNS0_7md_fileEPci155
_ZN4PLMD7molfileL12trx_timestepEPNS0_7md_fileEPNS0_5md_tsE155
_ZN4PLMD7molfileL10trx_headerEPNS0_7md_fileEi160
_ZN4PLMD7molfileL7trx_intEPNS0_7md_fileEPi2485
_ZN4PLMD7molfileL14xtc_sizeofintsEiPj9811
_ZN4PLMD7molfileL8xtc_dataEPNS0_7md_fileEPci9811
_ZN4PLMD7molfileL12xtc_3dfcoordEPNS0_7md_fileEPfPiS3_9812
_ZN4PLMD7molfileL12xtc_timestepEPNS0_7md_fileEPNS0_5md_tsE9915
_ZN4PLMD7molfileL11mdio_tsfreeEPNS0_5md_tsEi9962
_ZN4PLMD7molfileL12mdio_readboxEPNS0_6md_boxEPfS3_S3_9962
_ZN4PLMD7molfileL13mdio_timestepEPNS0_7md_fileEPNS0_5md_tsE10070
_ZN4PLMD7molfileL9xtc_floatEPNS0_7md_fileEPf107934
_ZN4PLMD7molfileL7xtc_intEPNS0_7md_fileEPi118045
_ZN4PLMD7molfileL11trx_rvectorEPNS0_7md_fileEPf486150
_ZN4PLMD7molfileL15xtc_receiveintsEPiiiPjS1_1316578
_ZN4PLMD7molfileL8trx_realEPNS0_7md_fileEPf1458760
_ZN4PLMD7molfileL13mdio_seterrorEi2203476
_ZN4PLMD7molfileL15xtc_receivebitsEPii5721918
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.func.html b/coverage-libs/molfile/Gromacs.h.func.html new file mode 100644 index 0000000000..4495f905bf --- /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:34274945.7 %
Date:2024-06-10 08:19:15Functions:223661.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10g96_headerEPNS0_7md_fileEPciPf0
_ZN4PLMD7molfileL10gro_headerEPNS0_7md_fileEPciPfPii0
_ZN4PLMD7molfileL10mdio_closeEPNS0_7md_fileE108
_ZN4PLMD7molfileL10mdio_errnoEv108
_ZN4PLMD7molfileL10trx_headerEPNS0_7md_fileEi160
_ZN4PLMD7molfileL10trx_stringEPNS0_7md_fileEPci155
_ZN4PLMD7molfileL11mdio_errmsgEi0
_ZN4PLMD7molfileL11mdio_headerEPNS0_7md_fileEPNS0_9md_headerE108
_ZN4PLMD7molfileL11mdio_tsfreeEPNS0_5md_tsEi9962
_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_9962
_ZN4PLMD7molfileL12put_trx_realEPNS0_7md_fileEf0
_ZN4PLMD7molfileL12trx_timestepEPNS0_7md_fileEPNS0_5md_tsE155
_ZN4PLMD7molfileL12xtc_3dfcoordEPNS0_7md_fileEPfPiS3_9812
_ZN4PLMD7molfileL12xtc_timestepEPNS0_7md_fileEPNS0_5md_tsE9915
_ZN4PLMD7molfileL13mdio_readlineEPNS0_7md_fileEPcii0
_ZN4PLMD7molfileL13mdio_seterrorEi2203476
_ZN4PLMD7molfileL13mdio_timestepEPNS0_7md_fileEPNS0_5md_tsE10070
_ZN4PLMD7molfileL13xtc_sizeofintEi0
_ZN4PLMD7molfileL14g96_countatomsEPNS0_7md_fileE0
_ZN4PLMD7molfileL14put_trx_stringEPNS0_7md_fileEPKc0
_ZN4PLMD7molfileL14xtc_sizeofintsEiPj9811
_ZN4PLMD7molfileL15xtc_receivebitsEPii5721918
_ZN4PLMD7molfileL15xtc_receiveintsEPiiiPjS1_1316578
_ZN4PLMD7molfileL7g96_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7gro_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7trx_intEPNS0_7md_fileEPi2485
_ZN4PLMD7molfileL7xtc_intEPNS0_7md_fileEPi118045
_ZN4PLMD7molfileL8trx_realEPNS0_7md_fileEPf1458760
_ZN4PLMD7molfileL8xtc_dataEPNS0_7md_fileEPci9811
_ZN4PLMD7molfileL9mdio_openEPKcii108
_ZN4PLMD7molfileL9xtc_floatEPNS0_7md_fileEPf107934
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.gcov.html b/coverage-libs/molfile/Gromacs.h.gcov.html new file mode 100644 index 0000000000..43f6d3c137 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.gcov.html @@ -0,0 +1,2088 @@ + + + + + + + + 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:34274945.7 %
Date:2024-06-10 08:19:15Functions: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.34 $       $Date: 2016/11/28 05:01:53 $
+      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         108 : md_file *mdio_open(const char *fn, const int fmt, const int rw) {
+     329             :         md_file *mf;
+     330             : 
+     331         108 :         if (!fn) {
+     332           0 :                 mdio_seterror(MDIO_BADPARAMS);
+     333           0 :                 return NULL;
+     334             :         }
+     335             : 
+     336             :         // Allocate memory
+     337         108 :         mf = (md_file *) malloc(sizeof(md_file));
+     338         108 :         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         108 :         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         108 :                 mf->fmt = fmt;
+     375             :         }
+     376             : 
+     377             :         // Differentiate between binary and ascii files. Also,
+     378             :         // .trX files need a header information structure allocated.
+     379         108 :         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         108 :         case MDFMT_XTC:  /* fallthrough */
+     399             :                 // Finally, open the file
+     400         108 :         if (rw)
+     401           0 :             mf->f = fopen(fn, "wb");
+     402             :         else
+     403         108 :             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         108 :         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         108 :         mdio_seterror(MDIO_SUCCESS);
+     422         108 :         return mf;
+     423             : }
+     424             : 
+     425             : 
+     426             : // Closes a molecular dynamics file.
+     427         108 : static int mdio_close(md_file *mf) {
+     428         108 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+     429             : 
+     430         108 :         if (fclose(mf->f) == EOF) return mdio_seterror(MDIO_CANTCLOSE);
+     431             : 
+     432             :         // Free the dynamically allocated memory
+     433         108 :         if (mf->trx) free(mf->trx);
+     434         108 :         free(mf);
+     435         108 :         return mdio_seterror(MDIO_SUCCESS);
+     436             : }
+     437             : 
+     438             : 
+     439             : // Returns the last error code reported by any of the mdio functions
+     440         108 : static int mdio_errno(void) {
+     441         108 :         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     2203476 : static int mdio_seterror(int code) {
+     455     2203476 :         mdio_errcode = code;
+     456     2203476 :         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        9962 : static int mdio_tsfree(md_ts *ts, int holderror) {
+     522        9962 :         if (!ts) {
+     523           0 :                 if (holderror) return -1;
+     524           0 :                 else return mdio_seterror(MDIO_BADPARAMS);
+     525             :         }
+     526             : 
+     527        9962 :         if (ts->pos && ts->natoms > 0) free(ts->pos);
+     528             : 
+     529        9962 :   if (ts->box) free(ts->box);
+     530             : 
+     531        9962 :         if (holderror) return -1;
+     532        9962 :         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        9962 : static int mdio_readbox(md_box *box, float *x, float *y, float *z) {
+     540             :   float A, B, C;
+     541             : 
+     542        9962 :   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        9962 :   A = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] ) * ANGS_PER_NM;
+     548        9962 :   B = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] ) * ANGS_PER_NM;
+     549        9962 :   C = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] ) * ANGS_PER_NM;
+     550        9962 :   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        9962 :     box->A = A;
+     556        9962 :     box->B = B;
+     557        9962 :     box->C = C;
+     558             :   
+     559             :     // gamma, beta, alpha are the angles between the x & y, x & z, y & z
+     560             :     // vectors, respectively
+     561        9962 :     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        9962 :     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        9962 :     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        9962 :   return mdio_seterror(MDIO_SUCCESS);
+     566             : }
+     567             : 
+     568             : 
+     569             : // Reads the header of a file (format independent)
+     570         108 : static int mdio_header(md_file *mf, md_header *mdh) {
+     571             :         int n;
+     572         108 :         if (!mf || !mdh) return mdio_seterror(MDIO_BADPARAMS);
+     573         108 :         if (!mf->f) return mdio_seterror(MDIO_BADPARAMS);
+     574             : 
+     575         108 :         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         103 :                 if (xtc_int(mf, &n) < 0) return -1;
+     600         103 :                 if (n != XTC_MAGIC) return mdio_seterror(MDIO_BADFORMAT);
+     601             : 
+     602             :                 // Get number of atoms
+     603         103 :                 if (xtc_int(mf, &n) < 0) return -1;
+     604         103 :                 mdh->natoms = n;
+     605         103 :                 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       10070 : static int mdio_timestep(md_file *mf, md_ts *ts) {
+     616       10070 :         if (!mf || !ts) return mdio_seterror(MDIO_BADPARAMS);
+     617       10070 :         if (!mf->f) return mdio_seterror(MDIO_BADPARAMS);
+     618             : 
+     619       10070 :         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        9915 :         case MDFMT_XTC:
+     631        9915 :                 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             :     // Allocate the box and convert the vectors.
+    1454         150 :     ts->box = (md_box *) malloc(sizeof(md_box));
+    1455         150 :     if (mdio_readbox(ts->box, x, y, z) < 0) {
+    1456           0 :       free(ts->box);
+    1457           0 :       ts->box = NULL;
+    1458           0 :       return -1;
+    1459             :     }
+    1460             :         }
+    1461             : 
+    1462         150 :         if (hdr->vir_size) {
+    1463           0 :                 if (trx_rvector(mf, NULL) < 0) return -1;
+    1464           0 :                 if (trx_rvector(mf, NULL) < 0) return -1;
+    1465           0 :                 if (trx_rvector(mf, NULL) < 0) return -1;
+    1466             :         }
+    1467             : 
+    1468         150 :         if (hdr->pres_size) {
+    1469           0 :                 if (trx_rvector(mf, NULL) < 0) return -1;
+    1470           0 :                 if (trx_rvector(mf, NULL) < 0) return -1;
+    1471           0 :                 if (trx_rvector(mf, NULL) < 0) return -1;
+    1472             :         }
+    1473             : 
+    1474         150 :         if (hdr->x_size) {
+    1475         150 :                 ts->pos = (float *) malloc(sizeof(float) * 3 * hdr->natoms);
+    1476         150 :                 if (!ts->pos) return mdio_seterror(MDIO_BADMALLOC);
+    1477             : 
+    1478         150 :                 ts->natoms = hdr->natoms;
+    1479             : 
+    1480      485850 :                 for (i = 0; i < hdr->natoms; i++) {
+    1481      485700 :                         if (trx_rvector(mf, &ts->pos[i * 3]) < 0) {
+    1482           0 :                                 mdio_tsfree(ts, 1);
+    1483           0 :                                 return -1;
+    1484             :                         }
+    1485      485700 :                         ts->pos[i * 3] *= ANGS_PER_NM;
+    1486      485700 :                         ts->pos[i * 3 + 1] *= ANGS_PER_NM;
+    1487      485700 :                         ts->pos[i * 3 + 2] *= ANGS_PER_NM;
+    1488             :                 }
+    1489             :         }
+    1490             : 
+    1491         150 :         if (hdr->v_size) {
+    1492           0 :                 for (i = 0; i < hdr->natoms; i++) {
+    1493           0 :                         if (trx_rvector(mf, NULL) < 0) {
+    1494           0 :                                 mdio_tsfree(ts, 1);
+    1495           0 :                                 return -1;
+    1496             :                         }
+    1497             :                 }
+    1498             :         }
+    1499             : 
+    1500         150 :         if (hdr->f_size) {
+    1501           0 :                 for (i = 0; i < hdr->natoms; i++) {
+    1502           0 :                         if (trx_rvector(mf, NULL) < 0) {
+    1503           0 :                                 mdio_tsfree(ts, 1);
+    1504           0 :                                 return -1;
+    1505             :                         }
+    1506             :                 }
+    1507             :         }
+    1508             : 
+    1509         150 :         return mdio_seterror(MDIO_SUCCESS);
+    1510             : }
+    1511             : 
+    1512             : 
+    1513             : // writes an int in big endian. Returns GMX_SUCCESS
+    1514             : // on success or a negative number on error.
+    1515           0 : static int put_trx_int(md_file *mf, int y) {
+    1516           0 :       if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1517             : 
+    1518             :       // sanity check.
+    1519             :       if (sizeof(int) != 4) return mdio_seterror(MDIO_SIZEERROR);
+    1520             : 
+    1521           0 :       if (mf->rev) swap4_aligned(&y, 1);
+    1522           0 :       if (fwrite(&y, 4, 1, mf->f) != 1)
+    1523           0 :     return mdio_seterror(MDIO_IOERROR);
+    1524             : 
+    1525           0 :   return mdio_seterror(MDIO_SUCCESS);
+    1526             : }
+    1527             : 
+    1528             : // writes a real in big-endian. Returns GMX_SUCCESS
+    1529             : // on success or a negative number on error.
+    1530           0 : static int put_trx_real(md_file *mf, float y) {
+    1531           0 :       if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1532             : 
+    1533           0 :       if (mf->rev) swap4_aligned(&y, 1);
+    1534           0 :       if (fwrite(&y, 4, 1, mf->f) != 1)
+    1535           0 :         return mdio_seterror(MDIO_IOERROR);
+    1536             : 
+    1537           0 :       return mdio_seterror(MDIO_SUCCESS);
+    1538             : }
+    1539             : 
+    1540             : 
+    1541             : // writes an xdr encoded string. Returns GMX_SUCCESS
+    1542             : // on success or a negative number on error.
+    1543           0 : static int put_trx_string(md_file *mf, const char *s) {
+    1544           0 :         if (!mf || !s) return mdio_seterror(MDIO_BADPARAMS);
+    1545             :         
+    1546             :         // write: size of object, string length, string data
+    1547           0 :         size_t len = strlen(s);
+    1548           0 :         if ( put_trx_int(mf, len+1)
+    1549           0 :              || put_trx_int(mf, len)
+    1550           0 :              || (fwrite(s, len, 1, mf->f) != 1))
+    1551           0 :           return mdio_seterror(MDIO_IOERROR);
+    1552             : 
+    1553           0 :         return mdio_seterror(MDIO_SUCCESS);
+    1554             : }
+    1555             : 
+    1556             : 
+    1557             : // xtc_int() - reads an integer from an xtc file
+    1558      118045 : static int xtc_int(md_file *mf, int *i) {
+    1559             :         unsigned char c[4];
+    1560             : 
+    1561      118045 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1562             :         // sanity check.
+    1563             :         if (sizeof(int) != 4) return mdio_seterror(MDIO_SIZEERROR);
+    1564             : 
+    1565      118045 :         if (fread(c, 1, 4, mf->f) != 4) {
+    1566         103 :                 if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1567           0 :                 else if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1568           0 :                 else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1569             :         }
+    1570             : 
+    1571      117942 :         if (i) *i = c[3] + (c[2] << 8) + (c[1] << 16) + (c[0] << 24);
+    1572      117942 :         return mdio_seterror(MDIO_SUCCESS);
+    1573             : }
+    1574             : 
+    1575             : 
+    1576             : // xtc_float() - reads a float from an xtc file
+    1577      107934 : static int xtc_float(md_file *mf, float *f) {
+    1578             :         unsigned char c[4];
+    1579             :         int i;
+    1580             : 
+    1581      107934 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1582             : 
+    1583      107934 :         if (fread(c, 1, 4, mf->f) != 4) {
+    1584           0 :                 if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1585           0 :                 else if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1586           0 :                 else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1587             :         }
+    1588             : 
+    1589      107934 :         if (f) {
+    1590             :                 // By reading the number in as an integer and then
+    1591             :                 // copying it to a floating point number we can
+    1592             :                 // ensure proper endianness
+    1593      107934 :                 i = c[3] + (c[2] << 8) + (c[1] << 16) + (c[0] << 24);
+    1594             :                 memcpy(f, &i, 4);
+    1595             :         }
+    1596      107934 :         return mdio_seterror(MDIO_SUCCESS);
+    1597             : }
+    1598             : 
+    1599             : 
+    1600             : // xtc_data() - reads a specific amount of data from an xtc
+    1601             : // file using the xdr format.
+    1602        9811 : static int xtc_data(md_file *mf, char *buf, int len) {
+    1603        9811 :         if (!mf || len < 1) return mdio_seterror(MDIO_BADPARAMS);
+    1604        9811 :   size_t slen = (size_t)len;
+    1605        9811 :         if (buf) {
+    1606       19622 :                 if (fread(buf, 1, slen, mf->f) != slen) {
+    1607           0 :                         if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1608           0 :                         if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1609           0 :                         else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1610             :                 }
+    1611        9811 :                 if (len % 4) {
+    1612        7617 :                         if (fseek(mf->f, 4 - (len % 4), SEEK_CUR)) {
+    1613           0 :                                 if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1614           0 :                                 if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1615           0 :                                 else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1616             :                         }
+    1617             :                 }
+    1618             :         }
+    1619             :         else {
+    1620             :                 int newlen;
+    1621             :                 newlen = len;
+    1622           0 :                 if (len % 4) newlen += (4 - (len % 4));
+    1623           0 :                 if (fseek(mf->f, newlen, SEEK_CUR)) {
+    1624           0 :                         if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1625           0 :                         if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1626           0 :                         else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1627             :                 }
+    1628             :         }
+    1629             :         return len;
+    1630             : }
+    1631             : 
+    1632             : 
+    1633             : // xtc_timestep() - reads a timestep from an .xtc file.
+    1634        9915 : static int xtc_timestep(md_file *mf, md_ts *ts) {
+    1635             :         int n;
+    1636             :         float f, x[3], y[3], z[3];
+    1637             : 
+    1638        9915 :         int size = 0; // explicitly initialized to zero.
+    1639             :         float precision;
+    1640             : 
+    1641        9915 :         if (!mf || !ts) return mdio_seterror(MDIO_BADPARAMS);
+    1642        9915 :         if (!mf->f) return mdio_seterror(MDIO_BADPARAMS);
+    1643        9915 :         if (mf->fmt != MDFMT_XTC) return mdio_seterror(MDIO_WRONGFORMAT);
+    1644             : 
+    1645             :         // Check magic number
+    1646        9915 :         if (xtc_int(mf, &n) < 0) return -1;
+    1647        9812 :         if (n != XTC_MAGIC) return mdio_seterror(MDIO_BADFORMAT);
+    1648             : 
+    1649             :         // Get number of atoms
+    1650        9812 :         if (xtc_int(mf, &n) < 0) return -1;
+    1651        9812 :         ts->natoms = n;
+    1652             : 
+    1653             :         // Get the simulation step
+    1654        9812 :         if (xtc_int(mf, &n) < 0) return -1;
+    1655        9812 :         ts->step = n;
+    1656             : 
+    1657             :         // Get the time value
+    1658        9812 :         if (xtc_float(mf, &f) < 0) return -1;
+    1659        9812 :         ts->time = f;
+    1660             : 
+    1661             :         // Read the basis vectors of the box
+    1662       19624 :   if ( (xtc_float(mf, &x[0]) < 0) ||
+    1663       19624 :        (xtc_float(mf, &x[1]) < 0) ||
+    1664       19624 :        (xtc_float(mf, &x[2]) < 0) ||
+    1665       19624 :        (xtc_float(mf, &y[0]) < 0) ||
+    1666       19624 :        (xtc_float(mf, &y[1]) < 0) ||
+    1667       19624 :        (xtc_float(mf, &y[2]) < 0) ||
+    1668       19624 :        (xtc_float(mf, &z[0]) < 0) ||
+    1669       29436 :        (xtc_float(mf, &z[1]) < 0) ||
+    1670        9812 :        (xtc_float(mf, &z[2]) < 0) )
+    1671           0 :     return -1;
+    1672             :   // Allocate the box and convert the vectors.
+    1673        9812 :   ts->box = (md_box *) malloc(sizeof(md_box));
+    1674        9812 :   if (mdio_readbox(ts->box, x, y, z) < 0) {
+    1675           0 :     free(ts->box);
+    1676           0 :     ts->box = NULL;
+    1677           0 :     return -1;
+    1678             :   }
+    1679             : 
+    1680        9812 :         ts->pos = (float *) malloc(sizeof(float) * 3 * ts->natoms);
+    1681        9812 :         if (!ts->pos) return mdio_seterror(MDIO_BADMALLOC);
+    1682        9812 :         n = xtc_3dfcoord(mf, ts->pos, &size, &precision);
+    1683        9812 :         if (n < 0) return -1;
+    1684             : 
+    1685             :         /* Now we're left with the job of scaling... */
+    1686     3959549 :         for (n = 0; n < ts->natoms * 3; n++)
+    1687     3949737 :                 ts->pos[n] *= ANGS_PER_NM;
+    1688             : 
+    1689        9812 :         return mdio_seterror(MDIO_SUCCESS);
+    1690             : }
+    1691             : 
+    1692             : 
+    1693             : ///////////////////////////////////////////////////////////////////////
+    1694             : // This algorithm is an implementation of the 3dfcoord algorithm
+    1695             : // written by Frans van Hoesel (hoesel@chem.rug.nl) as part of the
+    1696             : // Europort project in 1995.
+    1697             : ///////////////////////////////////////////////////////////////////////
+    1698             : 
+    1699             : // integer table used in decompression
+    1700             : static int xtc_magicints[] = {
+    1701             :         0, 0, 0, 0, 0, 0, 0, 0, 0,8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
+    1702             :         80, 101, 128, 161, 203, 256, 322, 406, 512, 645, 812, 1024, 1290,
+    1703             :         1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192, 10321, 13003, 16384,
+    1704             :         20642, 26007, 32768, 41285, 52015, 65536, 82570, 104031, 131072,
+    1705             :         165140, 208063, 262144, 330280, 416127, 524287, 660561, 832255,
+    1706             :         1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304,
+    1707             :         5284491, 6658042, 8388607, 10568983, 13316085, 16777216 };
+    1708             : 
+    1709             : #define FIRSTIDX 9
+    1710             : /* note that magicints[FIRSTIDX-1] == 0 */
+    1711             : #define LASTIDX (sizeof(xtc_magicints) / sizeof(*xtc_magicints))
+    1712             : 
+    1713             : 
+    1714             : // returns the number of bits in the binary expansion of
+    1715             : // the given integer.
+    1716           0 : static int xtc_sizeofint(int size) {
+    1717             :         unsigned int num = 1;
+    1718           0 :   unsigned int ssize = (unsigned int)size;
+    1719             :         int nbits = 0;
+    1720             : 
+    1721           0 :         while (ssize >= num && nbits < 32) {
+    1722           0 :                 nbits++;
+    1723           0 :                 num <<= 1;
+    1724             :         }
+    1725           0 :         return nbits;
+    1726             : }
+    1727             : 
+    1728             : // calculates the number of bits a set of integers, when compressed,
+    1729             : // will take up.
+    1730        9811 : static int xtc_sizeofints(int nints, unsigned int *sizes) {
+    1731             :         int i;
+    1732             :   unsigned int num;
+    1733             :         unsigned int nbytes, nbits, bytes[32], bytecnt, tmp;
+    1734             :         nbytes = 1;
+    1735        9811 :         bytes[0] = 1;
+    1736             :         nbits = 0;
+    1737       39244 :         for (i=0; i < nints; i++) {  
+    1738             :                 tmp = 0;
+    1739       88504 :                 for (bytecnt = 0; bytecnt < nbytes; bytecnt++) {
+    1740       59071 :                         tmp = bytes[bytecnt] * sizes[i] + tmp;
+    1741       59071 :                         bytes[bytecnt] = tmp & 0xff;
+    1742       59071 :                         tmp >>= 8;
+    1743             :                 }
+    1744       61740 :                 while (tmp != 0) {
+    1745       32307 :                         bytes[bytecnt++] = tmp & 0xff;
+    1746       32307 :                         tmp >>= 8;
+    1747             :                 }
+    1748             :                 nbytes = bytecnt;
+    1749             :         }
+    1750             :         num = 1;
+    1751        9811 :         nbytes--;
+    1752       43837 :         while (bytes[nbytes] >= num) {
+    1753       34026 :                 nbits++;
+    1754       34026 :                 num *= 2;
+    1755             :         }
+    1756        9811 :         return nbits + nbytes * 8;
+    1757             : }
+    1758             : 
+    1759             : // reads bits from a buffer.    
+    1760     5721918 : static int xtc_receivebits(int *buf, int nbits) {
+    1761             :         int cnt, num; 
+    1762             :         unsigned int lastbits, lastbyte;
+    1763             :         unsigned char * cbuf;
+    1764     5721918 :         int mask = (1 << nbits) -1;
+    1765             : 
+    1766     5721918 :         cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
+    1767     5721918 :         cnt = buf[0];
+    1768     5721918 :         lastbits = (unsigned int) buf[1];
+    1769     5721918 :         lastbyte = (unsigned int) buf[2];
+    1770             : 
+    1771             :         num = 0;
+    1772     9713261 :         while (nbits >= 8) {
+    1773     3991343 :                 lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
+    1774     3991343 :                 num |=  (lastbyte >> lastbits) << (nbits - 8);
+    1775             :                 nbits -=8;
+    1776             :         }
+    1777     5721918 :         if (nbits > 0) {
+    1778     1730575 :                 if (lastbits < (unsigned int)nbits) {
+    1779      971927 :                         lastbits += 8;
+    1780      971927 :                         lastbyte = (lastbyte << 8) | cbuf[cnt++];
+    1781             :                 }
+    1782     1730575 :                 lastbits -= nbits;
+    1783     1730575 :                 num |= (lastbyte >> lastbits) & ((1 << nbits) -1);
+    1784             :         }
+    1785     5721918 :         num &= mask;
+    1786     5721918 :         buf[0] = cnt;
+    1787     5721918 :         buf[1] = lastbits;
+    1788     5721918 :         buf[2] = lastbyte;
+    1789     5721918 :         return num; 
+    1790             : }
+    1791             : 
+    1792             : // decompresses small integers from the buffer
+    1793             : // sizes parameter has to be non-zero to prevent divide-by-zero
+    1794     1316578 : static void xtc_receiveints(int *buf, const int nints, int nbits,
+    1795             :                         unsigned int *sizes, int *nums) {
+    1796             :         int bytes[32];
+    1797             :         int i, j, nbytes, p, num;
+    1798             : 
+    1799     1316578 :         bytes[1] = bytes[2] = bytes[3] = 0;
+    1800             :         nbytes = 0;
+    1801     5268463 :         while (nbits > 8) {
+    1802     3951885 :                 bytes[nbytes++] = xtc_receivebits(buf, 8);
+    1803     3951885 :                 nbits -= 8;
+    1804             :         }
+    1805     1316578 :         if (nbits > 0) {
+    1806     1316578 :                 bytes[nbytes++] = xtc_receivebits(buf, nbits);
+    1807             :         }
+    1808     3949734 :         for (i = nints-1; i > 0; i--) {
+    1809             :                 num = 0;
+    1810    13170082 :                 for (j = nbytes-1; j >=0; j--) {
+    1811    10536926 :                         num = (num << 8) | bytes[j];
+    1812    10536926 :                         p = num / sizes[i];
+    1813    10536926 :                         bytes[j] = p;
+    1814    10536926 :                         num = num - p * sizes[i];
+    1815             :                 }
+    1816     2633156 :                 nums[i] = num;
+    1817             :         }
+    1818     1316578 :         nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
+    1819     1316578 : }
+    1820             : 
+    1821             : // function that actually reads and writes compressed coordinates    
+    1822        9812 : static int xtc_3dfcoord(md_file *mf, float *fp, int *size, float *precision) {
+    1823             :         static int *ip = NULL;
+    1824             :         static int oldsize;
+    1825             :         static int *buf;
+    1826             : 
+    1827             :         int minint[3], maxint[3], *lip;
+    1828             :         int smallidx;
+    1829             :         unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3;
+    1830             :         int flag, k;
+    1831             :         int small, smaller, i, is_smaller, run;
+    1832             :         float *lfp;
+    1833             :         int tmp, *thiscoord,  prevcoord[3];
+    1834             : 
+    1835             :         int bufsize, lsize;
+    1836             :         unsigned int bitsize;
+    1837             :         float inv_precision;
+    1838             : 
+    1839             :         /* avoid uninitialized data compiler warnings */
+    1840             :         bitsizeint[0] = 0;
+    1841             :         bitsizeint[1] = 0;
+    1842             :         bitsizeint[2] = 0;
+    1843             : 
+    1844        9812 :         if (xtc_int(mf, &lsize) < 0) return -1;
+    1845             : 
+    1846        9812 :         if (*size != 0 && lsize != *size) return mdio_seterror(MDIO_BADFORMAT);
+    1847             : 
+    1848        9812 :         *size = lsize;
+    1849        9812 :         size3 = *size * 3;
+    1850        9812 :         if (*size <= 9) {
+    1851           2 :                 for (i = 0; i < *size; i++) {
+    1852           1 :                         if (xtc_float(mf, fp + (3 * i)) < 0) return -1;
+    1853           1 :                         if (xtc_float(mf, fp + (3 * i) + 1) < 0) return -1;
+    1854           1 :                         if (xtc_float(mf, fp + (3 * i) + 2) < 0) return -1;
+    1855             :                 }
+    1856             :                 return *size;
+    1857             :         }
+    1858        9811 :         xtc_float(mf, precision);
+    1859        9811 :         if (ip == NULL) {
+    1860         102 :                 ip = (int *)malloc(size3 * sizeof(*ip));
+    1861         102 :                 if (ip == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1862         102 :                 bufsize = (int) (size3 * 1.2);
+    1863         102 :                 buf = (int *)malloc(bufsize * sizeof(*buf));
+    1864         102 :                 if (buf == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1865         102 :                 oldsize = *size;
+    1866        9709 :         } else if (*size > oldsize) {
+    1867           0 :                 ip = (int *)realloc(ip, size3 * sizeof(*ip));
+    1868           0 :                 if (ip == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1869           0 :                 bufsize = (int) (size3 * 1.2);
+    1870           0 :                 buf = (int *)realloc(buf, bufsize * sizeof(*buf));
+    1871           0 :                 if (buf == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1872           0 :                 oldsize = *size;
+    1873             :         }
+    1874        9811 :         buf[0] = buf[1] = buf[2] = 0;
+    1875             : 
+    1876        9811 :         xtc_int(mf, &(minint[0]));
+    1877        9811 :         xtc_int(mf, &(minint[1]));
+    1878        9811 :         xtc_int(mf, &(minint[2]));
+    1879             : 
+    1880        9811 :         xtc_int(mf, &(maxint[0]));
+    1881        9811 :         xtc_int(mf, &(maxint[1]));
+    1882        9811 :         xtc_int(mf, &(maxint[2]));
+    1883             :                 
+    1884        9811 :         sizeint[0] = maxint[0] - minint[0]+1;
+    1885        9811 :         sizeint[1] = maxint[1] - minint[1]+1;
+    1886        9811 :         sizeint[2] = maxint[2] - minint[2]+1;
+    1887             :         
+    1888             :         /* check if one of the sizes is to big to be multiplied */
+    1889        9811 :         if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) {
+    1890           0 :                 bitsizeint[0] = xtc_sizeofint(sizeint[0]);
+    1891           0 :                 bitsizeint[1] = xtc_sizeofint(sizeint[1]);
+    1892           0 :                 bitsizeint[2] = xtc_sizeofint(sizeint[2]);
+    1893             :                 bitsize = 0; /* flag the use of large sizes */
+    1894             :         } else {
+    1895        9811 :                 bitsize = xtc_sizeofints(3, sizeint);
+    1896             :         }
+    1897             : 
+    1898        9811 :         xtc_int(mf, &smallidx);
+    1899        9811 :         smaller = xtc_magicints[FIRSTIDX > smallidx - 1 ? FIRSTIDX : smallidx - 1] / 2;
+    1900        9811 :         small = xtc_magicints[smallidx] / 2;
+    1901        9811 :         sizesmall[0] = sizesmall[1] = sizesmall[2] = xtc_magicints[smallidx];
+    1902             : 
+    1903             :         /* check for zero values that would yield corrupted data */
+    1904        9811 :         if ( !sizesmall[0] || !sizesmall[1] || !sizesmall[2] ) {
+    1905             :                 printf("XTC corrupted, sizesmall==0 (case 1)\n");
+    1906           0 :                 return -1;
+    1907             :         }
+    1908             : 
+    1909             : 
+    1910             :         /* buf[0] holds the length in bytes */
+    1911        9811 :         if (xtc_int(mf, &(buf[0])) < 0) return -1;
+    1912             : 
+    1913        9811 :         if (xtc_data(mf, (char *) &buf[3], (int) buf[0]) < 0) return -1;
+    1914             : 
+    1915        9811 :         buf[0] = buf[1] = buf[2] = 0;
+    1916             : 
+    1917             :         lfp = fp;
+    1918        9811 :         inv_precision = 1.0f / (*precision);
+    1919             :         run = 0;
+    1920             :         i = 0;
+    1921        9811 :         lip = ip;
+    1922      301460 :         while (i < lsize) {
+    1923      291649 :                 thiscoord = (int *)(lip) + i * 3;
+    1924             : 
+    1925      291649 :                 if (bitsize == 0) {
+    1926           0 :                         thiscoord[0] = xtc_receivebits(buf, bitsizeint[0]);
+    1927           0 :                         thiscoord[1] = xtc_receivebits(buf, bitsizeint[1]);
+    1928           0 :                         thiscoord[2] = xtc_receivebits(buf, bitsizeint[2]);
+    1929             :                 } else {
+    1930      291649 :                         xtc_receiveints(buf, 3, bitsize, sizeint, thiscoord);
+    1931             :                 }
+    1932             : 
+    1933      291649 :                 i++;
+    1934      291649 :                 thiscoord[0] += minint[0];
+    1935      291649 :                 thiscoord[1] += minint[1];
+    1936      291649 :                 thiscoord[2] += minint[2];
+    1937             : 
+    1938             :                 prevcoord[0] = thiscoord[0];
+    1939             :                 prevcoord[1] = thiscoord[1];
+    1940             :                 prevcoord[2] = thiscoord[2];
+    1941             :  
+    1942             : 
+    1943      291649 :                 flag = xtc_receivebits(buf, 1);
+    1944             :                 is_smaller = 0;
+    1945      291649 :                 if (flag == 1) {
+    1946      161806 :                         run = xtc_receivebits(buf, 5);
+    1947      161806 :                         is_smaller = run % 3;
+    1948      161806 :                         run -= is_smaller;
+    1949      161806 :                         is_smaller--;
+    1950             :                 }
+    1951      291649 :                 if (run > 0) {
+    1952      239992 :                         thiscoord += 3;
+    1953     1264921 :                         for (k = 0; k < run; k+=3) {
+    1954     1024929 :                                 xtc_receiveints(buf, 3, smallidx, sizesmall, thiscoord);
+    1955     1024929 :                                 i++;
+    1956     1024929 :                                 thiscoord[0] += prevcoord[0] - small;
+    1957     1024929 :                                 thiscoord[1] += prevcoord[1] - small;
+    1958     1024929 :                                 thiscoord[2] += prevcoord[2] - small;
+    1959     1024929 :                                 if (k == 0) {
+    1960             :                                         /* interchange first with second atom for better
+    1961             :                                          * compression of water molecules
+    1962             :                                          */
+    1963      239992 :                                         tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
+    1964             :                                         prevcoord[0] = tmp;
+    1965      239992 :                                         tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
+    1966             :                                         prevcoord[1] = tmp;
+    1967      239992 :                                         tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
+    1968             :                                         prevcoord[2] = tmp;
+    1969      239992 :                                         *lfp++ = prevcoord[0] * inv_precision;
+    1970      239992 :                                         *lfp++ = prevcoord[1] * inv_precision;
+    1971      239992 :                                         *lfp++ = prevcoord[2] * inv_precision;
+    1972             : 
+    1973      239992 :                                         if ( !sizesmall[0] || !sizesmall[1] || !sizesmall[2] ) {
+    1974             :                                                 printf("XTC corrupted, sizesmall==0 (case 2)\n");
+    1975           0 :                                                 return -1;
+    1976             :                                         }
+    1977             : 
+    1978             :                                 } else {
+    1979             :                                         prevcoord[0] = thiscoord[0];
+    1980             :                                         prevcoord[1] = thiscoord[1];
+    1981             :                                         prevcoord[2] = thiscoord[2];
+    1982             :                                 }
+    1983     1024929 :                                 *lfp++ = thiscoord[0] * inv_precision;
+    1984     1024929 :                                 *lfp++ = thiscoord[1] * inv_precision;
+    1985     1024929 :                                 *lfp++ = thiscoord[2] * inv_precision;
+    1986             :                         }
+    1987             :                 } else {
+    1988       51657 :                         *lfp++ = thiscoord[0] * inv_precision;
+    1989       51657 :                         *lfp++ = thiscoord[1] * inv_precision;
+    1990       51657 :                         *lfp++ = thiscoord[2] * inv_precision;          
+    1991             :                 }
+    1992      291649 :                 smallidx += is_smaller;
+    1993      291649 :                 if (is_smaller < 0) {
+    1994             :                         small = smaller;
+    1995       32417 :                         if (smallidx > FIRSTIDX) {
+    1996       32417 :                                 smaller = xtc_magicints[smallidx - 1] /2;
+    1997             :                         } else {
+    1998             :                                 smaller = 0;
+    1999             :                         }
+    2000      259232 :                 } else if (is_smaller > 0) {
+    2001             :                         smaller = small;
+    2002       96566 :                         small = xtc_magicints[smallidx] / 2;
+    2003             :                 }
+    2004      291649 :                 sizesmall[0] = sizesmall[1] = sizesmall[2] = xtc_magicints[smallidx] ;
+    2005             :         }
+    2006             :         return 1;
+    2007             : }
+    2008             : }
+    2009             : }
+    2010             : #endif
+    2011             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..946eddd48a --- /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-06-10 08:19:15Functions: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_initEv6946
_ZN4PLMD7molfile26molfile_crdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE6946
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/crdplugin.cpp.func.html b/coverage-libs/molfile/crdplugin.cpp.func.html new file mode 100644 index 0000000000..5f67bcceae --- /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-06-10 08:19:15Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_crdplugin_finiEv0
_ZN4PLMD7molfile22molfile_crdplugin_initEv6946
_ZN4PLMD7molfile26molfile_crdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE6946
_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.15
+
+ + + diff --git a/coverage-libs/molfile/crdplugin.cpp.gcov.html b/coverage-libs/molfile/crdplugin.cpp.gcov.html new file mode 100644 index 0000000000..5ea1a6d299 --- /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-06-10 08:19:15Functions: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        6946 : VMDPLUGIN_API int VMDPLUGIN_init(void) { 
+     226             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+     227        6946 :   plugin.abiversion = vmdplugin_ABIVERSION;
+     228        6946 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+     229        6946 :   plugin.name = "crd";
+     230        6946 :   plugin.prettyname = "AMBER Coordinates";
+     231        6946 :   plugin.author = "Justin Gullingsrud, John Stone";
+     232             :   plugin.majorv = 0;
+     233        6946 :   plugin.minorv = 9;
+     234        6946 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+     235        6946 :   plugin.filename_extension = "mdcrd,crd";
+     236        6946 :   plugin.open_file_read = open_crd_read;
+     237        6946 :   plugin.read_next_timestep = read_crd_timestep;
+     238        6946 :   plugin.close_file_read = close_crd_read;
+     239        6946 :   plugin.open_file_write = open_crd_write;
+     240        6946 :   plugin.write_timestep = write_crd_timestep;
+     241        6946 :   plugin.close_file_write = close_crd_write;
+     242             : 
+     243             :   memcpy(&crdboxplugin, &plugin, sizeof(molfile_plugin_t));
+     244        6946 :   crdboxplugin.name = "crdbox";
+     245        6946 :   crdboxplugin.prettyname = "AMBER Coordinates with Periodic Box";
+     246             : 
+     247        6946 :   return VMDPLUGIN_SUCCESS; 
+     248             : }
+     249             : 
+     250        6946 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     251        6946 :   (*cb)(v, (vmdplugin_t *)&plugin);
+     252        6946 :   (*cb)(v, (vmdplugin_t *)&crdboxplugin);
+     253        6946 :   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.15
+
+ + + 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 0000000000..f5db81510c --- /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:19745743.1 %
Date:2024-06-10 08:19:15Functions: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_initEv6946
_ZN4PLMD7molfile26molfile_dcdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE6946
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/dcdplugin.cpp.func.html b/coverage-libs/molfile/dcdplugin.cpp.func.html new file mode 100644 index 0000000000..3b60f60959 --- /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:19745743.1 %
Date:2024-06-10 08:19:15Functions:101952.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile26molfile_gromacsplugin_finiEv0
_ZN4PLMD7molfile26molfile_gromacsplugin_initEv6946
_ZN4PLMD7molfile30molfile_gromacsplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE6946
_ZN4PLMD7molfileL13open_g96_readEPKcS2_Pi0
_ZN4PLMD7molfileL13open_gro_readEPKcS2_Pi0
_ZN4PLMD7molfileL13open_trr_readEPKcS2_Pi108
_ZN4PLMD7molfileL14close_g96_readEPv0
_ZN4PLMD7molfileL14close_gro_readEPv0
_ZN4PLMD7molfileL14close_trr_readEPv108
_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_tE10070
_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.15
+
+ + + diff --git a/coverage-libs/molfile/gromacsplugin.cpp.gcov.html b/coverage-libs/molfile/gromacsplugin.cpp.gcov.html new file mode 100644 index 0000000000..b2b96532a8 --- /dev/null +++ b/coverage-libs/molfile/gromacsplugin.cpp.gcov.html @@ -0,0 +1,929 @@ + + + + + + + + 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:10635829.6 %
Date:2024-06-10 08:19:15Functions: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.52 $       $Date: 2016/11/28 05:01:54 $
+      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, i+1,
+     277           0 :              pos[0] / ANGS_PER_NM, pos[1] / ANGS_PER_NM, pos[2] / ANGS_PER_NM);
+     278           0 :      if(vel)
+     279             :      {
+     280           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);
+     281           0 :          vel += 3;
+     282             :      }
+     283           0 :      fprintf(gmx->mf->f, "\n");
+     284           0 :      ++atom;
+     285           0 :      pos += 3;
+     286             :   }
+     287           0 :   convert_vmd_box_for_writing(ts, x, y, z);
+     288           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]);
+     289             : 
+     290             :   return MOLFILE_SUCCESS;
+     291             : }
+     292             : 
+     293           0 : static void close_gro_write(void *v) {
+     294             :   gmxdata *gmx = (gmxdata *)v;
+     295           0 :   mdio_close(gmx->mf);
+     296           0 :   free(gmx->atomlist);
+     297           0 :   delete gmx->meta;
+     298           0 :   delete gmx;
+     299           0 : }
+     300             : 
+     301             : 
+     302           0 : static void *open_g96_read(const char *filename, const char *,
+     303             :     int *natoms) {
+     304             : 
+     305             :     md_file *mf;
+     306             :     md_header mdh;
+     307             :     char gbuf[MAX_G96_LINE + 1];
+     308             : 
+     309           0 :     mf = mdio_open(filename, MDFMT_G96);
+     310           0 :     if (!mf) {
+     311           0 :         fprintf(stderr, "gromacsplugin) Cannot open file '%s', %s\n",
+     312             :                 filename, mdio_errmsg(mdio_errno()));
+     313           0 :         return NULL;
+     314             :     }
+     315             : 
+     316             :         // read in the header data
+     317           0 :         if (g96_header(mf, mdh.title, MAX_MDIO_TITLE, &mdh.timeval) < 0) {
+     318           0 :             fprintf(stderr, "gromacsplugin) Cannot read header from '%s', %s\n",
+     319             :                     filename, mdio_errmsg(mdio_errno()));
+     320           0 :             return NULL;
+     321             :         }
+     322             : 
+     323             :         // First, look for a timestep block
+     324           0 :         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0) {
+     325           0 :             fprintf(stderr, "gromacsplugin) Cannot read header from '%s', %s\n",
+     326             :                     filename, mdio_errmsg(mdio_errno()));
+     327           0 :             return NULL;
+     328             :         }
+     329           0 :         if (!strcasecmp(gbuf, "TIMESTEP")) {
+     330             :             // Read in the value line and the END line, and the next
+     331           0 :             if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0 ||
+     332           0 :                 mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0 ||
+     333           0 :                 mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0) {
+     334           0 :               fprintf(stderr, "gromacsplugin) Cannot read header from '%s', %s\n",
+     335             :                       filename, mdio_errmsg(mdio_errno()));
+     336           0 :               return NULL;
+     337             :             }
+     338             :         }
+     339           0 :         if (strcasecmp(gbuf, "POSITION") && strcasecmp(gbuf, "REFPOSITION")) {
+     340           0 :           fprintf(stderr, "gromacsplugin) No structure information in file %s\n", filename);
+     341           0 :           return NULL;
+     342             :         }
+     343           0 :         *natoms = g96_countatoms(mf);
+     344             : 
+     345           0 :         gmxdata *gmx = new gmxdata;
+     346             :         memset(gmx,0,sizeof(gmxdata));
+     347           0 :         gmx->mf = mf;
+     348           0 :         gmx->natoms = *natoms; 
+     349           0 :         return gmx;
+     350             : }
+     351             : 
+     352           0 : static int read_g96_structure(void *mydata, int *optflags,
+     353             :     molfile_atom_t *atoms) {
+     354             : 
+     355             :     char gbuf[MAX_G96_LINE + 1];
+     356             :     gmxdata *gmx = (gmxdata *)mydata;
+     357             :     md_atom ma;
+     358           0 :     md_file *mf = gmx->mf;
+     359             : 
+     360           0 :     *optflags = MOLFILE_NOOPTIONS; // no optional data
+     361             : 
+     362           0 :         for (int i = 0; i < gmx->natoms; i++) {
+     363           0 :             molfile_atom_t *atom = atoms+i;
+     364           0 :             if (g96_rec(mf, &ma) < 0) {
+     365           0 :                 fprintf(stderr, "gromacsplugin) Error reading atom %d from file, %s\n",
+     366             :                   i+1, mdio_errmsg(mdio_errno()));
+     367           0 :                 return MOLFILE_ERROR;
+     368             :             }
+     369           0 :             strcpy(atom->name, ma.atomname);
+     370           0 :             strcpy(atom->type, ma.atomname);
+     371           0 :             strcpy(atom->resname, ma.resname);
+     372           0 :             atom->resid = atoi(ma.resid);
+     373           0 :             atom->chain[0] = '\0';
+     374           0 :             atom->segid[0] = '\0';
+     375             :         }
+     376             : 
+     377           0 :         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0) {
+     378           0 :             fprintf(stderr, "gromacsplugin) Warning, error reading END record, %s\n",
+     379             :                 mdio_errmsg(mdio_errno()));
+     380             :         }
+     381             : 
+     382             :             // ... another problem: there may or may not be a VELOCITY
+     383             :             // block or a BOX block, so we need to read one line beyond
+     384             :             // the POSITION block to determine this. If neither VEL. nor
+     385             :             // BOX are present we've read a line too far and infringed
+     386             :             // on the next timestep, so we need to keep track of the
+     387             :             // position now for a possible fseek() later to backtrack.
+     388           0 :             long fpos = ftell(mf->f);
+     389             : 
+     390             :             // Now we must read in the velocities and the box, if present
+     391           0 :             if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) >= 0) {
+     392             : 
+     393             :                 // Is there a velocity block present ?
+     394           0 :                 if (!strcasecmp(gbuf, "VELOCITY") || !strcasecmp(gbuf, "VELOCITYRED")) {
+     395             :                         // Ignore all the coordinates - VMD doesn't use them
+     396             :                         for (;;) {
+     397           0 :                                 if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0)
+     398             :                                         return MOLFILE_ERROR;
+     399           0 :                                 if (!strcasecmp(gbuf, "END")) break;
+     400             :                         }
+     401             : 
+     402             :                         // Again, record our position because we may need
+     403             :                         // to fseek here later if we read too far.
+     404           0 :                         fpos = ftell(mf->f);
+     405             : 
+     406             :                         // Go ahead and read the next line.
+     407           0 :                         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0)
+     408             :                     return MOLFILE_ERROR;
+     409             :                 }
+     410             : 
+     411             :                 // Is there a box present ?
+     412           0 :                 if (!strcasecmp(gbuf, "BOX")) {
+     413             :                         // Ignore the box coordinates at this time.
+     414           0 :                         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0)
+     415             :                     return MOLFILE_ERROR;
+     416           0 :                         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0)
+     417             :                     return MOLFILE_ERROR;
+     418           0 :                         if (strcasecmp(gbuf, "END"))
+     419             :                     return MOLFILE_ERROR;
+     420             :                 }
+     421             :                 else {
+     422             :                         // We have read too far, so fseek back to the
+     423             :                         // last known safe position so we don't return
+     424             :                         // with the file pointer set infringing on the
+     425             :                         // next timestep data.
+     426           0 :                         fseek(mf->f, fpos, SEEK_SET);
+     427             :                 }
+     428             :         }
+     429             :         else {
+     430             :             // Go ahead and rewind for good measure
+     431           0 :             fseek(mf->f, fpos, SEEK_SET);
+     432             :         }
+     433           0 :         rewind(mf->f);
+     434             :         return MOLFILE_SUCCESS;
+     435             : }
+     436             : 
+     437           0 : static int read_g96_timestep(void *v, int natoms, molfile_timestep_t *ts) {
+     438             : 
+     439             :   gmxdata *gmx = (gmxdata *)v;
+     440             :   md_ts mdts;
+     441             :   memset(&mdts, 0, sizeof(md_ts));
+     442           0 :   mdts.natoms = natoms;
+     443             : 
+     444           0 :   if (mdio_timestep(gmx->mf, &mdts) < 0)
+     445             :     return MOLFILE_ERROR;
+     446           0 :   if (ts) {
+     447           0 :     memcpy(ts->coords, mdts.pos, 3 * sizeof(float) * gmx->natoms);
+     448           0 :     if (mdts.box) {
+     449           0 :       ts->A = mdts.box->A;
+     450           0 :       ts->B = mdts.box->B;
+     451           0 :       ts->C = mdts.box->C;
+     452           0 :       ts->alpha = mdts.box->alpha;
+     453           0 :       ts->beta = mdts.box->beta;
+     454           0 :       ts->gamma = mdts.box->gamma;
+     455             :     }
+     456             :   }
+     457           0 :   mdio_tsfree(&mdts);
+     458           0 :   return MOLFILE_SUCCESS;
+     459             : }
+     460             : 
+     461           0 : static void close_g96_read(void *v) {
+     462             :   gmxdata *gmx = (gmxdata *)v;
+     463           0 :   mdio_close(gmx->mf);
+     464           0 :   delete gmx;
+     465           0 : }
+     466             : 
+     467             : 
+     468             : //
+     469             : // TRR and XTC files
+     470             : //
+     471             : 
+     472         108 : static void *open_trr_read(const char *filename, const char *filetype,
+     473             :     int *natoms) {
+     474             : 
+     475             :     md_file *mf;
+     476             :     md_header mdh;
+     477             :     gmxdata *gmx;
+     478             :     int format;
+     479             : 
+     480         108 :     if (!strcmp(filetype, "trr"))
+     481             :       format = MDFMT_TRR;
+     482         103 :     else if (!strcmp(filetype, "trj"))
+     483             :       format = MDFMT_TRJ;
+     484         103 :     else if (!strcmp(filetype, "xtc"))
+     485             :       format = MDFMT_XTC;
+     486             :     else
+     487             :       return NULL;
+     488             : 
+     489         108 :     mf = mdio_open(filename, format);
+     490         108 :     if (!mf) {
+     491           0 :         fprintf(stderr, "gromacsplugin) Cannot open file '%s', %s\n",
+     492             :                 filename, mdio_errmsg(mdio_errno()));
+     493           0 :         return NULL;
+     494             :     }
+     495         108 :     if (mdio_header(mf, &mdh) < 0) {
+     496           0 :         mdio_close(mf);
+     497           0 :         fprintf(stderr, "gromacsplugin) Cannot read header fromm '%s', %s\n",
+     498             :                 filename, mdio_errmsg(mdio_errno()));
+     499           0 :         return NULL;
+     500             :     }
+     501         108 :     *natoms = mdh.natoms;
+     502         108 :     gmx = new gmxdata;
+     503             :     memset(gmx,0,sizeof(gmxdata));
+     504         108 :     gmx->mf = mf;
+     505         108 :     gmx->natoms = mdh.natoms;
+     506         108 :     return gmx;
+     507             : }
+     508             : 
+     509       10070 : static int read_trr_timestep(void *v, int natoms, molfile_timestep_t *ts) {
+     510             :   gmxdata *gmx = (gmxdata *)v;
+     511             :   md_ts mdts;
+     512             :   memset(&mdts, 0, sizeof(md_ts));
+     513       10070 :   mdts.natoms = natoms;
+     514             : 
+     515       10070 :   if (mdio_timestep(gmx->mf, &mdts) < 0) {
+     516         108 :     if (mdio_errno() == MDIO_EOF || mdio_errno() == MDIO_IOERROR) {
+     517             :       // XXX Lame, why does mdio treat IOERROR like EOF?
+     518             :       return MOLFILE_ERROR;
+     519             :     }
+     520           0 :     fprintf(stderr, "gromacsplugin) Error reading timestep, %s\n",
+     521             :             mdio_errmsg(mdio_errno()));
+     522           0 :     return MOLFILE_ERROR;
+     523             :   }
+     524        9962 :   if (mdts.natoms != natoms) {
+     525           0 :     fprintf(stderr, "gromacsplugin) Timestep in file contains wrong number of atoms\n");
+     526           0 :     fprintf(stderr, "gromacsplugin) Found %d, expected %d\n", mdts.natoms, natoms);
+     527           0 :     mdio_tsfree(&mdts);
+     528           0 :     return MOLFILE_ERROR;
+     529             :   }
+     530             : 
+     531        9962 :   if (ts) {
+     532        9962 :     memcpy(ts->coords, mdts.pos, 3 * sizeof(float) * gmx->natoms);
+     533        9962 :     if (mdts.box) {
+     534        9962 :       ts->A = mdts.box->A;
+     535        9962 :       ts->B = mdts.box->B;
+     536        9962 :       ts->C = mdts.box->C;
+     537        9962 :       ts->alpha = mdts.box->alpha;
+     538        9962 :       ts->beta = mdts.box->beta;
+     539        9962 :       ts->gamma = mdts.box->gamma;
+     540             :     }
+     541             :   }
+     542        9962 :   mdio_tsfree(&mdts);
+     543        9962 :   return MOLFILE_SUCCESS;
+     544             : }
+     545             : 
+     546         108 : static void close_trr_read(void *v) {
+     547             :   gmxdata *gmx = (gmxdata *)v;
+     548         108 :   mdio_close(gmx->mf);
+     549         108 :   delete gmx;
+     550         108 : }
+     551             : 
+     552             : // open file for writing
+     553           0 : static void *open_trr_write(const char *filename, const char *filetype,
+     554             :     int natoms) {
+     555             : 
+     556             :     md_file *mf;
+     557             :     gmxdata *gmx;
+     558             :     int format;
+     559             : 
+     560           0 :     if (!strcmp(filetype, "trr"))
+     561             :       format = MDFMT_TRR;
+     562           0 :     else if (!strcmp(filetype, "xtc"))
+     563             :       format = MDFMT_XTC;
+     564             :     else
+     565             :       return NULL;
+     566             : 
+     567           0 :     mf = mdio_open(filename, format, MDIO_WRITE);
+     568           0 :     if (!mf) {
+     569           0 :         fprintf(stderr, "gromacsplugin) Cannot open file '%s', %s\n",
+     570             :                 filename, mdio_errmsg(mdio_errno()));
+     571           0 :         return NULL;
+     572             :     }
+     573           0 :     gmx = new gmxdata;
+     574             :     memset(gmx,0,sizeof(gmxdata));
+     575           0 :     gmx->mf = mf;
+     576           0 :     gmx->natoms = natoms;
+     577             :     // set some parameters for the output stream:
+     578             :     // start at step 0, convert to big-endian, write single precision.
+     579             :     gmx->step   = 0;
+     580           0 :     gmx->mf->rev = host_is_little_endian();
+     581           0 :     gmx->mf->prec = sizeof(float);
+     582           0 :     return gmx;
+     583             : }
+     584             : 
+     585             : // write a trr timestep. the file format has a header with each record
+     586           0 : static int write_trr_timestep(void *mydata, const molfile_timestep_t *ts)
+     587             : {
+     588             :   const float nm=0.1;
+     589             : 
+     590             :   gmxdata *gmx = (gmxdata *)mydata;
+     591             : 
+     592             :   // determine and write header from structure info.
+     593             :   // write trr header. XXX: move this to Gromacs.h ??
+     594           0 :   if (gmx->mf->fmt == MDFMT_TRR) {
+     595             :     int i;
+     596             : 
+     597           0 :     if ( put_trx_int(gmx->mf, TRX_MAGIC)            // ID
+     598           0 :          || put_trx_string(gmx->mf, "GMX_trn_file") // version
+     599           0 :          || put_trx_int(gmx->mf, 0)                 // ir_size (ignored)
+     600           0 :          || put_trx_int(gmx->mf, 0)                 // e_size (ignored)
+     601           0 :          || put_trx_int(gmx->mf, 9*sizeof(float))   // box
+     602           0 :          || put_trx_int(gmx->mf, 0)                 // vir_size (ignored)
+     603           0 :          || put_trx_int(gmx->mf, 0)                 // pres_size (ignored)
+     604           0 :          || put_trx_int(gmx->mf, 0)                 // top_size (ignored)
+     605           0 :          || put_trx_int(gmx->mf, 0)                 // sym_size (ignored)
+     606           0 :          || put_trx_int(gmx->mf, 3*sizeof(float)*gmx->natoms) // coordinates
+     607           0 :          || put_trx_int(gmx->mf, 0)                 // no velocities
+     608           0 :          || put_trx_int(gmx->mf, 0)                 // no forces
+     609           0 :          || put_trx_int(gmx->mf, gmx->natoms)       // number of atoms
+     610           0 :          || put_trx_int(gmx->mf, gmx->step)         // current step number
+     611           0 :          || put_trx_int(gmx->mf, 0)                 // nre (ignored)
+     612           0 :          || put_trx_real(gmx->mf, 0.1*gmx->step)    // current time. (dummy value: 0.1)
+     613           0 :          || put_trx_real(gmx->mf, 0.0))             // current lambda
+     614           0 :       return MOLFILE_ERROR;
+     615             : 
+     616             :     // set up box according to the VMD unitcell conventions.
+     617             :     // the a-vector is collinear with the x-axis and
+     618             :     // the b-vector is in the xy-plane.
+     619           0 :     const float sa = sin((double)ts->alpha/180.0*M_PI);
+     620           0 :     const float ca = cos((double)ts->alpha/180.0*M_PI);
+     621           0 :     const float cb = cos((double)ts->beta/180.0*M_PI);
+     622           0 :     const float cg = cos((double)ts->gamma/180.0*M_PI);
+     623           0 :     const float sg = sin((double)ts->gamma/180.0*M_PI);
+     624             :     float box[9];
+     625           0 :     box[0] = ts->A;    box[1] = 0.0;      box[2] = 0.0;
+     626           0 :     box[3] = ts->B*ca; box[4] = ts->B*sa; box[5] = 0.0;
+     627           0 :     box[6] = ts->C*cb; box[7] = ts->C*(ca - cb*cg)/sg;
+     628           0 :     box[8] = ts->C*sqrt((double)(1.0 + 2.0*ca*cb*cg
+     629           0 :                                  - ca*ca - cb*cb - cg*cg)/(1.0 - cg*cg));
+     630             : 
+     631           0 :     for (i=0; i<9; ++i) {
+     632           0 :       if (put_trx_real(gmx->mf, box[i]*nm))
+     633             :         return MOLFILE_ERROR;
+     634             :     }
+     635             : #ifdef TEST_TRR_PLUGIN
+     636             :     fprintf(stderr, "gromacsplugin) box is:\n %f %f %f\n %f %f %f\n %f %f %f\n\n",
+     637             :             box[0], box[1], box[2], box[3], box[4], box[5], box[6], box[7], box[8]);
+     638             : #endif
+     639             : 
+     640             :     // write coordinates
+     641           0 :     for (i=0; i<(3*gmx->natoms); ++i) {
+     642           0 :       if (put_trx_real(gmx->mf, ts->coords[i]*nm))
+     643             :         return MOLFILE_ERROR;
+     644             :     }
+     645             :   } else {
+     646           0 :     fprintf(stderr, "gromacsplugin) only .trr is supported for writing\n");
+     647           0 :     return MOLFILE_ERROR;
+     648             :   }
+     649             : 
+     650           0 :   ++ gmx->step;
+     651           0 :   return MOLFILE_SUCCESS;
+     652             :   }
+     653             : 
+     654             : 
+     655           0 : static void close_trr_write(void *v) {
+     656             :   gmxdata *gmx = (gmxdata *)v;
+     657           0 :   mdio_close(gmx->mf);
+     658           0 :   delete gmx;
+     659           0 : }
+     660             : 
+     661             : #define GROMACS_PLUGIN_MAJOR_VERSION 1
+     662             : #define GROMACS_PLUGIN_MINOR_VERSION 2 
+     663             : 
+     664             : //
+     665             : // plugin registration stuff below
+     666             : //
+     667             : 
+     668             : static molfile_plugin_t gro_plugin;
+     669             : static molfile_plugin_t g96_plugin;
+     670             : static molfile_plugin_t trr_plugin;
+     671             : static molfile_plugin_t xtc_plugin;
+     672             : static molfile_plugin_t trj_plugin;
+     673             : 
+     674             : 
+     675        6946 : VMDPLUGIN_API int VMDPLUGIN_init() {
+     676             :   // GRO plugin init
+     677             :   memset(&gro_plugin, 0, sizeof(molfile_plugin_t));
+     678        6946 :   gro_plugin.abiversion = vmdplugin_ABIVERSION;
+     679        6946 :   gro_plugin.type = MOLFILE_PLUGIN_TYPE;
+     680        6946 :   gro_plugin.name = "gro";
+     681        6946 :   gro_plugin.prettyname = "Gromacs GRO";
+     682        6946 :   gro_plugin.author = "David Norris, Justin Gullingsrud, Magnus Lundborg";
+     683        6946 :   gro_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     684        6946 :   gro_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     685             :   gro_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     686        6946 :   gro_plugin.filename_extension = "gro";
+     687        6946 :   gro_plugin.open_file_read = open_gro_read;
+     688        6946 :   gro_plugin.read_structure = read_gro_structure;
+     689        6946 :   gro_plugin.read_next_timestep = read_gro_timestep;
+     690        6946 :   gro_plugin.close_file_read = close_gro_read;
+     691        6946 :   gro_plugin.open_file_write = open_gro_write;
+     692        6946 :   gro_plugin.write_structure = write_gro_structure;
+     693        6946 :   gro_plugin.write_timestep = write_gro_timestep;
+     694        6946 :   gro_plugin.close_file_write = close_gro_write;
+     695        6946 :   gro_plugin.read_molecule_metadata = read_gro_molecule_metadata;
+     696             : 
+     697             :   // G96 plugin init
+     698             :   memset(&g96_plugin, 0, sizeof(molfile_plugin_t));
+     699        6946 :   g96_plugin.abiversion = vmdplugin_ABIVERSION;
+     700        6946 :   g96_plugin.type = MOLFILE_PLUGIN_TYPE;
+     701        6946 :   g96_plugin.name = "g96";
+     702        6946 :   g96_plugin.prettyname = "Gromacs g96";
+     703        6946 :   g96_plugin.author = "David Norris, Justin Gullingsrud";
+     704        6946 :   g96_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     705        6946 :   g96_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     706             :   g96_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     707        6946 :   g96_plugin.filename_extension = "g96";
+     708        6946 :   g96_plugin.open_file_read = open_g96_read;
+     709        6946 :   g96_plugin.read_structure = read_g96_structure;
+     710        6946 :   g96_plugin.read_next_timestep = read_g96_timestep;
+     711        6946 :   g96_plugin.close_file_read = close_g96_read;
+     712             : 
+     713             :   // TRR plugin
+     714             :   memset(&trr_plugin, 0, sizeof(molfile_plugin_t));
+     715        6946 :   trr_plugin.abiversion = vmdplugin_ABIVERSION;
+     716        6946 :   trr_plugin.type = MOLFILE_PLUGIN_TYPE;
+     717        6946 :   trr_plugin.name = "trr";
+     718        6946 :   trr_plugin.prettyname = "Gromacs TRR Trajectory";
+     719        6946 :   trr_plugin.author = "David Norris, Justin Gullingsrud, Axel Kohlmeyer";
+     720        6946 :   trr_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     721        6946 :   trr_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     722             :   trr_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     723        6946 :   trr_plugin.filename_extension = "trr";
+     724        6946 :   trr_plugin.open_file_read = open_trr_read;
+     725        6946 :   trr_plugin.read_next_timestep = read_trr_timestep;
+     726        6946 :   trr_plugin.close_file_read = close_trr_read;
+     727        6946 :   trr_plugin.open_file_write = open_trr_write;
+     728        6946 :   trr_plugin.write_timestep = write_trr_timestep;
+     729        6946 :   trr_plugin.close_file_write = close_trr_write;
+     730             : 
+     731             :   // XTC plugin 
+     732             :   memset(&xtc_plugin, 0, sizeof(molfile_plugin_t));
+     733        6946 :   xtc_plugin.abiversion = vmdplugin_ABIVERSION;
+     734        6946 :   xtc_plugin.type = MOLFILE_PLUGIN_TYPE;
+     735        6946 :   xtc_plugin.name = "xtc";
+     736        6946 :   xtc_plugin.prettyname = "Gromacs XTC Compressed Trajectory";
+     737        6946 :   xtc_plugin.author = "David Norris, Justin Gullingsrud";
+     738        6946 :   xtc_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     739        6946 :   xtc_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     740             :   xtc_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     741        6946 :   xtc_plugin.filename_extension = "xtc";
+     742        6946 :   xtc_plugin.open_file_read = open_trr_read;
+     743        6946 :   xtc_plugin.read_next_timestep = read_trr_timestep;
+     744        6946 :   xtc_plugin.close_file_read = close_trr_read;
+     745             : 
+     746             :   // TRJ plugin
+     747             :   memset(&trj_plugin, 0, sizeof(molfile_plugin_t));
+     748        6946 :   trj_plugin.abiversion = vmdplugin_ABIVERSION;
+     749        6946 :   trj_plugin.type = MOLFILE_PLUGIN_TYPE;
+     750        6946 :   trj_plugin.name = "trj";
+     751        6946 :   trj_plugin.prettyname = "Gromacs TRJ Trajectory";
+     752        6946 :   trj_plugin.author = "David Norris, Justin Gullingsrud";
+     753        6946 :   trj_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     754        6946 :   trj_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     755             :   trj_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     756        6946 :   trj_plugin.filename_extension = "trj";
+     757        6946 :   trj_plugin.open_file_read = open_trr_read;
+     758        6946 :   trj_plugin.read_next_timestep = read_trr_timestep;
+     759        6946 :   trj_plugin.close_file_read = close_trr_read;
+     760             : 
+     761        6946 :   return 0;
+     762             : }
+     763             : 
+     764        6946 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     765        6946 :   (*cb)(v, (vmdplugin_t *)&gro_plugin);
+     766        6946 :   (*cb)(v, (vmdplugin_t *)&g96_plugin);
+     767        6946 :   (*cb)(v, (vmdplugin_t *)&trr_plugin);
+     768        6946 :   (*cb)(v, (vmdplugin_t *)&trj_plugin);
+     769        6946 :   (*cb)(v, (vmdplugin_t *)&xtc_plugin);
+     770        6946 :   return 0;
+     771             : }
+     772             : 
+     773           0 : VMDPLUGIN_API int VMDPLUGIN_fini() {
+     774           0 :   return 0;
+     775             : }
+     776             : 
+     777             : }
+     778             : }
+     779             : 
+     780             : 
+     781             : #ifdef TEST_G96_PLUGIN
+     782             : 
+     783             : int main(int argc, char *argv[]) {
+     784             :   int natoms;
+     785             : 
+     786             :   molfile_timestep_t timestep;
+     787             :   void *v;
+     788             :   int i;
+     789             : 
+     790             :   if (argc < 2) return 1;
+     791             :   while (--argc) {
+     792             :     ++argv;
+     793             :     v = open_g96_read(*argv, "g96", &natoms);
+     794             :     if (!v) {
+     795             :       fprintf(stderr, "open_g96_read failed for file %s\n", *argv);
+     796             :       return 1;
+     797             :     }
+     798             :     timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
+     799             :     i = 0;
+     800             :     while(!read_g96_timestep(v, natoms, &timestep)) {
+     801             :       ++i;
+     802             :     }
+     803             :     fprintf(stderr, "ended read_g96_timestep on step %d\n", i);
+     804             :     free(timestep.coords);
+     805             :     close_g96_read(v);
+     806             :   }
+     807             :   return 0;
+     808             : }
+     809             : 
+     810             : #endif
+     811             : 
+     812             : #ifdef TEST_TRR_PLUGIN
+     813             : 
+     814             : int main(int argc, char *argv[]) {
+     815             :   int natoms;
+     816             : 
+     817             :   molfile_timestep_t timestep;
+     818             :   void *v, *w;
+     819             :   int i;
+     820             : 
+     821             :   if (argc != 3) return 1;
+     822             :   v = open_trr_read(argv[1], "trr", &natoms);
+     823             :   if (!v) {
+     824             :     fprintf(stderr, "open_trr_read failed for file %s\n", argv[1]);
+     825             :     return 1;
+     826             :   }
+     827             :   timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
+     828             :   w = open_trr_write(argv[2], "trr", natoms);
+     829             :   if (!w) {
+     830             :     fprintf(stderr, "open_trr_write failed for file %s\n", argv[2]);
+     831             :     return 1;
+     832             :   }
+     833             : 
+     834             :   i = 0;
+     835             :   while(!read_trr_timestep(v, natoms, &timestep)) {
+     836             :     ++i;
+     837             :     if (write_trr_timestep(w, &timestep)) {
+     838             :       fprintf(stderr, "write error\n");
+     839             :       return 1;
+     840             :     }
+     841             :   }
+     842             : 
+     843             :   fprintf(stderr, "ended read_trr_timestep on step %d\n", i);
+     844             :   free(timestep.coords);
+     845             :   close_trr_read(v);
+     846             :   close_trr_write(w);
+     847             :   return 0;
+     848             : }
+     849             : 
+     850             : #endif
+     851             : 
+     852             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/index-sort-f.html b/coverage-libs/molfile/index-sort-f.html new file mode 100644 index 0000000000..5cca32ba3f --- /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:856209740.8 %
Date:2024-06-10 08:19:15Functions: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.6%29.6%
+
29.6 %106 / 35821.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.1%43.1%
+
43.1 %197 / 45752.6 %10 / 19
crdplugin.cpp +
64.7%64.7%
+
64.7 %55 / 8555.6 %5 / 9
Gromacs.h +
45.7%45.7%
+
45.7 %342 / 74961.1 %22 / 36
fastio.h +
55.9%55.9%
+
55.9 %19 / 3471.4 %5 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/index-sort-l.html b/coverage-libs/molfile/index-sort-l.html new file mode 100644 index 0000000000..6aa2a025bd --- /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:856209740.8 %
Date:2024-06-10 08:19:15Functions: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.6%29.6%
+
29.6 %106 / 35821.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.1%43.1%
+
43.1 %197 / 45752.6 %10 / 19
Gromacs.h +
45.7%45.7%
+
45.7 %342 / 74961.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.15
+
+ + + diff --git a/coverage-libs/molfile/index.html b/coverage-libs/molfile/index.html new file mode 100644 index 0000000000..4564f50669 --- /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:856209740.8 %
Date:2024-06-10 08:19:15Functions:5612445.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Gromacs.h +
45.7%45.7%
+
45.7 %342 / 74961.1 %22 / 36
crdplugin.cpp +
64.7%64.7%
+
64.7 %55 / 8555.6 %5 / 9
dcdplugin.cpp +
43.1%43.1%
+
43.1 %197 / 45752.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.6%29.6%
+
29.6 %106 / 35821.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.15
+
+ + + 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 0000000000..d83edeb57b --- /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-06-10 08:19:15Functions: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_Pi48
_ZN4PLMD7molfileL14close_pdb_readEPv48
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE107
_ZN4PLMD7molfile22molfile_pdbplugin_initEv6946
_ZN4PLMD7molfile26molfile_pdbplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE6946
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/pdbplugin.cpp.func.html b/coverage-libs/molfile/pdbplugin.cpp.func.html new file mode 100644 index 0000000000..58731e9b7c --- /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-06-10 08:19:15Functions:51435.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_pdbplugin_finiEv0
_ZN4PLMD7molfile22molfile_pdbplugin_initEv6946
_ZN4PLMD7molfile26molfile_pdbplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE6946
_ZN4PLMD7molfileL10read_bondsEPvPiPS2_S3_PPfS3_S2_PPPc0
_ZN4PLMD7molfileL12write_cryst1EP8_IO_FILEPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL13open_pdb_readEPKcS2_Pi48
_ZN4PLMD7molfileL14close_pdb_readEPv48
_ZN4PLMD7molfileL14write_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL15open_file_writeEPKcS2_i0
_ZN4PLMD7molfileL15write_structureEPviPKNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL16close_file_writeEPv0
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE107
_ZN4PLMD7molfileL18read_pdb_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL22read_molecule_metadataEPvPPNS0_18molfile_metadata_tE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/pdbplugin.cpp.gcov.html b/coverage-libs/molfile/pdbplugin.cpp.gcov.html new file mode 100644 index 0000000000..bcb89d0e3a --- /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-06-10 08:19:15Functions: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          48 : 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          48 :   fd = fopen(filepath, "r");
+      95          48 :   if (!fd) 
+      96             :     return NULL;
+      97          48 :   pdb = (pdbdata *)malloc(sizeof(pdbdata));
+      98          48 :   pdb->fd = fd;
+      99          48 :   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          48 :   *natoms=0;
+     106             :   nconect=0;
+     107             :   do {
+     108      100481 :     indx = read_pdb_record(pdb->fd, pdbstr);
+     109      100481 :     if (indx == PDB_ATOM) {
+     110      100260 :       *natoms += 1;
+     111         221 :     } else if (indx == PDB_CONECT) {
+     112           0 :       nconect++;
+     113         221 :     } 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         221 :     } else if (indx == PDB_REMARK || indx == PDB_CONECT || indx == PDB_UNKNOWN) {
+     118         142 :       int len=strlen(pdbstr);
+     119         142 :       int newlen = len + pdb->meta->remarklen;
+     120             : 
+     121         142 :       char *newstr=(char*)realloc(pdb->meta->remarks, newlen + 1);
+     122         142 :       if (newstr != NULL) {
+     123         142 :         pdb->meta->remarks = newstr;
+     124         142 :         pdb->meta->remarks[pdb->meta->remarklen] = '\0';
+     125         142 :         memcpy(pdb->meta->remarks + pdb->meta->remarklen, pdbstr, len);
+     126         142 :         pdb->meta->remarks[newlen] = '\0';
+     127         142 :         pdb->meta->remarklen = newlen;
+     128             :       }
+     129             :     }
+     130             :  
+     131      100481 :   } while (indx != PDB_END && indx != PDB_EOF);
+     132             : 
+     133             :   /* If no atoms were found, this is probably not a PDB file! */
+     134          48 :   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          48 :   rewind(pdb->fd); /* if ok, rewind file and prepare to parse it for real */
+     145          48 :   pdb->natoms = *natoms;
+     146          48 :   pdb->nconect = nconect;
+     147          48 :   pdb->nbonds = 0;
+     148          48 :   pdb->maxbnum = 0;
+     149          48 :   pdb->from = NULL;
+     150          48 :   pdb->to = NULL;
+     151          48 :   pdb->idxmap = NULL;
+     152          48 :   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          48 :   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         107 : 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         107 :   if (pdb->natoms == 0) 
+     286             :     return MOLFILE_ERROR; /* EOF */
+     287         107 :   if (ts) {
+     288         107 :     x = ts->coords;
+     289         107 :     y = x+1;
+     290         107 :     z = x+2;
+     291             :   } else {
+     292             :     x = y = z = 0;
+     293             :   } 
+     294             :   i = 0;
+     295             :   do {
+     296      104656 :     indx = read_pdb_record(pdb->fd, pdbstr);
+     297      104656 :     if((indx == PDB_END || indx == PDB_EOF) && (i < pdb->natoms)) {
+     298             :       return MOLFILE_ERROR;
+     299      104608 :     } else if(indx == PDB_ATOM) {
+     300      104358 :       if(i++ >= pdb->natoms) {
+     301             :         break;      
+     302             :       }
+     303             :       /* just get the coordinates, and store them */
+     304      104358 :       if (ts) {
+     305      104358 :         get_pdb_coordinates(pdbstr, x, y, z, &occup, &bfac);
+     306      104358 :         x += 3;
+     307      104358 :         y += 3;
+     308      104358 :         z += 3;
+     309             :       } 
+     310         250 :     } else if (indx == PDB_CRYST1) {
+     311          33 :       if (ts) {
+     312          33 :         get_pdb_cryst1(pdbstr, &ts->alpha, &ts->beta, &ts->gamma,
+     313             :                                &ts->A, &ts->B, &ts->C);
+     314             :       }
+     315             :     }
+     316      104608 :   } while(!(indx == PDB_END || indx == PDB_EOF));
+     317             : 
+     318             :   return MOLFILE_SUCCESS;
+     319             : }
+     320             : 
+     321          48 : static void close_pdb_read(void *v) { 
+     322             :   pdbdata *pdb = (pdbdata *)v;
+     323          48 :   if (pdb->fd != NULL)
+     324          48 :     fclose(pdb->fd);
+     325          48 :   if (pdb->idxmap != NULL)
+     326           0 :     free(pdb->idxmap);
+     327          48 :   if (pdb->meta->remarks != NULL)
+     328          38 :     free(pdb->meta->remarks);
+     329          48 :   if (pdb->meta != NULL) 
+     330          48 :     free(pdb->meta);
+     331          48 :   free(pdb);
+     332          48 : }
+     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        6946 : VMDPLUGIN_API int VMDPLUGIN_init() {
+     613             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+     614        6946 :   plugin.abiversion = vmdplugin_ABIVERSION;
+     615        6946 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+     616        6946 :   plugin.name = "pdb";
+     617        6946 :   plugin.prettyname = "PDB";
+     618        6946 :   plugin.author = "Justin Gullingsrud, John Stone";
+     619        6946 :   plugin.majorv = 1;
+     620        6946 :   plugin.minorv = 16;
+     621        6946 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+     622        6946 :   plugin.filename_extension = "pdb,ent";
+     623        6946 :   plugin.open_file_read = open_pdb_read;
+     624        6946 :   plugin.read_structure = read_pdb_structure;
+     625        6946 :   plugin.read_bonds = read_bonds;
+     626        6946 :   plugin.read_next_timestep = read_next_timestep;
+     627        6946 :   plugin.close_file_read = close_pdb_read;
+     628        6946 :   plugin.open_file_write = open_file_write;
+     629        6946 :   plugin.write_structure = write_structure;
+     630        6946 :   plugin.write_timestep = write_timestep;
+     631        6946 :   plugin.close_file_write = close_file_write;
+     632        6946 :   plugin.read_molecule_metadata = read_molecule_metadata;
+     633        6946 :   return VMDPLUGIN_SUCCESS;
+     634             : }
+     635             : 
+     636        6946 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     637        6946 :   (*cb)(v, (vmdplugin_t *)&plugin);
+     638        6946 :   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.15
+
+ + + 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 0000000000..2ad31db0af --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..806ba752b2 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..1cdadd980e --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..4866c2d3eb --- /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-06-10 08:19:15Functions: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_33
_ZN4PLMD7molfileL19get_pdb_coordinatesEPKcPfS3_S3_S3_S3_104358
_ZN4PLMD7molfileL15read_pdb_recordEP8_IO_FILEPc205137
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/readpdb.h.func.html b/coverage-libs/molfile/readpdb.h.func.html new file mode 100644 index 0000000000..361b195e59 --- /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-06-10 08:19:15Functions: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_33
_ZN4PLMD7molfileL14get_pdb_fieldsEPKciPiPcS4_S4_S4_S4_S4_S4_S4_PfS5_S5_S5_S5_0
_ZN4PLMD7molfileL14get_pdb_headerEPKcPcS3_S3_0
_ZN4PLMD7molfileL15read_pdb_recordEP8_IO_FILEPc205137
_ZN4PLMD7molfileL19get_pdb_coordinatesEPKcPfS3_S3_S3_S3_104358
_ZN4PLMD7molfileL20write_raw_pdb_recordEP8_IO_FILEPKciS4_S4_iS4_S4_S4_fffffS4_S4_0
_ZN4PLMD7molfileL23adjust_pdb_field_stringEPc0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage-libs/molfile/readpdb.h.gcov.html b/coverage-libs/molfile/readpdb.h.gcov.html new file mode 100644 index 0000000000..2f4cef3efd --- /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-06-10 08:19:15Functions: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      205137 : 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      205137 :   if (inbuf != fgets(inbuf, PDB_RECORD_LENGTH + 2, f)) {
+      93          48 :     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      205089 :     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         471 :     } else if (!strncmp(inbuf, "CONECT", 6)) {
+     113             :       recType = PDB_CONECT;
+     114         471 :     } else if (!strncmp(inbuf, "REMARK", 6)) {
+     115             :       recType = PDB_REMARK;
+     116         377 :     } else if (!strncmp(inbuf, "CRYST1", 6)) {
+     117             :       recType = PDB_CRYST1;
+     118         313 :     } else if (!strncmp(inbuf, "HEADER", 6)) {
+     119             :       recType = PDB_HEADER;
+     120         313 :     } 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      205137 :   ch = fgetc(f);
+     146      205137 :   if (ch != '\r')
+     147      205137 :     ungetc(ch, f);
+     148             :   
+     149      205137 :   return recType;
+     150             : }
+     151             : 
+     152             : 
+     153             : /* Extract the alpha/beta/gamma a/b/c unit cell info from a CRYST1 record */
+     154          33 : 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          33 :   s = tmp+6 ;          ch = tmp[15]; tmp[15] = 0;
+     163          33 :   *a = (float) atof(s);
+     164          33 :   s = tmp+15; *s = ch; ch = tmp[24]; tmp[24] = 0;
+     165          33 :   *b = (float) atof(s);
+     166          33 :   s = tmp+24; *s = ch; ch = tmp[33]; tmp[33] = 0;
+     167          33 :   *c = (float) atof(s);
+     168          33 :   s = tmp+33; *s = ch; ch = tmp[40]; tmp[40] = 0;
+     169          33 :   *alpha = (float) atof(s);
+     170          33 :   s = tmp+40; *s = ch; ch = tmp[47]; tmp[47] = 0;
+     171          33 :   *beta = (float) atof(s);
+     172          33 :   s = tmp+47; *s = ch; ch = tmp[54]; tmp[54] = 0;
+     173          33 :   *gamma = (float) atof(s);
+     174          33 : }
+     175             : 
+     176             : 
+     177             : /* Extract the x,y,z coords, occupancy, and beta from an ATOM record */
+     178      104358 : 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      104358 :   if (x != NULL) {
+     185      104358 :     strncpy(numstr, record + 30, 8);
+     186      104358 :     *x = (float) atof(numstr);
+     187             :   }
+     188             : 
+     189      104358 :   if (y != NULL) {
+     190      104358 :     strncpy(numstr+10, record + 38, 8);
+     191      104358 :     *y = (float) atof(numstr+10);
+     192             :   }
+     193             : 
+     194      104358 :   if (z != NULL) {
+     195      104358 :     strncpy(numstr+20, record + 46, 8);
+     196      104358 :     *z = (float) atof(numstr+20);
+     197             :   }
+     198             : 
+     199      104358 :   if (occup != NULL) {
+     200      104358 :     strncpy(numstr+30, record + 54, 6);
+     201      104358 :     *occup = (float) atof(numstr+30);
+     202             :   }
+     203             : 
+     204      104358 :   if (beta != NULL) {
+     205      104358 :     strncpy(numstr+40, record + 60, 6);
+     206      104358 :     *beta = (float) atof(numstr+40);
+     207             :   }
+     208      104358 : }
+     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             :     sprintf(indexbuf, "%5d", index);
+     410           0 :   } else if (index < 1048576) {
+     411             :     sprintf(indexbuf, "%05x", index);
+     412             :   } else {
+     413             :     sprintf(indexbuf, "*****");
+     414             :   }
+     415             : 
+     416           0 :   if (resid < 10000) {
+     417             :     sprintf(residbuf, "%4d", resid);
+     418           0 :   } else if (resid < 65536) {
+     419             :     sprintf(residbuf, "%04x", resid);
+     420             :   } else { 
+     421             :     sprintf(residbuf, "****");
+     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.15
+
+ + + 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 0000000000..230169f9fe --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/xdrfile/index-sort-l.html b/coverage-libs/xdrfile/index-sort-l.html new file mode 100644 index 0000000000..825cdccefd --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/xdrfile/index.html b/coverage-libs/xdrfile/index.html new file mode 100644 index 0000000000..74addd3b80 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..f1370c9ab5 --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile.cpp.func.html b/coverage-libs/xdrfile/xdrfile.cpp.func.html new file mode 100644 index 0000000000..ec8a01540a --- /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-06-10 08:19:15Functions: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.15
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile.cpp.gcov.html b/coverage-libs/xdrfile/xdrfile.cpp.gcov.html new file mode 100644 index 0000000000..8416fcd245 --- /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-06-10 08:19:15Functions: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             :                 sprintf(newmode,"wb+");
+     236             :                 xdrmode=XDR_ENCODE;
+     237          10 :         } else if(*mode == 'a' || *mode == 'A') 
+     238             :     {
+     239             :                 sprintf(newmode,"ab+");
+     240             :                 xdrmode = XDR_ENCODE;
+     241          10 :         } else if(*mode == 'r' || *mode == 'R')
+     242             :     {
+     243             :                 sprintf(newmode,"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.15
+
+ + + 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 0000000000..b4488813d8 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..627d00a57f --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..048aabfa2d --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..5cc928df6d --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..1618de894c --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..0107c2e1a2 --- /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-06-10 08:19:15Functions: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.15
+
+ + + 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 0000000000..d2249213b4 --- /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-06-10 08:19:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ActionWithInputMatrixC1ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getBaseMultiColvarERKj7
_ZN4PLMD6adjmat21ActionWithInputMatrixC2ERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat21ActionWithInputMatrix16registerKeywordsERNS_8KeywordsE32
_ZNK4PLMD6adjmat21ActionWithInputMatrix23getNumberOfAtomsInGroupERKj34
_ZNK4PLMD6adjmat21ActionWithInputMatrix20getNumberOfNodeTypesEv66
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getAbsoluteIndexOfCentralAtomERKj504
_ZNK4PLMD6adjmat21ActionWithInputMatrix24addConnectionDerivativesERKjS3_RNS_10MultiValueES5_1440
_ZNK4PLMD6adjmat21ActionWithInputMatrix19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE1679
_ZNK4PLMD6adjmat21ActionWithInputMatrix12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE2004
_ZNK4PLMD6adjmat21ActionWithInputMatrix21getNumberOfQuantitiesEv2181
_ZN4PLMD6adjmat21ActionWithInputMatrix22getNumberOfDerivativesEv13250
_ZNK4PLMD6adjmat21ActionWithInputMatrix23retrieveConnectionValueERKjS3_RSt6vectorIdSaIdEE46452
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getPositionOfAtomForLinkCellsERKj54763
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getAdjacencyVesselEv78058
_ZNK4PLMD6adjmat21ActionWithInputMatrix16getNumberOfNodesEv16261547
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.cpp.func.html b/coverage/adjmat/ActionWithInputMatrix.cpp.func.html new file mode 100644 index 0000000000..8173adc464 --- /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-06-10 08:19:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ActionWithInputMatrix16registerKeywordsERNS_8KeywordsE32
_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.15
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.cpp.gcov.html b/coverage/adjmat/ActionWithInputMatrix.cpp.gcov.html new file mode 100644 index 0000000000..212cefe956 --- /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-06-10 08:19:14Functions: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          32 : void ActionWithInputMatrix::registerKeywords( Keywords& keys ) {
+      33          32 :   MultiColvarBase::registerKeywords( keys );
+      34          64 :   keys.add("compulsory","MATRIX","the action that calculates the adjacency matrix vessel we would like to analyze");
+      35          32 : }
+      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.15
+
+ + + 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 0000000000..120da03376 --- /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-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat21ActionWithInputMatrix7computeERKjRNS_11multicolvar13AtomValuePackE0
_ZN4PLMD6adjmat21ActionWithInputMatrix10isPeriodicEv80
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.h.func.html b/coverage/adjmat/ActionWithInputMatrix.h.func.html new file mode 100644 index 0000000000..8a04d287b8 --- /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-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ActionWithInputMatrix10isPeriodicEv80
_ZNK4PLMD6adjmat21ActionWithInputMatrix7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.h.gcov.html b/coverage/adjmat/ActionWithInputMatrix.h.gcov.html new file mode 100644 index 0000000000..a588d38c25 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..26574ab7e6 --- /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:8610185.1 %
Date:2024-06-10 08:19:14Functions: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_8KeywordsE29
_ZN4PLMD6adjmat19AdjacencyMatrixBase27parseConnectionDescriptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbRKj46
_ZNK4PLMD6adjmat19AdjacencyMatrixBase20getNumberOfNodeTypesEv132
_ZNK4PLMD6adjmat19AdjacencyMatrixBase21getSizeOfInputVectorsEv5807
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html new file mode 100644 index 0000000000..941af439a6 --- /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:8610185.1 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase16registerKeywordsERNS_8KeywordsE29
_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.15
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html new file mode 100644 index 0000000000..d39a5087d5 --- /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:8610185.1 %
Date:2024-06-10 08:19:14Functions: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          29 : void AdjacencyMatrixBase::registerKeywords( Keywords& keys ) {
+      33          29 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      34          58 :   keys.remove("LOWMEM"); keys.use("HIGHMEM");
+      35          29 : }
+      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          23 :   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.15
+
+ + + 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 0000000000..f63d63aee1 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase10isPeriodicEv25
_ZNK4PLMD6adjmat19AdjacencyMatrixBase29getAbsoluteIndexOfCentralAtomERKj504
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.func.html b/coverage/adjmat/AdjacencyMatrixBase.h.func.html new file mode 100644 index 0000000000..a95b011e52 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase10isPeriodicEv25
_ZNK4PLMD6adjmat19AdjacencyMatrixBase29getAbsoluteIndexOfCentralAtomERKj504
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html b/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html new file mode 100644 index 0000000000..543a341d9e --- /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-06-10 08:19:14Functions: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"); Vector dum; return dum; }
+      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.15
+
+ + + 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 0000000000..7a8d324904 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixVessel.cpp.func.html b/coverage/adjmat/AdjacencyMatrixVessel.cpp.func.html new file mode 100644 index 0000000000..5960e9c7bc --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixVessel.cpp.gcov.html b/coverage/adjmat/AdjacencyMatrixVessel.cpp.gcov.html new file mode 100644 index 0000000000..3494ef3f40 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..d56d01602d --- /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-06-10 08:19:14Functions: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_8KeywordsE3
_ZNK4PLMD6adjmat17AlignedMatrixBase7computeERKjRNS_11multicolvar13AtomValuePackE5806
_ZNK4PLMD6adjmat17AlignedMatrixBase15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE57063
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/AlignedMatrixBase.cpp.func.html b/coverage/adjmat/AlignedMatrixBase.cpp.func.html new file mode 100644 index 0000000000..3c663351de --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17AlignedMatrixBase14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE2
_ZN4PLMD6adjmat17AlignedMatrixBase16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat17AlignedMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat17AlignedMatrixBaseC2ERKNS_13ActionOptionsE1
_ZNK4PLMD6adjmat17AlignedMatrixBase15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE57063
_ZNK4PLMD6adjmat17AlignedMatrixBase7computeERKjRNS_11multicolvar13AtomValuePackE5806
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/AlignedMatrixBase.cpp.gcov.html b/coverage/adjmat/AlignedMatrixBase.cpp.gcov.html new file mode 100644 index 0000000000..d82c7553f8 --- /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-06-10 08:19:14Functions: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           3 : void AlignedMatrixBase::registerKeywords( Keywords& keys ) {
+      31           3 :   AdjacencyMatrixBase::registerKeywords( keys );
+      32           6 :   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           6 :   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           6 :   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           6 :   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           3 : }
+      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.15
+
+ + + 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 0000000000..84aee819b1 --- /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-06-10 08:19:14Functions: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_8KeywordsE58
_ZNK4PLMD6adjmat19ClusterAnalysisBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE66
_ZNK4PLMD6adjmat19ClusterAnalysisBase26getNodePropertyDerivativesERKjRNS_10MultiValueE1604
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getPropertiesOfNodeERKjRSt6vectorIdSaIdEE1801
_ZNK4PLMD6adjmat19ClusterAnalysisBase29getPositionOfAtomForLinkCellsERKj1975
_ZNK4PLMD6adjmat19ClusterAnalysisBase21getNumberOfQuantitiesEv2073
_ZNK4PLMD6adjmat19ClusterAnalysisBase16getNumberOfNodesEv15981876
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.cpp.func.html b/coverage/adjmat/ClusterAnalysisBase.cpp.func.html new file mode 100644 index 0000000000..58641f6ca8 --- /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-06-10 08:19:14Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19ClusterAnalysisBase10isPeriodicEv11
_ZN4PLMD6adjmat19ClusterAnalysisBase16registerKeywordsERNS_8KeywordsE58
_ZN4PLMD6adjmat19ClusterAnalysisBase17turnOnDerivativesEv8
_ZN4PLMD6adjmat19ClusterAnalysisBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19ClusterAnalysisBaseC2ERKNS_13ActionOptionsE54
_ZNK4PLMD6adjmat19ClusterAnalysisBase12areConnectedERKjS3_0
_ZNK4PLMD6adjmat19ClusterAnalysisBase12nodeIsActiveERKj1
_ZNK4PLMD6adjmat19ClusterAnalysisBase16getNumberOfNodesEv15981876
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getNumberOfClustersEv4
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getPropertiesOfNodeERKjRSt6vectorIdSaIdEE1801
_ZNK4PLMD6adjmat19ClusterAnalysisBase21getNumberOfQuantitiesEv2073
_ZNK4PLMD6adjmat19ClusterAnalysisBase22getCutoffForConnectionEv0
_ZNK4PLMD6adjmat19ClusterAnalysisBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE66
_ZNK4PLMD6adjmat19ClusterAnalysisBase26getNodePropertyDerivativesERKjRNS_10MultiValueE1604
_ZNK4PLMD6adjmat19ClusterAnalysisBase29getPositionOfAtomForLinkCellsERKj1975
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.cpp.gcov.html b/coverage/adjmat/ClusterAnalysisBase.cpp.gcov.html new file mode 100644 index 0000000000..e1f7d9087b --- /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-06-10 08:19:14Functions: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          58 : void ClusterAnalysisBase::registerKeywords( Keywords& keys ) {
+      28          58 :   MultiColvarBase::registerKeywords( keys );
+      29         116 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+      30          58 : }
+      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.15
+
+ + + 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 0000000000..aa8f6326fa --- /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-06-10 08:19:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19ClusterAnalysisBase7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.h.func.html b/coverage/adjmat/ClusterAnalysisBase.h.func.html new file mode 100644 index 0000000000..52b4a1ea44 --- /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-06-10 08:19:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19ClusterAnalysisBase7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.h.gcov.html b/coverage/adjmat/ClusterAnalysisBase.h.gcov.html new file mode 100644 index 0000000000..31bb15fc16 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..8196fe7cfe --- /dev/null +++ b/coverage/adjmat/ClusterDiameter.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:272993.1 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat15ClusterDiameter17turnOnDerivativesEv0
_ZN4PLMD6adjmat15ClusterDiameterC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe806createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat15ClusterDiameter9calculateEv2
_ZN4PLMD6adjmat15ClusterDiameterC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat15ClusterDiameter16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD6adjmat15ClusterDiameter11performTaskERKjS3_RNS_10MultiValueE2016
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe80C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe80D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterDiameter.cpp.func.html b/coverage/adjmat/ClusterDiameter.cpp.func.html new file mode 100644 index 0000000000..4670eed08e --- /dev/null +++ b/coverage/adjmat/ClusterDiameter.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:272993.1 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe806createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe80C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe80D2Ev3473
_ZN4PLMD6adjmat15ClusterDiameter16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat15ClusterDiameter17turnOnDerivativesEv0
_ZN4PLMD6adjmat15ClusterDiameter9calculateEv2
_ZN4PLMD6adjmat15ClusterDiameterC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat15ClusterDiameterC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat15ClusterDiameter11performTaskERKjS3_RNS_10MultiValueE2016
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterDiameter.cpp.gcov.html b/coverage/adjmat/ClusterDiameter.cpp.gcov.html new file mode 100644 index 0000000000..d52aa0145f --- /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:272993.1 %
Date:2024-06-10 08:19:14Functions:7977.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 "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       10423 : PLUMED_REGISTER_ACTION(ClusterDiameter,"CLUSTER_DIAMETER")
+      81             : 
+      82           3 : void ClusterDiameter::registerKeywords( Keywords& keys ) {
+      83           3 :   ClusterAnalysisBase::registerKeywords( keys );
+      84           6 :   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           3 : }
+      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.15
+
+ + + 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 0000000000..379f7dac80 --- /dev/null +++ b/coverage/adjmat/ClusterDistribution.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:434987.8 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19ClusterDistributionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe836createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat19ClusterDistribution9calculateEv1
_ZN4PLMD6adjmat19ClusterDistributionC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat19ClusterDistribution16registerKeywordsERNS_8KeywordsE2
_ZNK4PLMD6adjmat19ClusterDistribution11performTaskERKjS3_RNS_10MultiValueE3
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe83C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe83D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterDistribution.cpp.func.html b/coverage/adjmat/ClusterDistribution.cpp.func.html new file mode 100644 index 0000000000..b55cc5eae1 --- /dev/null +++ b/coverage/adjmat/ClusterDistribution.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:434987.8 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe836createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe83C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe83D2Ev3473
_ZN4PLMD6adjmat19ClusterDistribution16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6adjmat19ClusterDistribution9calculateEv1
_ZN4PLMD6adjmat19ClusterDistributionC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat19ClusterDistributionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat19ClusterDistribution11performTaskERKjS3_RNS_10MultiValueE3
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterDistribution.cpp.gcov.html b/coverage/adjmat/ClusterDistribution.cpp.gcov.html new file mode 100644 index 0000000000..ac19c2c6c5 --- /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:434987.8 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(ClusterDistribution,"CLUSTER_DISTRIBUTION")
+      84             : 
+      85           2 : void ClusterDistribution::registerKeywords( Keywords& keys ) {
+      86           2 :   ClusterAnalysisBase::registerKeywords( keys );
+      87           4 :   keys.add("compulsory","TRANSFORM","none","the switching function to use to convert the crystallinity parameter to a number between zero and one");
+      88           4 :   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           6 :   keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("BETWEEN");
+      91           8 :   keys.use("HISTOGRAM"); keys.use("ALT_MIN"); keys.use("MIN"); keys.use("MAX");
+      92           2 : }
+      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.15
+
+ + + 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 0000000000..bd73a6b4f1 --- /dev/null +++ b/coverage/adjmat/ClusterProperties.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3030100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17ClusterPropertiesC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe746createERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat17ClusterPropertiesC1ERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat17ClusterProperties16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD6adjmat17ClusterProperties9calculateEv34
_ZNK4PLMD6adjmat17ClusterProperties11performTaskERKjS3_RNS_10MultiValueE1795
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe74C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe74D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterProperties.cpp.func.html b/coverage/adjmat/ClusterProperties.cpp.func.html new file mode 100644 index 0000000000..3564d0519e --- /dev/null +++ b/coverage/adjmat/ClusterProperties.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3030100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe746createERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe74C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe74D2Ev3473
_ZN4PLMD6adjmat17ClusterProperties16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD6adjmat17ClusterProperties9calculateEv34
_ZN4PLMD6adjmat17ClusterPropertiesC1ERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat17ClusterPropertiesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat17ClusterProperties11performTaskERKjS3_RNS_10MultiValueE1795
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterProperties.cpp.gcov.html b/coverage/adjmat/ClusterProperties.cpp.gcov.html new file mode 100644 index 0000000000..b59579913e --- /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:3030100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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       10473 : PLUMED_REGISTER_ACTION(ClusterProperties,"CLUSTER_PROPERTIES")
+      75             : 
+      76          28 : void ClusterProperties::registerKeywords( Keywords& keys ) {
+      77          28 :   ClusterAnalysisBase::registerKeywords( keys );
+      78          56 :   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          84 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
+      80          84 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+      81          84 :   if( keys.reserved("VSUM") ) keys.use("VSUM");
+      82         112 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS"); keys.use("ALT_MIN");
+      83         140 :   keys.use("MIN"); keys.use("MAX"); keys.use("SUM"); keys.use("LOWEST"); keys.use("HIGHEST");
+      84          28 : }
+      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.15
+
+ + + 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 0000000000..379f3302a9 --- /dev/null +++ b/coverage/adjmat/ClusterSize.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:172085.0 %
Date:2024-06-10 08:19:14Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11ClusterSize17turnOnDerivativesEv0
_ZN4PLMD6adjmat11ClusterSizeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat11ClusterSize11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD6adjmat11ClusterSizeC1ERKNS_13ActionOptionsE24
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe796createERKNS_13ActionOptionsE24
_ZN4PLMD6adjmat11ClusterSize16registerKeywordsERNS_8KeywordsE25
_ZN4PLMD6adjmat11ClusterSize9calculateEv27
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe79C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe79D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterSize.cpp.func.html b/coverage/adjmat/ClusterSize.cpp.func.html new file mode 100644 index 0000000000..51ba998c8c --- /dev/null +++ b/coverage/adjmat/ClusterSize.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:172085.0 %
Date:2024-06-10 08:19:14Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11ClusterSize16registerKeywordsERNS_8KeywordsE25
_ZN4PLMD6adjmat11ClusterSize17turnOnDerivativesEv0
_ZN4PLMD6adjmat11ClusterSize9calculateEv27
_ZN4PLMD6adjmat11ClusterSizeC1ERKNS_13ActionOptionsE24
_ZN4PLMD6adjmat11ClusterSizeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe796createERKNS_13ActionOptionsE24
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe79C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe79D2Ev3473
_ZNK4PLMD6adjmat11ClusterSize11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterSize.cpp.gcov.html b/coverage/adjmat/ClusterSize.cpp.gcov.html new file mode 100644 index 0000000000..052ca6c7ee --- /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:172085.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10467 : PLUMED_REGISTER_ACTION(ClusterSize,"CLUSTER_NATOMS")
+      80             : 
+      81          25 : void ClusterSize::registerKeywords( Keywords& keys ) {
+      82          25 :   ClusterAnalysisBase::registerKeywords( keys );
+      83          50 :   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          25 : }
+      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          24 :   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.15
+
+ + + 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 0000000000..30df02d6c5 --- /dev/null +++ b/coverage/adjmat/ClusterWithSurface.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + 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:495786.0 %
Date:2024-06-10 08:19:14Functions:121675.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat18ClusterWithSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat18ClusterWithSurface12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE0
_ZNK4PLMD6adjmat18ClusterWithSurface19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD6adjmat18ClusterWithSurface29getPositionOfAtomForLinkCellsERKj0
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe986createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat18ClusterWithSurface17performClusteringEv2
_ZN4PLMD6adjmat18ClusterWithSurfaceC1ERKNS_13ActionOptionsE2
_ZNK4PLMD6adjmat18ClusterWithSurface22getCutoffForConnectionEv2
_ZN4PLMD6adjmat18ClusterWithSurface16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat18ClusterWithSurface22getNumberOfDerivativesEv4
_ZNK4PLMD6adjmat18ClusterWithSurface22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE6
_ZNK4PLMD6adjmat18ClusterWithSurface21getNumberOfQuantitiesEv14
_ZNK4PLMD6adjmat18ClusterWithSurface29getAbsoluteIndexOfCentralAtomERKj128
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe98C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe98D2Ev3473
_ZNK4PLMD6adjmat18ClusterWithSurface16getNumberOfNodesEv16155834
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterWithSurface.cpp.func.html b/coverage/adjmat/ClusterWithSurface.cpp.func.html new file mode 100644 index 0000000000..3e103db228 --- /dev/null +++ b/coverage/adjmat/ClusterWithSurface.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + 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:495786.0 %
Date:2024-06-10 08:19:14Functions:121675.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe986createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe98C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe98D2Ev3473
_ZN4PLMD6adjmat18ClusterWithSurface16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat18ClusterWithSurface17performClusteringEv2
_ZN4PLMD6adjmat18ClusterWithSurface22getNumberOfDerivativesEv4
_ZN4PLMD6adjmat18ClusterWithSurfaceC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat18ClusterWithSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat18ClusterWithSurface12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE0
_ZNK4PLMD6adjmat18ClusterWithSurface16getNumberOfNodesEv16155834
_ZNK4PLMD6adjmat18ClusterWithSurface19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD6adjmat18ClusterWithSurface21getNumberOfQuantitiesEv14
_ZNK4PLMD6adjmat18ClusterWithSurface22getCutoffForConnectionEv2
_ZNK4PLMD6adjmat18ClusterWithSurface22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE6
_ZNK4PLMD6adjmat18ClusterWithSurface29getAbsoluteIndexOfCentralAtomERKj128
_ZNK4PLMD6adjmat18ClusterWithSurface29getPositionOfAtomForLinkCellsERKj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusterWithSurface.cpp.gcov.html b/coverage/adjmat/ClusterWithSurface.cpp.gcov.html new file mode 100644 index 0000000000..41418c751f --- /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:495786.0 %
Date:2024-06-10 08:19:14Functions:121675.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 "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       10423 : PLUMED_REGISTER_ACTION(ClusterWithSurface,"CLUSTER_WITHSURFACE")
+      99             : 
+     100           3 : void ClusterWithSurface::registerKeywords( Keywords& keys ) {
+     101           3 :   ClusteringBase::registerKeywords( keys );
+     102           3 :   keys.remove("MATRIX");
+     103           6 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+     104           6 :   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           3 : }
+     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.15
+
+ + + 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 0000000000..343d33dc1d --- /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-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBaseC1ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14ClusteringBase12areConnectedERKjS3_0
_ZN4PLMD6adjmat14ClusteringBase17turnOnDerivativesEv8
_ZNK4PLMD6adjmat14ClusteringBase22getCutoffForConnectionEv8
_ZN4PLMD6adjmat14ClusteringBaseC2ERKNS_13ActionOptionsE17
_ZN4PLMD6adjmat14ClusteringBase16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD6adjmat14ClusteringBase9calculateEv26
_ZNK4PLMD6adjmat14ClusteringBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE74
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.cpp.func.html b/coverage/adjmat/ClusteringBase.cpp.func.html new file mode 100644 index 0000000000..8c9bd329d8 --- /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-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBase16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD6adjmat14ClusteringBase17turnOnDerivativesEv8
_ZN4PLMD6adjmat14ClusteringBase9calculateEv26
_ZN4PLMD6adjmat14ClusteringBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat14ClusteringBaseC2ERKNS_13ActionOptionsE17
_ZNK4PLMD6adjmat14ClusteringBase12areConnectedERKjS3_0
_ZNK4PLMD6adjmat14ClusteringBase22getCutoffForConnectionEv8
_ZNK4PLMD6adjmat14ClusteringBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE74
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.cpp.gcov.html b/coverage/adjmat/ClusteringBase.cpp.gcov.html new file mode 100644 index 0000000000..a22e13ec4c --- /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-06-10 08:19:14Functions: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          19 : void ClusteringBase::registerKeywords( Keywords& keys ) {
+      30          19 :   ActionWithInputMatrix::registerKeywords( keys );
+      31          19 : }
+      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.15
+
+ + + 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 0000000000..80a8f2db76 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBase5applyEv26
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.h.func.html b/coverage/adjmat/ClusteringBase.h.func.html new file mode 100644 index 0000000000..a12816b48c --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBase5applyEv26
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.h.gcov.html b/coverage/adjmat/ClusteringBase.h.gcov.html new file mode 100644 index 0000000000..7893b6c997 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..ae7382dc20 --- /dev/null +++ b/coverage/adjmat/ContactAlignedMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:52222.7 %
Date:2024-06-10 08:19:14Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe876createERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat20ContactAlignedMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat20ContactAlignedMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
_ZN4PLMD6adjmat20ContactAlignedMatrix16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe87C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe87D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ContactAlignedMatrix.cpp.func.html b/coverage/adjmat/ContactAlignedMatrix.cpp.func.html new file mode 100644 index 0000000000..486b8fe405 --- /dev/null +++ b/coverage/adjmat/ContactAlignedMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:52222.7 %
Date:2024-06-10 08:19:14Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe876createERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe87C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe87D2Ev3473
_ZN4PLMD6adjmat20ContactAlignedMatrix16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD6adjmat20ContactAlignedMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat20ContactAlignedMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ContactAlignedMatrix.cpp.gcov.html b/coverage/adjmat/ContactAlignedMatrix.cpp.gcov.html new file mode 100644 index 0000000000..8835d172e0 --- /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:52222.7 %
Date:2024-06-10 08:19:14Functions:3837.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 "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       10419 : PLUMED_REGISTER_ACTION(ContactAlignedMatrix,"ALIGNED_MATRIX")
+      88             : 
+      89           1 : void ContactAlignedMatrix::registerKeywords( Keywords& keys ) {
+      90           1 :   AlignedMatrixBase::registerKeywords( keys );
+      91           3 :   keys.add("numbered","ORIENTATION_SWITCH","A switching function that transforms the dot product of the input vectors.");
+      92           1 : }
+      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.15
+
+ + + 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 0000000000..7e50248fec --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:3737100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13ContactMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe836createERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD6adjmat13ContactMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE14
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe83C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe83D2Ev3473
_ZNK4PLMD6adjmat13ContactMatrix7computeERKjRNS_11multicolvar13AtomValuePackE28888
_ZNK4PLMD6adjmat13ContactMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE55746
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.func.html b/coverage/adjmat/ContactMatrix.cpp.func.html new file mode 100644 index 0000000000..c57250d934 --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:3737100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe836createERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe83C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe83D2Ev3473
_ZN4PLMD6adjmat13ContactMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE14
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat13ContactMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat13ContactMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE55746
_ZNK4PLMD6adjmat13ContactMatrix7computeERKjRNS_11multicolvar13AtomValuePackE28888
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.gcov.html b/coverage/adjmat/ContactMatrix.cpp.gcov.html new file mode 100644 index 0000000000..d20cf63ec3 --- /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:3737100.0 %
Date:2024-06-10 08:19:14Functions:8988.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 "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       10443 : PLUMED_REGISTER_ACTION(ContactMatrix,"CONTACT_MATRIX")
+      84             : 
+      85          13 : void ContactMatrix::registerKeywords( Keywords& keys ) {
+      86          13 :   AdjacencyMatrixBase::registerKeywords( keys );
+      87          26 :   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          26 :   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          39 :   keys.add("hidden","ATOMSA",""); keys.add("hidden","ATOMSB","");
+      97          13 : }
+      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.15
+
+ + + 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 0000000000..c57bc760e2 --- /dev/null +++ b/coverage/adjmat/DFSClustering.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13DFSClusteringC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe946createERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat13DFSClusteringC1ERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat13DFSClustering16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD6adjmat13DFSClustering17performClusteringEv24
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe94C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe94D2Ev3473
_ZN4PLMD6adjmat13DFSClustering7exploreERKj8193
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/DFSClustering.cpp.func.html b/coverage/adjmat/DFSClustering.cpp.func.html new file mode 100644 index 0000000000..b8b53b003a --- /dev/null +++ b/coverage/adjmat/DFSClustering.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe946createERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe94C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe94D2Ev3473
_ZN4PLMD6adjmat13DFSClustering16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD6adjmat13DFSClustering17performClusteringEv24
_ZN4PLMD6adjmat13DFSClustering7exploreERKj8193
_ZN4PLMD6adjmat13DFSClusteringC1ERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat13DFSClusteringC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/DFSClustering.cpp.gcov.html b/coverage/adjmat/DFSClustering.cpp.gcov.html new file mode 100644 index 0000000000..7524979d61 --- /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:2626100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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       10449 : PLUMED_REGISTER_ACTION(DFSClustering,"DFSCLUSTERING")
+      95             : 
+      96          16 : void DFSClustering::registerKeywords( Keywords& keys ) {
+      97          16 :   ClusteringBase::registerKeywords( keys );
+      98          32 :   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          16 : }
+     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.15
+
+ + + 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 0000000000..a82c6c3a52 --- /dev/null +++ b/coverage/adjmat/DumpGraph.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:3535100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat9DumpGraphC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe636createERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat9DumpGraph5applyEv4
_ZN4PLMD6adjmat9DumpGraph6updateEv4
_ZN4PLMD6adjmat9DumpGraph9calculateEv4
_ZN4PLMD6adjmat9DumpGraphC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat9DumpGraph16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe63C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe63D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/DumpGraph.cpp.func.html b/coverage/adjmat/DumpGraph.cpp.func.html new file mode 100644 index 0000000000..9ee2085eef --- /dev/null +++ b/coverage/adjmat/DumpGraph.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:3535100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe636createERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe63C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe63D2Ev3473
_ZN4PLMD6adjmat9DumpGraph16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6adjmat9DumpGraph5applyEv4
_ZN4PLMD6adjmat9DumpGraph6updateEv4
_ZN4PLMD6adjmat9DumpGraph9calculateEv4
_ZN4PLMD6adjmat9DumpGraphC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat9DumpGraphC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/DumpGraph.cpp.gcov.html b/coverage/adjmat/DumpGraph.cpp.gcov.html new file mode 100644 index 0000000000..88d28be063 --- /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:3535100.0 %
Date:2024-06-10 08:19:14Functions:8988.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 "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       10427 : PLUMED_REGISTER_ACTION(DumpGraph,"DUMPGRAPH")
+      64             : 
+      65           5 : void DumpGraph::registerKeywords( Keywords& keys ) {
+      66           5 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      67          10 :   keys.add("compulsory","MATRIX","the action that calculates the adjacency matrix vessel we would like to analyze");
+      68          10 :   keys.add("compulsory","STRIDE","1","the frequency with which you would like to output the graph");
+      69          10 :   keys.add("compulsory","FILE","the name of the file on which to output the data");
+      70          10 :   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           5 : }
+      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.15
+
+ + + 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 0000000000..040d7ae4d8 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:697197.2 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11HBondMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat11HBondMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe1076createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat11HBondMatrix16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat11HBondMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE6
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe107C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe107D2Ev3473
_ZNK4PLMD6adjmat11HBondMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE4038
_ZNK4PLMD6adjmat11HBondMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
_ZNK4PLMD6adjmat11HBondMatrix17calculateForThreeERKjS3_S3_RKNS_13VectorGenericILj3EEERKdS9_RNS_11multicolvar13AtomValuePackE516132
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.func.html b/coverage/adjmat/HbondMatrix.cpp.func.html new file mode 100644 index 0000000000..add846abb1 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:697197.2 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11HBondMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE6
_ZN4PLMD6adjmat11HBondMatrix16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat11HBondMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat11HBondMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe1076createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe107C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe107D2Ev3473
_ZNK4PLMD6adjmat11HBondMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE4038
_ZNK4PLMD6adjmat11HBondMatrix17calculateForThreeERKjS3_S3_RKNS_13VectorGenericILj3EEERKdS9_RNS_11multicolvar13AtomValuePackE516132
_ZNK4PLMD6adjmat11HBondMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.gcov.html b/coverage/adjmat/HbondMatrix.cpp.gcov.html new file mode 100644 index 0000000000..412aae935d --- /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:697197.2 %
Date:2024-06-10 08:19:14Functions:91090.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 "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       10423 : PLUMED_REGISTER_ACTION(HBondMatrix,"HBOND_MATRIX")
+     108             : 
+     109           3 : void HBondMatrix::registerKeywords( Keywords& keys ) {
+     110           3 :   AdjacencyMatrixBase::registerKeywords( keys );
+     111           6 :   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           6 :   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           6 :   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           6 :   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           6 :   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           6 :   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           6 :   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           3 :   keys.use("SUM");
+     136           3 : }
+     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.15
+
+ + + 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 0000000000..5a65167319 --- /dev/null +++ b/coverage/adjmat/MatrixColumnSums.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3131100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16MatrixColumnSumsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe756createERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16MatrixColumnSumsC1ERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16MatrixColumnSums16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD6adjmat16MatrixColumnSums7computeERKjRNS_11multicolvar13AtomValuePackE238
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe75C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe75D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/MatrixColumnSums.cpp.func.html b/coverage/adjmat/MatrixColumnSums.cpp.func.html new file mode 100644 index 0000000000..96d4ef0f1a --- /dev/null +++ b/coverage/adjmat/MatrixColumnSums.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3131100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe756createERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe75C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe75D2Ev3473
_ZN4PLMD6adjmat16MatrixColumnSums16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6adjmat16MatrixColumnSumsC1ERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16MatrixColumnSumsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat16MatrixColumnSums7computeERKjRNS_11multicolvar13AtomValuePackE238
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/MatrixColumnSums.cpp.gcov.html b/coverage/adjmat/MatrixColumnSums.cpp.gcov.html new file mode 100644 index 0000000000..40860f2f03 --- /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:3131100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10429 : PLUMED_REGISTER_ACTION(MatrixColumnSums,"COLUMNSUMS")
+      76             : 
+      77           6 : void MatrixColumnSums::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           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.15
+
+ + + 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 0000000000..0822a6b7ff --- /dev/null +++ b/coverage/adjmat/MatrixRowSums.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2222100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13MatrixRowSumsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe756createERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat13MatrixRowSumsC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat13MatrixRowSums16registerKeywordsERNS_8KeywordsE5
_ZNK4PLMD6adjmat13MatrixRowSums7computeERKjRNS_11multicolvar13AtomValuePackE203
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe75C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe75D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/MatrixRowSums.cpp.func.html b/coverage/adjmat/MatrixRowSums.cpp.func.html new file mode 100644 index 0000000000..edb679c3df --- /dev/null +++ b/coverage/adjmat/MatrixRowSums.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2222100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe756createERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe75C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe75D2Ev3473
_ZN4PLMD6adjmat13MatrixRowSums16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6adjmat13MatrixRowSumsC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat13MatrixRowSumsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat13MatrixRowSums7computeERKjRNS_11multicolvar13AtomValuePackE203
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/MatrixRowSums.cpp.gcov.html b/coverage/adjmat/MatrixRowSums.cpp.gcov.html new file mode 100644 index 0000000000..cda2c31174 --- /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:2222100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10427 : PLUMED_REGISTER_ACTION(MatrixRowSums,"ROWSUMS")
+      76             : 
+      77           5 : void MatrixRowSums::registerKeywords( Keywords& keys ) {
+      78           5 :   ActionWithInputMatrix::registerKeywords( keys );
+      79          15 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      80          20 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN");
+      81          20 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      82           5 : }
+      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.15
+
+ + + 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 0000000000..8160be2e49 --- /dev/null +++ b/coverage/adjmat/OutputCluster.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:418747.1 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13OutputCluster11explore_dfsERKj0
_ZN4PLMD6adjmat13OutputCluster7exploreERKjS3_0
_ZN4PLMD6adjmat13OutputClusterC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe896createERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat13OutputCluster5applyEv8
_ZN4PLMD6adjmat13OutputCluster6updateEv8
_ZN4PLMD6adjmat13OutputCluster9calculateEv8
_ZN4PLMD6adjmat13OutputClusterC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat13OutputCluster16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe89C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe89D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/OutputCluster.cpp.func.html b/coverage/adjmat/OutputCluster.cpp.func.html new file mode 100644 index 0000000000..119c5feb87 --- /dev/null +++ b/coverage/adjmat/OutputCluster.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:418747.1 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe896createERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe89C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe89D2Ev3473
_ZN4PLMD6adjmat13OutputCluster11explore_dfsERKj0
_ZN4PLMD6adjmat13OutputCluster16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6adjmat13OutputCluster5applyEv8
_ZN4PLMD6adjmat13OutputCluster6updateEv8
_ZN4PLMD6adjmat13OutputCluster7exploreERKjS3_0
_ZN4PLMD6adjmat13OutputCluster9calculateEv8
_ZN4PLMD6adjmat13OutputClusterC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat13OutputClusterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/OutputCluster.cpp.gcov.html b/coverage/adjmat/OutputCluster.cpp.gcov.html new file mode 100644 index 0000000000..f81987c240 --- /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:418747.1 %
Date:2024-06-10 08:19:14Functions:81172.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 "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       10435 : PLUMED_REGISTER_ACTION(OutputCluster,"OUTPUT_CLUSTER")
+      90             : 
+      91           9 : void OutputCluster::registerKeywords( Keywords& keys ) {
+      92           9 :   Action::registerKeywords( keys );
+      93           9 :   ActionPilot::registerKeywords( keys );
+      94          18 :   keys.add("compulsory","CLUSTERS","the action that performed the clustering");
+      95          18 :   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          18 :   keys.add("compulsory","STRIDE","1","the frequency with which you would like to output the atoms in the cluster");
+      97          18 :   keys.add("compulsory","FILE","the name of the file on which to output the details of the cluster");
+      98          18 :   keys.add("compulsory","MAXDEPTH","6","maximum depth for searches over paths to reconstruct clusters for PBC");
+      99          18 :   keys.add("compulsory","MAXGOES","200","number of times to run searches to reconstruct clusters");
+     100          18 :   keys.addFlag("MAKE_WHOLE",false,"reconstruct the clusters and remove all periodic boundary conditions.");
+     101           9 : }
+     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.15
+
+ + + 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 0000000000..46b8795730 --- /dev/null +++ b/coverage/adjmat/SMACMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat10SMACMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat10SMACMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE1
_ZN4PLMD6adjmat10SMACMatrixC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe956createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat10SMACMatrix16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe95C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe95D2Ev3473
_ZNK4PLMD6adjmat10SMACMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_5806
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/SMACMatrix.cpp.func.html b/coverage/adjmat/SMACMatrix.cpp.func.html new file mode 100644 index 0000000000..6932f6c767 --- /dev/null +++ b/coverage/adjmat/SMACMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat10SMACMatrix16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6adjmat10SMACMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE1
_ZN4PLMD6adjmat10SMACMatrixC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat10SMACMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe956createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe95C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe95D2Ev3473
_ZNK4PLMD6adjmat10SMACMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_5806
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/SMACMatrix.cpp.gcov.html b/coverage/adjmat/SMACMatrix.cpp.gcov.html new file mode 100644 index 0000000000..baa5afc0b4 --- /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:3636100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(SMACMatrix,"SMAC_MATRIX")
+      96             : 
+      97           2 : void SMACMatrix::registerKeywords( Keywords& keys ) {
+      98           2 :   AlignedMatrixBase::registerKeywords( keys );
+      99           4 :   keys.add("numbered","KERNEL","The various kernels that are used to determine whether or not the molecules are aligned");
+     100           2 : }
+     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           2 :   }
+     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       11612 :   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.15
+
+ + + 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 0000000000..7677fd720d --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:617482.4 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6SprintC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe1086createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6Sprint16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6adjmat6Sprint5applyEv17
_ZN4PLMD6adjmat6Sprint9calculateEv17
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe108C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe108D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.func.html b/coverage/adjmat/Sprint.cpp.func.html new file mode 100644 index 0000000000..2c1b66ccd3 --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:617482.4 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe1086createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe108C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe108D2Ev3473
_ZN4PLMD6adjmat6Sprint16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6adjmat6Sprint5applyEv17
_ZN4PLMD6adjmat6Sprint9calculateEv17
_ZN4PLMD6adjmat6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6SprintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.gcov.html b/coverage/adjmat/Sprint.cpp.gcov.html new file mode 100644 index 0000000000..f1e325b028 --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.gcov.html @@ -0,0 +1,318 @@ + + + + + + + + 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:617482.4 %
Date:2024-06-10 08:19:14Functions:7887.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 "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 ?? 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       10421 : PLUMED_REGISTER_ACTION(Sprint,"SPRINT")
+     109             : 
+     110           2 : void Sprint::registerKeywords( Keywords& keys ) {
+     111           2 :   ActionWithInputMatrix::registerKeywords( keys );
+     112           2 :   componentsAreNotOptional(keys);
+     113           4 :   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-1, "
+     115             :                           "the second smallest will be labelled <em>label</em>.coord-1 and so on");
+     116           2 : }
+     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          14 :     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             :   std::vector<Vector>&   f(modifyForces());
+     216             :   Tensor&           v(modifyVirial());
+     217             :   unsigned          nat=getNumberOfAtoms();
+     218             : 
+     219          17 :   std::vector<double> forces( 3*getNumberOfAtoms() + 9 );
+     220         255 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     221         238 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
+     222           0 :       for(unsigned j=0; j<nat; ++j) {
+     223           0 :         f[j][0]+=forces[3*j+0];
+     224           0 :         f[j][1]+=forces[3*j+1];
+     225           0 :         f[j][2]+=forces[3*j+2];
+     226             :       }
+     227           0 :       v(0,0)+=forces[3*nat+0];
+     228           0 :       v(0,1)+=forces[3*nat+1];
+     229           0 :       v(0,2)+=forces[3*nat+2];
+     230           0 :       v(1,0)+=forces[3*nat+3];
+     231           0 :       v(1,1)+=forces[3*nat+4];
+     232           0 :       v(1,2)+=forces[3*nat+5];
+     233           0 :       v(2,0)+=forces[3*nat+6];
+     234           0 :       v(2,1)+=forces[3*nat+7];
+     235           0 :       v(2,2)+=forces[3*nat+8];
+     236             :     }
+     237             :   }
+     238          17 : }
+     239             : 
+     240             : }
+     241             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e5ee8e13b4 --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:156156100.0 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TopologyMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe786createERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat14TopologyMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat14TopologyMatrix16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6adjmat14TopologyMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE24
_ZNK4PLMD6adjmat14TopologyMatrix21getNumberOfQuantitiesEv100
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe78C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe78D2Ev3473
_ZNK4PLMD6adjmat14TopologyMatrix7computeERKjRNS_11multicolvar13AtomValuePackE9616
_ZNK4PLMD6adjmat14TopologyMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE31203
_ZNK4PLMD6adjmat14TopologyMatrix22calculateForThreeAtomsERKjRKNS_13VectorGenericILj3EEERKdRNS_13HistogramBeadERNS_11multicolvar13AtomValuePackE117917799
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.func.html b/coverage/adjmat/TopologyMatrix.cpp.func.html new file mode 100644 index 0000000000..0eb856b3ff --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:156156100.0 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe786createERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe78C2Ev3473
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe78D2Ev3473
_ZN4PLMD6adjmat14TopologyMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE24
_ZN4PLMD6adjmat14TopologyMatrix16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6adjmat14TopologyMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat14TopologyMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14TopologyMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE31203
_ZNK4PLMD6adjmat14TopologyMatrix21getNumberOfQuantitiesEv100
_ZNK4PLMD6adjmat14TopologyMatrix22calculateForThreeAtomsERKjRKNS_13VectorGenericILj3EEERKdRNS_13HistogramBeadERNS_11multicolvar13AtomValuePackE117917799
_ZNK4PLMD6adjmat14TopologyMatrix7computeERKjRNS_11multicolvar13AtomValuePackE9616
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.gcov.html b/coverage/adjmat/TopologyMatrix.cpp.gcov.html new file mode 100644 index 0000000000..c18ea9c1b3 --- /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:156156100.0 %
Date:2024-06-10 08:19:14Functions:101190.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 "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       10431 : PLUMED_REGISTER_ACTION(TopologyMatrix,"TOPOLOGY_MATRIX")
+      79             : 
+      80           7 : void TopologyMatrix::registerKeywords( Keywords& keys ) {
+      81           7 :   AdjacencyMatrixBase::registerKeywords( keys );
+      82          14 :   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          14 :   keys.add("atoms","ATOMS","");
+      88          14 :   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          14 :   keys.add("numbered","RADIUS","");
+      91          14 :   keys.add("numbered","CYLINDER_SWITCH","a switching function on \\f$(r_{ij}\\cdot r_{ik}-1)/r_{ij}\\f$");
+      92          14 :   keys.add("numbered","BIN_SIZE","the size to use for the bins");
+      93          21 :   keys.add("compulsory","DENSITY_THRESHOLD","");
+      94          14 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      95          14 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      96          14 :   keys.add("hidden","FAKE","");
+      97           7 : }
+      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.15
+
+ + + diff --git a/coverage/adjmat/index-sort-f.html b/coverage/adjmat/index-sort-f.html new file mode 100644 index 0000000000..dcbe8ebfb6 --- /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:1039117288.7 %
Date:2024-06-10 08:19:14Functions:18322382.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
22.7%22.7%
+
22.7 %5 / 2237.5 %3 / 8
ActionWithInputMatrix.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
ClusterSize.cpp +
85.0%85.0%
+
85.0 %17 / 2066.7 %6 / 9
OutputCluster.cpp +
47.1%47.1%
+
47.1 %41 / 8772.7 %8 / 11
ClusteringBase.cpp +
93.5%93.5%
+
93.5 %29 / 3175.0 %6 / 8
ClusterWithSurface.cpp +
86.0%86.0%
+
86.0 %49 / 5775.0 %12 / 16
ClusterDiameter.cpp +
93.1%93.1%
+
93.1 %27 / 2977.8 %7 / 9
ClusterAnalysisBase.cpp +
91.7%91.7%
+
91.7 %44 / 4880.0 %12 / 15
AdjacencyMatrixBase.cpp +
85.1%85.1%
+
85.1 %86 / 10181.8 %9 / 11
AlignedMatrixBase.cpp +
88.0%88.0%
+
88.0 %44 / 5083.3 %5 / 6
MatrixColumnSums.cpp +
100.0%
+
100.0 %31 / 3185.7 %6 / 7
MatrixRowSums.cpp +
100.0%
+
100.0 %22 / 2285.7 %6 / 7
ClusterDistribution.cpp +
87.8%87.8%
+
87.8 %43 / 4987.5 %7 / 8
DFSClustering.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
SMACMatrix.cpp +
100.0%
+
100.0 %36 / 3687.5 %7 / 8
ClusterProperties.cpp +
100.0%
+
100.0 %30 / 3087.5 %7 / 8
Sprint.cpp +
82.4%82.4%
+
82.4 %61 / 7487.5 %7 / 8
ContactMatrix.cpp +
100.0%
+
100.0 %37 / 3788.9 %8 / 9
DumpGraph.cpp +
100.0%
+
100.0 %35 / 3588.9 %8 / 9
HbondMatrix.cpp +
97.2%97.2%
+
97.2 %69 / 7190.0 %9 / 10
TopologyMatrix.cpp +
100.0%
+
100.0 %156 / 15690.9 %10 / 11
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.15
+
+ + + diff --git a/coverage/adjmat/index-sort-l.html b/coverage/adjmat/index-sort-l.html new file mode 100644 index 0000000000..fda969cecf --- /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:1039117288.7 %
Date:2024-06-10 08:19:14Functions:18322382.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
22.7%22.7%
+
22.7 %5 / 2237.5 %3 / 8
OutputCluster.cpp +
47.1%47.1%
+
47.1 %41 / 8772.7 %8 / 11
ActionWithInputMatrix.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
Sprint.cpp +
82.4%82.4%
+
82.4 %61 / 7487.5 %7 / 8
ClusterSize.cpp +
85.0%85.0%
+
85.0 %17 / 2066.7 %6 / 9
AdjacencyMatrixBase.cpp +
85.1%85.1%
+
85.1 %86 / 10181.8 %9 / 11
ClusterWithSurface.cpp +
86.0%86.0%
+
86.0 %49 / 5775.0 %12 / 16
ClusterDistribution.cpp +
87.8%87.8%
+
87.8 %43 / 4987.5 %7 / 8
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 +
93.1%93.1%
+
93.1 %27 / 2977.8 %7 / 9
ClusteringBase.cpp +
93.5%93.5%
+
93.5 %29 / 3175.0 %6 / 8
HbondMatrix.cpp +
97.2%97.2%
+
97.2 %69 / 7190.0 %9 / 10
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 %22 / 2285.7 %6 / 7
DFSClustering.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
ClusterProperties.cpp +
100.0%
+
100.0 %30 / 3087.5 %7 / 8
MatrixColumnSums.cpp +
100.0%
+
100.0 %31 / 3185.7 %6 / 7
DumpGraph.cpp +
100.0%
+
100.0 %35 / 3588.9 %8 / 9
SMACMatrix.cpp +
100.0%
+
100.0 %36 / 3687.5 %7 / 8
ContactMatrix.cpp +
100.0%
+
100.0 %37 / 3788.9 %8 / 9
ActionWithInputMatrix.cpp +
100.0%
+
100.0 %70 / 7093.8 %15 / 16
TopologyMatrix.cpp +
100.0%
+
100.0 %156 / 15690.9 %10 / 11
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/adjmat/index.html b/coverage/adjmat/index.html new file mode 100644 index 0000000000..b527ae72b2 --- /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:1039117288.7 %
Date:2024-06-10 08:19:14Functions:18322382.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.1%85.1%
+
85.1 %86 / 10181.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 +
93.1%93.1%
+
93.1 %27 / 2977.8 %7 / 9
ClusterDistribution.cpp +
87.8%87.8%
+
87.8 %43 / 4987.5 %7 / 8
ClusterProperties.cpp +
100.0%
+
100.0 %30 / 3087.5 %7 / 8
ClusterSize.cpp +
85.0%85.0%
+
85.0 %17 / 2066.7 %6 / 9
ClusterWithSurface.cpp +
86.0%86.0%
+
86.0 %49 / 5775.0 %12 / 16
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 +
22.7%22.7%
+
22.7 %5 / 2237.5 %3 / 8
ContactMatrix.cpp +
100.0%
+
100.0 %37 / 3788.9 %8 / 9
DFSClustering.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
DumpGraph.cpp +
100.0%
+
100.0 %35 / 3588.9 %8 / 9
HbondMatrix.cpp +
97.2%97.2%
+
97.2 %69 / 7190.0 %9 / 10
MatrixColumnSums.cpp +
100.0%
+
100.0 %31 / 3185.7 %6 / 7
MatrixRowSums.cpp +
100.0%
+
100.0 %22 / 2285.7 %6 / 7
OutputCluster.cpp +
47.1%47.1%
+
47.1 %41 / 8772.7 %8 / 11
SMACMatrix.cpp +
100.0%
+
100.0 %36 / 3687.5 %7 / 8
Sprint.cpp +
82.4%82.4%
+
82.4 %61 / 7487.5 %7 / 8
TopologyMatrix.cpp +
100.0%
+
100.0 %156 / 15690.9 %10 / 11
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12AnalysisBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12AnalysisBase6updateEv39
_ZN4PLMD8analysis12AnalysisBase16getArgumentNamesB5cxx11Ev50
_ZN4PLMD8analysis12AnalysisBase12runFinalJobsEv107
_ZN4PLMD8analysis12AnalysisBaseC2ERKNS_13ActionOptionsE109
_ZN4PLMD8analysis12AnalysisBase16registerKeywordsERNS_8KeywordsE129
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/AnalysisBase.cpp.func.html b/coverage/analysis/AnalysisBase.cpp.func.html new file mode 100644 index 0000000000..969da22c2b --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12AnalysisBase12runFinalJobsEv107
_ZN4PLMD8analysis12AnalysisBase16getArgumentNamesB5cxx11Ev50
_ZN4PLMD8analysis12AnalysisBase16registerKeywordsERNS_8KeywordsE129
_ZN4PLMD8analysis12AnalysisBase6updateEv39
_ZN4PLMD8analysis12AnalysisBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12AnalysisBaseC2ERKNS_13ActionOptionsE109
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/AnalysisBase.cpp.gcov.html b/coverage/analysis/AnalysisBase.cpp.gcov.html new file mode 100644 index 0000000000..5c212f4f07 --- /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-06-10 08:19:14Functions: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         129 : void AnalysisBase::registerKeywords( Keywords& keys ) {
+      31         129 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      32         129 :   ActionWithValue::registerKeywords( keys ); ActionAtomistic::registerKeywords( keys );
+      33         129 :   ActionWithArguments::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES");
+      34         387 :   ActionWithVessel::registerKeywords( keys ); keys.remove("TOL"); keys.reset_style("TIMINGS","hidden"); keys.isAnalysis();
+      35         387 :   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         129 : }
+      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.15
+
+ + + 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 0000000000..d984c8c1c8 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/AnalysisBase.h.func.html b/coverage/analysis/AnalysisBase.h.func.html new file mode 100644 index 0000000000..d9f81cd880 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/AnalysisBase.h.gcov.html b/coverage/analysis/AnalysisBase.h.gcov.html new file mode 100644 index 0000000000..67e3eaa94e --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..29f315c24e --- /dev/null +++ b/coverage/analysis/Average.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:283384.8 %
Date:2024-06-10 08:19:14Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis7Average10isPeriodicEv0
_ZN4PLMD8analysis7AverageC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis7Average11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis7Average17accumulateAverageERNS_10MultiValueE0
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe1076createERKNS_13ActionOptionsE3
_ZN4PLMD8analysis7AverageC1ERKNS_13ActionOptionsE3
_ZN4PLMD8analysis7Average16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8analysis7Average15finishAveragingEv1022
_ZN4PLMD8analysis7Average17performOperationsERKb1022
_ZN4PLMD8analysis7Average5applyEv1025
_ZN4PLMD8analysis7Average9calculateEv1025
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe107C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe107D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/Average.cpp.func.html b/coverage/analysis/Average.cpp.func.html new file mode 100644 index 0000000000..9eb0a5f192 --- /dev/null +++ b/coverage/analysis/Average.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:283384.8 %
Date:2024-06-10 08:19:14Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe1076createERKNS_13ActionOptionsE3
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe107C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe107D2Ev3473
_ZN4PLMD8analysis7Average10isPeriodicEv0
_ZN4PLMD8analysis7Average15finishAveragingEv1022
_ZN4PLMD8analysis7Average16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8analysis7Average17performOperationsERKb1022
_ZN4PLMD8analysis7Average5applyEv1025
_ZN4PLMD8analysis7Average9calculateEv1025
_ZN4PLMD8analysis7AverageC1ERKNS_13ActionOptionsE3
_ZN4PLMD8analysis7AverageC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis7Average11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis7Average17accumulateAverageERNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/Average.cpp.gcov.html b/coverage/analysis/Average.cpp.gcov.html new file mode 100644 index 0000000000..2c56c8687c --- /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:283384.8 %
Date:2024-06-10 08:19:14Functions:91369.2 %
+
+ + + + + + + + +

+
          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       10425 : PLUMED_REGISTER_ACTION(Average,"AVERAGE")
+     108             : 
+     109           4 : void Average::registerKeywords( Keywords& keys ) {
+     110           4 :   vesselbase::ActionWithAveraging::registerKeywords( keys ); keys.use("ARG");
+     111           8 :   keys.remove("SERIAL"); keys.remove("LOWMEM");
+     112           4 : }
+     113             : 
+     114           3 : Average::Average( const ActionOptions& ao ):
+     115             :   Action(ao),
+     116           3 :   ActionWithAveraging(ao)
+     117             : {
+     118           3 :   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           3 :   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.15
+
+ + + 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 0000000000..bbc63ab053 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/AverageVessel.cpp.func.html b/coverage/analysis/AverageVessel.cpp.func.html new file mode 100644 index 0000000000..55e120c780 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/AverageVessel.cpp.gcov.html b/coverage/analysis/AverageVessel.cpp.gcov.html new file mode 100644 index 0000000000..897757d38a --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..71d798479b --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13AverageVessel11descriptionB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/AverageVessel.h.func.html b/coverage/analysis/AverageVessel.h.func.html new file mode 100644 index 0000000000..48ec46fe03 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13AverageVessel11descriptionB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/AverageVessel.h.gcov.html b/coverage/analysis/AverageVessel.h.gcov.html new file mode 100644 index 0000000000..099dee3b1c --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..70f2b3e0ae --- /dev/null +++ b/coverage/analysis/Committor.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:7474100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9CommittorC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe776createERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9CommittorC1ERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9Committor16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8analysis9Committor5applyEv30
_ZN4PLMD8analysis9Committor9calculateEv30
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe77C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe77D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/Committor.cpp.func.html b/coverage/analysis/Committor.cpp.func.html new file mode 100644 index 0000000000..a7e44f6eb9 --- /dev/null +++ b/coverage/analysis/Committor.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:7474100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe776createERKNS_13ActionOptionsE9
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe77C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe77D2Ev3473
_ZN4PLMD8analysis9Committor16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8analysis9Committor5applyEv30
_ZN4PLMD8analysis9Committor9calculateEv30
_ZN4PLMD8analysis9CommittorC1ERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9CommittorC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/Committor.cpp.gcov.html b/coverage/analysis/Committor.cpp.gcov.html new file mode 100644 index 0000000000..309e4bc154 --- /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:7474100.0 %
Date:2024-06-10 08:19:14Functions:7887.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             : 
+      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       10437 : PLUMED_REGISTER_ACTION(Committor,"COMMITTOR")
+      78             : 
+      79          10 : void Committor::registerKeywords( Keywords& keys ) {
+      80          10 :   Action::registerKeywords(keys);
+      81          10 :   ActionPilot::registerKeywords(keys);
+      82          10 :   ActionWithArguments::registerKeywords(keys);
+      83          10 :   keys.use("ARG");
+      84          20 :   keys.add("numbered", "BASIN_LL","List of lower limits for basin #");
+      85          20 :   keys.add("numbered", "BASIN_UL","List of upper limits for basin #");
+      86          30 :   keys.reset_style("BASIN_LL","compulsory"); keys.reset_style("BASIN_UL","compulsory");
+      87          20 :   keys.add("compulsory","STRIDE","1","the frequency with which the CVs are analyzed");
+      88          20 :   keys.add("optional","FILE","the name of the file on which to output the reached basin");
+      89          20 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+      90          20 :   keys.addFlag("NOSTOP",false,"if true do not stop the simulation when reaching a basin but just keep track of it");
+      91          10 : }
+      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.15
+
+ + + 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 0000000000..9de7bbda77 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.cpp.func.html b/coverage/analysis/DataCollectionObject.cpp.func.html new file mode 100644 index 0000000000..805890e5a0 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.cpp.gcov.html b/coverage/analysis/DataCollectionObject.cpp.gcov.html new file mode 100644 index 0000000000..b271f8cb88 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..d6d85bdef5 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8analysis20DataCollectionObject16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6517
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.h.func.html b/coverage/analysis/DataCollectionObject.h.func.html new file mode 100644 index 0000000000..f97bc36d74 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8analysis20DataCollectionObject16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6517
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.h.gcov.html b/coverage/analysis/DataCollectionObject.h.gcov.html new file mode 100644 index 0000000000..b0fc037a38 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..2294865fad --- /dev/null +++ b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:506083.3 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe606createERKNS_13ActionOptionsE13
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC1ERKNS_13ActionOptionsE13
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix15performAnalysisEv20
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix27getDissimilarityInstructionB5cxx11Ev413
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix22dissimilaritiesWereSetEv436
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe60C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe60D2Ev3473
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16getDissimilarityERKjS3_611659
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html new file mode 100644 index 0000000000..704a0356f5 --- /dev/null +++ b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:506083.3 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe606createERKNS_13ActionOptionsE13
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe60C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe60D2Ev3473
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix15performAnalysisEv20
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16getDissimilarityERKjS3_611659
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC1ERKNS_13ActionOptionsE13
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix22dissimilaritiesWereSetEv436
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix27getDissimilarityInstructionB5cxx11Ev413
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/EuclideanDissimilarityMatrix.cpp.gcov.html b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.gcov.html new file mode 100644 index 0000000000..7fa7b99eb8 --- /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:506083.3 %
Date:2024-06-10 08:19:14Functions: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 "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       10445 : PLUMED_REGISTER_ACTION(EuclideanDissimilarityMatrix,"EUCLIDEAN_DISSIMILARITIES")
+      61             : 
+      62          14 : void EuclideanDissimilarityMatrix::registerKeywords( Keywords& keys ) {
+      63          42 :   AnalysisBase::registerKeywords( keys ); keys.use("ARG"); keys.reset_style("ARG","optional");
+      64          28 :   keys.add("compulsory","METRIC","EUCLIDEAN","the method that you are going to use to measure the distances between points");
+      65          28 :   keys.add("atoms","ATOMS","the list of atoms that you are going to use in the measure of distance that you are using");
+      66          14 : }
+      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.15
+
+ + + 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 0000000000..776abb00c4 --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21FarthestPointSamplingC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe476createERKNS_13ActionOptionsE1
_ZN4PLMD8analysis21FarthestPointSampling15selectLandmarksEv1
_ZN4PLMD8analysis21FarthestPointSamplingC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis21FarthestPointSampling16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe47C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe47D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.func.html b/coverage/analysis/FarthestPointSampling.cpp.func.html new file mode 100644 index 0000000000..df820335ef --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe476createERKNS_13ActionOptionsE1
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe47C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe47D2Ev3473
_ZN4PLMD8analysis21FarthestPointSampling15selectLandmarksEv1
_ZN4PLMD8analysis21FarthestPointSampling16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8analysis21FarthestPointSamplingC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis21FarthestPointSamplingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.gcov.html b/coverage/analysis/FarthestPointSampling.cpp.gcov.html new file mode 100644 index 0000000000..524e2baac5 --- /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:2626100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(FarthestPointSampling,"LANDMARK_SELECT_FPS")
+      48             : 
+      49           2 : void FarthestPointSampling::registerKeywords( Keywords& keys ) {
+      50           2 :   LandmarkSelectionBase::registerKeywords(keys);
+      51           4 :   keys.add("compulsory","SEED","1234","a random number seed");
+      52           2 : }
+      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.15
+
+ + + 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 0000000000..ceaf9bfbca --- /dev/null +++ b/coverage/analysis/Histogram.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + 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:20320897.6 %
Date:2024-06-10 08:19:14Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9Histogram10isPeriodicEv0
_ZN4PLMD8analysis9HistogramC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis9Histogram17performOperationsERKb5
_ZN4PLMD8analysis9Histogram17turnOnDerivativesEv8
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe2236createERKNS_13ActionOptionsE34
_ZN4PLMD8analysis9HistogramC1ERKNS_13ActionOptionsE34
_ZN4PLMD8analysis9Histogram16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD8analysis9Histogram19prepareForAveragingEv115
_ZNK4PLMD8analysis9Histogram10threadSafeEv121
_ZN4PLMD8analysis9Histogram5applyEv133
_ZN4PLMD8analysis9Histogram15finishAveragingEv135
_ZNK4PLMD8analysis9Histogram21getNumberOfQuantitiesEv462
_ZN4PLMD8analysis9Histogram22getNumberOfDerivativesEv728
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe223C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe223D2Ev3473
_ZNK4PLMD8analysis9Histogram7computeERKjRNS_10MultiValueE15404
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.func.html b/coverage/analysis/Histogram.cpp.func.html new file mode 100644 index 0000000000..ffe842710a --- /dev/null +++ b/coverage/analysis/Histogram.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + 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:20320897.6 %
Date:2024-06-10 08:19:14Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe2236createERKNS_13ActionOptionsE34
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe223C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe223D2Ev3473
_ZN4PLMD8analysis9Histogram10isPeriodicEv0
_ZN4PLMD8analysis9Histogram15finishAveragingEv135
_ZN4PLMD8analysis9Histogram16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD8analysis9Histogram17performOperationsERKb5
_ZN4PLMD8analysis9Histogram17turnOnDerivativesEv8
_ZN4PLMD8analysis9Histogram19prepareForAveragingEv115
_ZN4PLMD8analysis9Histogram22getNumberOfDerivativesEv728
_ZN4PLMD8analysis9Histogram5applyEv133
_ZN4PLMD8analysis9HistogramC1ERKNS_13ActionOptionsE34
_ZN4PLMD8analysis9HistogramC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis9Histogram10threadSafeEv121
_ZNK4PLMD8analysis9Histogram21getNumberOfQuantitiesEv462
_ZNK4PLMD8analysis9Histogram7computeERKjRNS_10MultiValueE15404
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.gcov.html b/coverage/analysis/Histogram.cpp.gcov.html new file mode 100644 index 0000000000..f7025b6ab8 --- /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:20320897.6 %
Date:2024-06-10 08:19:14Functions:141687.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 "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       10487 : PLUMED_REGISTER_ACTION(Histogram,"HISTOGRAM")
+     224             : 
+     225          35 : void Histogram::registerKeywords( Keywords& keys ) {
+     226          70 :   gridtools::ActionWithGrid::registerKeywords( keys ); keys.use("ARG"); keys.remove("NORMALIZATION");
+     227          70 :   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          70 :   keys.add("optional","DATA","input data from action with vessel and compute histogram");
+     229          70 :   keys.add("optional","VECTORS","input three dimensional vectors for computing histogram");
+     230          70 :   keys.add("compulsory","GRID_MIN","the lower bounds for the grid");
+     231          70 :   keys.add("compulsory","GRID_MAX","the upper bounds for the grid");
+     232          70 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     233          70 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     234          70 :   keys.use("UPDATE_FROM"); keys.use("UPDATE_UNTIL");
+     235          35 : }
+     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 :   setForcesOnAtoms( finalForces );
+     530             :   // Reset everything for next regular loop
+     531          20 :   in_apply=false;
+     532             : }
+     533             : 
+     534             : }
+     535             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..3f07e04f73 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21LandmarkSelectionBaseC1ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis21LandmarkSelectionBase15voronoiAnalysisERKSt6vectorIjSaIjEERS2_IdSaIdEERS4_8
_ZN4PLMD8analysis21LandmarkSelectionBaseC2ERKNS_13ActionOptionsE10
_ZN4PLMD8analysis21LandmarkSelectionBase15performAnalysisEv12
_ZN4PLMD8analysis21LandmarkSelectionBase16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD8analysis21LandmarkSelectionBase11selectFrameERKj291
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.cpp.func.html b/coverage/analysis/LandmarkSelectionBase.cpp.func.html new file mode 100644 index 0000000000..ce200ec495 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21LandmarkSelectionBase11selectFrameERKj291
_ZN4PLMD8analysis21LandmarkSelectionBase15performAnalysisEv12
_ZN4PLMD8analysis21LandmarkSelectionBase16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD8analysis21LandmarkSelectionBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis21LandmarkSelectionBaseC2ERKNS_13ActionOptionsE10
_ZNK4PLMD8analysis21LandmarkSelectionBase15voronoiAnalysisERKSt6vectorIjSaIjEERS2_IdSaIdEERS4_8
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.cpp.gcov.html b/coverage/analysis/LandmarkSelectionBase.cpp.gcov.html new file mode 100644 index 0000000000..ebb419d215 --- /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-06-10 08:19:14Functions: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          15 : void LandmarkSelectionBase::registerKeywords( Keywords& keys ) {
+      28          15 :   AnalysisBase::registerKeywords( keys );
+      29          30 :   keys.add("compulsory","NLANDMARKS","the number of landmarks that you would like to select");
+      30          30 :   keys.addFlag("NOVORONOI",false,"do not do a Voronoi analysis of the data to determine weights of final points");
+      31          30 :   keys.addFlag("IGNORE_WEIGHTS",false,"ignore the weights in the underlying analysis object");
+      32          15 : }
+      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.15
+
+ + + 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 0000000000..d05012ad1a --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.h.func.html b/coverage/analysis/LandmarkSelectionBase.h.func.html new file mode 100644 index 0000000000..a68ead8594 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.h.gcov.html b/coverage/analysis/LandmarkSelectionBase.h.gcov.html new file mode 100644 index 0000000000..d1a16260fc --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..401565a0e5 --- /dev/null +++ b/coverage/analysis/LandmarkStaged.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:64712.8 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe506createERKNS_13ActionOptionsE0
_ZN4PLMD8analysis14LandmarkStaged15selectLandmarksEv0
_ZN4PLMD8analysis14LandmarkStagedC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis14LandmarkStagedC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis14LandmarkStaged16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe50C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe50D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/LandmarkStaged.cpp.func.html b/coverage/analysis/LandmarkStaged.cpp.func.html new file mode 100644 index 0000000000..c9398e1d54 --- /dev/null +++ b/coverage/analysis/LandmarkStaged.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:64712.8 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe506createERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe50C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe50D2Ev3473
_ZN4PLMD8analysis14LandmarkStaged15selectLandmarksEv0
_ZN4PLMD8analysis14LandmarkStaged16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD8analysis14LandmarkStagedC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis14LandmarkStagedC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/LandmarkStaged.cpp.gcov.html b/coverage/analysis/LandmarkStaged.cpp.gcov.html new file mode 100644 index 0000000000..a9a98ad49c --- /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:64712.8 %
Date:2024-06-10 08:19:14Functions:3742.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 "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       10419 : PLUMED_REGISTER_ACTION(LandmarkStaged,"LANDMARK_SELECT_STAGED")
+      51             : 
+      52           1 : void LandmarkStaged::registerKeywords( Keywords& keys ) {
+      53           1 :   LandmarkSelectionBase::registerKeywords(keys);
+      54           2 :   keys.add("compulsory","GAMMA","the gamma parameter to be used in weights");
+      55           2 :   keys.add("compulsory","SEED","1234","a random number seed");
+      56           1 : }
+      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.15
+
+ + + 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 0000000000..dc01c241c8 --- /dev/null +++ b/coverage/analysis/OutputColvarFile.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:474897.9 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis16OutputColvarFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis16OutputColvarFile11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe606createERKNS_13ActionOptionsE20
_ZN4PLMD8analysis16OutputColvarFileC1ERKNS_13ActionOptionsE20
_ZN4PLMD8analysis16OutputColvarFile16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD8analysis16OutputColvarFile15performAnalysisEv24
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe60C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe60D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/OutputColvarFile.cpp.func.html b/coverage/analysis/OutputColvarFile.cpp.func.html new file mode 100644 index 0000000000..e3fc1cf44c --- /dev/null +++ b/coverage/analysis/OutputColvarFile.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:474897.9 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe606createERKNS_13ActionOptionsE20
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe60C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe60D2Ev3473
_ZN4PLMD8analysis16OutputColvarFile15performAnalysisEv24
_ZN4PLMD8analysis16OutputColvarFile16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD8analysis16OutputColvarFileC1ERKNS_13ActionOptionsE20
_ZN4PLMD8analysis16OutputColvarFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis16OutputColvarFile11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/OutputColvarFile.cpp.gcov.html b/coverage/analysis/OutputColvarFile.cpp.gcov.html new file mode 100644 index 0000000000..831eaa8f7a --- /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:474897.9 %
Date:2024-06-10 08:19:14Functions: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 "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       10459 : PLUMED_REGISTER_ACTION(OutputColvarFile,"OUTPUT_ANALYSIS_DATA_TO_COLVAR")
+      61             : 
+      62          21 : void OutputColvarFile::registerKeywords( Keywords& keys ) {
+      63          21 :   AnalysisBase::registerKeywords( keys ); keys.use("ARG");
+      64          42 :   keys.add("compulsory","FILE","the name of the file to output to");
+      65          42 :   keys.add("compulsory","REPLICA","0","the replicas for which you would like to output this information");
+      66          42 :   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          42 :   keys.add("optional","FMT","the format to output the data using");
+      68          21 : }
+      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 :     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.15
+
+ + + 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 0000000000..a978175460 --- /dev/null +++ b/coverage/analysis/OutputPDBFile.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:293096.7 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13OutputPDBFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis13OutputPDBFile11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe566createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13OutputPDBFileC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13OutputPDBFile16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8analysis13OutputPDBFile15performAnalysisEv8
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe56C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe56D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/OutputPDBFile.cpp.func.html b/coverage/analysis/OutputPDBFile.cpp.func.html new file mode 100644 index 0000000000..ba7cf8d0a5 --- /dev/null +++ b/coverage/analysis/OutputPDBFile.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:293096.7 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe566createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe56C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe56D2Ev3473
_ZN4PLMD8analysis13OutputPDBFile15performAnalysisEv8
_ZN4PLMD8analysis13OutputPDBFile16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8analysis13OutputPDBFileC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13OutputPDBFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis13OutputPDBFile11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/OutputPDBFile.cpp.gcov.html b/coverage/analysis/OutputPDBFile.cpp.gcov.html new file mode 100644 index 0000000000..80fbff553a --- /dev/null +++ b/coverage/analysis/OutputPDBFile.cpp.gcov.html @@ -0,0 +1,177 @@ + + + + + + + + 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:293096.7 %
Date:2024-06-10 08:19:14Functions: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 "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/Atoms.h"
+      29             : #include "core/GenericMolInfo.h"
+      30             : #include "tools/PDB.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace analysis {
+      34             : 
+      35             : //+PLUMEDOC ANALYSIS OUTPUT_ANALYSIS_DATA_TO_PDB
+      36             : /*
+      37             : This can be used to output the data that has been stored in an Analysis object.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : class OutputPDBFile : public AnalysisBase {
+      45             : private:
+      46             :   PDB mypdb;
+      47             :   std::string fmt;
+      48             :   std::string filename;
+      49             : public:
+      50             :   static void registerKeywords( Keywords& keys );
+      51             :   explicit OutputPDBFile( const ActionOptions& );
+      52           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      53             :   void performAnalysis() override;
+      54             : };
+      55             : 
+      56       10431 : PLUMED_REGISTER_ACTION(OutputPDBFile,"OUTPUT_ANALYSIS_DATA_TO_PDB")
+      57             : 
+      58           7 : void OutputPDBFile::registerKeywords( Keywords& keys ) {
+      59           7 :   AnalysisBase::registerKeywords( keys );
+      60          14 :   keys.add("compulsory","FILE","the name of the file to output to");
+      61          14 :   keys.add("optional","FMT","the format to use in the output file");
+      62          14 :   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");
+      63           7 : }
+      64             : 
+      65           6 : OutputPDBFile::OutputPDBFile( const ActionOptions& ao ):
+      66             :   Action(ao),
+      67             :   AnalysisBase(ao),
+      68           6 :   fmt("%f")
+      69             : {
+      70             :   // Get setup the pdb
+      71           6 :   mypdb.setAtomNumbers( my_input_data->getAtomIndexes() );
+      72           6 :   mypdb.setArgumentNames( my_input_data->getArgumentNames() );
+      73             : 
+      74             :   // Find a moldata object
+      75           6 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      76          12 :   if( ! moldat ) warning("PDB output files do not have atom types unless you use MOLDATA");
+      77             : 
+      78          18 :   parse("FILE",filename); parse("FMT",fmt);
+      79          12 :   if( !getRestart() ) { OFile ofile; ofile.link(*this); ofile.setBackupString("analysis"); ofile.backupAllFiles(filename); }
+      80           6 :   log.printf("  printing data to file named %s \n",filename.c_str() );
+      81           6 : }
+      82             : 
+      83           8 : void OutputPDBFile::performAnalysis() {
+      84             :   // Find a moldata object
+      85           8 :   auto* mymoldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      86             :   // Output the embedding in plumed pdb format
+      87          16 :   OFile afile; afile.link(*this); afile.setBackupString("analysis"); std::size_t psign=fmt.find("%");
+      88          16 :   afile.open( filename ); std::string descr="REMARK WEIGHT=%-" + fmt.substr(psign+1) + "\n";
+      89         426 :   for(unsigned j=0; j<getNumberOfDataPoints(); ++j) {
+      90         418 :     afile.printf("DESCRIPTION: analysis data from calculation done by %s at time %f \n",getLabel().c_str(),getTime() );
+      91         836 :     if( dissimilaritiesWereSet() ) afile.printf("REMARK %s \n", getDissimilarityInstruction().c_str() );
+      92         418 :     afile.printf(descr.c_str(),getWeight(j) ); getStoredData(j,false).transferDataToPDB( mypdb );
+      93         418 :     if( plumed.getAtoms().usingNaturalUnits() ) mypdb.print( 1.0, mymoldat, afile, fmt );
+      94          18 :     else mypdb.print( plumed.getAtoms().getUnits().getLength()/0.1, mymoldat, afile, fmt );
+      95             :   }
+      96           8 :   afile.close();
+      97           8 : }
+      98             : 
+      99             : }
+     100             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..6a3f31ca11 --- /dev/null +++ b/coverage/analysis/PrintDissimilarityMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:222395.7 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis24PrintDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis24PrintDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe506createERKNS_13ActionOptionsE8
_ZN4PLMD8analysis24PrintDissimilarityMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis24PrintDissimilarityMatrix15performAnalysisEv9
_ZN4PLMD8analysis24PrintDissimilarityMatrix16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe50C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe50D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/PrintDissimilarityMatrix.cpp.func.html b/coverage/analysis/PrintDissimilarityMatrix.cpp.func.html new file mode 100644 index 0000000000..c0d5b6ec36 --- /dev/null +++ b/coverage/analysis/PrintDissimilarityMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:222395.7 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe506createERKNS_13ActionOptionsE8
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe50C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe50D2Ev3473
_ZN4PLMD8analysis24PrintDissimilarityMatrix15performAnalysisEv9
_ZN4PLMD8analysis24PrintDissimilarityMatrix16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD8analysis24PrintDissimilarityMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis24PrintDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis24PrintDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/PrintDissimilarityMatrix.cpp.gcov.html b/coverage/analysis/PrintDissimilarityMatrix.cpp.gcov.html new file mode 100644 index 0000000000..181d782e17 --- /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:222395.7 %
Date:2024-06-10 08:19:14Functions: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 "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       10435 : PLUMED_REGISTER_ACTION(PrintDissimilarityMatrix,"PRINT_DISSIMILARITY_MATRIX")
+      51             : 
+      52           9 : void PrintDissimilarityMatrix::registerKeywords( Keywords& keys ) {
+      53           9 :   AnalysisBase::registerKeywords( keys );
+      54          18 :   keys.add("compulsory","FILE","name of file on which to output the data");
+      55          18 :   keys.add("optional","FMT","the format to use for the output of numbers");
+      56          18 :   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           9 : }
+      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.15
+
+ + + 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 0000000000..a3fb3e5b68 --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:747894.9 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis18ReadAnalysisFramesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis18ReadAnalysisFrames27getDissimilarityInstructionB5cxx11Ev5
_ZNK4PLMD8analysis18ReadAnalysisFrames14getAtomIndexesEv12
_ZN4PLMD8analysis18ReadAnalysisFrames16calculateWeightsEv26
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe396createERKNS_13ActionOptionsE30
_ZN4PLMD8analysis18ReadAnalysisFramesC1ERKNS_13ActionOptionsE30
_ZN4PLMD8analysis18ReadAnalysisFrames16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD8analysis18ReadAnalysisFrames15getArgumentListEv62
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe39C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe39D2Ev3473
_ZN4PLMD8analysis18ReadAnalysisFrames6updateEv7500
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.cpp.func.html b/coverage/analysis/ReadAnalysisFrames.cpp.func.html new file mode 100644 index 0000000000..5286ba44af --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:747894.9 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe396createERKNS_13ActionOptionsE30
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe39C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe39D2Ev3473
_ZN4PLMD8analysis18ReadAnalysisFrames15getArgumentListEv62
_ZN4PLMD8analysis18ReadAnalysisFrames16calculateWeightsEv26
_ZN4PLMD8analysis18ReadAnalysisFrames16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD8analysis18ReadAnalysisFrames6updateEv7500
_ZN4PLMD8analysis18ReadAnalysisFramesC1ERKNS_13ActionOptionsE30
_ZN4PLMD8analysis18ReadAnalysisFramesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis18ReadAnalysisFrames14getAtomIndexesEv12
_ZNK4PLMD8analysis18ReadAnalysisFrames27getDissimilarityInstructionB5cxx11Ev5
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.cpp.gcov.html b/coverage/analysis/ReadAnalysisFrames.cpp.gcov.html new file mode 100644 index 0000000000..4ea3bddeb2 --- /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:747894.9 %
Date:2024-06-10 08:19:14Functions:101190.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 "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       10479 : PLUMED_REGISTER_ACTION(ReadAnalysisFrames,"COLLECT_FRAMES")
+      40             : 
+      41          31 : void ReadAnalysisFrames::registerKeywords( Keywords& keys ) {
+      42          31 :   AnalysisBase::registerKeywords( keys );
+      43          93 :   keys.remove("SERIAL"); keys.remove("USE_OUTPUT_DATA_FROM"); keys.use("ARG");
+      44          62 :   keys.add("atoms-1","ATOMS","the atoms whose positions we are tracking for the purpose of analyzing the data");
+      45          62 :   keys.add("atoms-1","STRIDE","the frequency with which data should be stored for analysis.  By default data is collected on every step");
+      46          62 :   keys.add("compulsory","CLEAR","0","the frequency with which data should all be deleted and restarted");
+      47          62 :   keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages");
+      48          31 :   ActionWithValue::useCustomisableComponents( keys );
+      49          31 : }
+      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.15
+
+ + + 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 0000000000..d8cb09f949 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.h.func.html b/coverage/analysis/ReadAnalysisFrames.h.func.html new file mode 100644 index 0000000000..495c152136 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.h.gcov.html b/coverage/analysis/ReadAnalysisFrames.h.gcov.html new file mode 100644 index 0000000000..6c90faa251 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..4217e8e4b6 --- /dev/null +++ b/coverage/analysis/ReadDissimilarityMatrix.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + 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-06-10 08:19:14Functions:121675.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis23ReadDissimilarityMatrix15performAnalysisEv0
_ZN4PLMD8analysis23ReadDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix23getDataPointIndexInBaseERKj0
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe766createERKNS_13ActionOptionsE2
_ZN4PLMD8analysis23ReadDissimilarityMatrix12runFinalJobsEv2
_ZN4PLMD8analysis23ReadDissimilarityMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD8analysis23ReadDissimilarityMatrix16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8analysis23ReadDissimilarityMatrix13getStoredDataERKjRKb5
_ZN4PLMD8analysis23ReadDissimilarityMatrix6updateEv7
_ZNK4PLMD8analysis23ReadDissimilarityMatrix22dissimilaritiesWereSetEv11
_ZN4PLMD8analysis23ReadDissimilarityMatrix9getWeightERKj18
_ZNK4PLMD8analysis23ReadDissimilarityMatrix21getNumberOfDataPointsEv257
_ZN4PLMD8analysis23ReadDissimilarityMatrix16getDissimilarityERKjS3_334
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe76C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe76D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/ReadDissimilarityMatrix.cpp.func.html b/coverage/analysis/ReadDissimilarityMatrix.cpp.func.html new file mode 100644 index 0000000000..5343c20e22 --- /dev/null +++ b/coverage/analysis/ReadDissimilarityMatrix.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + 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-06-10 08:19:14Functions:121675.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe766createERKNS_13ActionOptionsE2
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe76C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe76D2Ev3473
_ZN4PLMD8analysis23ReadDissimilarityMatrix12runFinalJobsEv2
_ZN4PLMD8analysis23ReadDissimilarityMatrix13getStoredDataERKjRKb5
_ZN4PLMD8analysis23ReadDissimilarityMatrix15performAnalysisEv0
_ZN4PLMD8analysis23ReadDissimilarityMatrix16getDissimilarityERKjS3_334
_ZN4PLMD8analysis23ReadDissimilarityMatrix16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8analysis23ReadDissimilarityMatrix6updateEv7
_ZN4PLMD8analysis23ReadDissimilarityMatrix9getWeightERKj18
_ZN4PLMD8analysis23ReadDissimilarityMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD8analysis23ReadDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix21getNumberOfDataPointsEv257
_ZNK4PLMD8analysis23ReadDissimilarityMatrix22dissimilaritiesWereSetEv11
_ZNK4PLMD8analysis23ReadDissimilarityMatrix23getDataPointIndexInBaseERKj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html b/coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html new file mode 100644 index 0000000000..80d209c6ec --- /dev/null +++ b/coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html @@ -0,0 +1,242 @@ + + + + + + + + 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-06-10 08:19:14Functions:121675.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 "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 "tools/IFile.h"
+      31             : 
+      32             : //+PLUMEDOC ANALYSIS READ_DISSIMILARITY_MATRIX
+      33             : /*
+      34             : Read a matrix of dissimilarities between a trajectory of atomic configurations from a file.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace analysis {
+      43             : 
+      44             : class ReadDissimilarityMatrix : public AnalysisBase {
+      45             : private:
+      46             :   unsigned nnodes;
+      47             :   std::vector<DataCollectionObject> fake_data;
+      48             :   std::string fname, wfile;
+      49             : //  Matrix<double> dissimilarities;
+      50             :   std::vector<std::vector<double> > dissimilarities;
+      51             :   std::vector<double> weights;
+      52             : public:
+      53             :   static void registerKeywords( Keywords& keys );
+      54             :   explicit ReadDissimilarityMatrix( const ActionOptions& ao );
+      55             :   unsigned getNumberOfDataPoints() const override;
+      56             : // Return the index of the data point in the base class
+      57             :   unsigned getDataPointIndexInBase( const unsigned& idata ) const override;
+      58             : /// This gives an error as if we read in the matrix we dont have the coordinates
+      59             :   DataCollectionObject& getStoredData( const unsigned& idata, const bool& calcdist ) override;
+      60             : /// Tell everyone we have dissimilarities
+      61          11 :   bool dissimilaritiesWereSet() const override { return true; }
+      62             : /// Get the dissimilarity between two data points
+      63             :   double getDissimilarity( const unsigned&, const unsigned& ) override;
+      64             : /// Get the weight from the input file
+      65             :   double getWeight( const unsigned& idata ) override;
+      66             : /// Just tell plumed to stop
+      67             :   void update() override;
+      68             : /// Read in the dissimilarity matrix
+      69             :   void runFinalJobs() override;
+      70             : /// This does nothing
+      71           0 :   void performAnalysis() override {};
+      72             : /// Overwrite virtual function in base class
+      73           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      74             : };
+      75             : 
+      76       10423 : PLUMED_REGISTER_ACTION(ReadDissimilarityMatrix,"READ_DISSIMILARITY_MATRIX")
+      77             : 
+      78           3 : void ReadDissimilarityMatrix::registerKeywords( Keywords& keys ) {
+      79           3 :   AnalysisBase::registerKeywords( keys );
+      80           6 :   keys.add("compulsory","FILE","an input file containing the matrix of dissimilarities");
+      81           6 :   keys.add("optional","WFILE","input file containing weights of points");
+      82           6 :   keys.reset_style("USE_OUTPUT_DATA_FROM","optional");
+      83           3 : }
+      84             : 
+      85           2 : ReadDissimilarityMatrix::ReadDissimilarityMatrix( const ActionOptions& ao ):
+      86             :   Action(ao),
+      87             :   AnalysisBase(ao),
+      88           2 :   nnodes(1)
+      89             : {
+      90           2 :   setStride(1); // Set the stride equal to one to ensure we don't get stuck in an infinite loop
+      91           2 :   std::vector<ActionSetup*> setupActions=plumed.getActionSet().select<ActionSetup*>();
+      92           2 :   if( my_input_data && (plumed.getActionSet().size()-setupActions.size())!=1 ) error("should only be this action and the READ_ANALYSIS_FRAMES command in the input file");
+      93           2 :   if( !my_input_data && plumed.getActionSet().size()!=0 ) error("read dissimilarity matrix command must be at top of input file");
+      94             : 
+      95           2 :   parse("FILE",fname);
+      96           2 :   log.printf("  reading dissimilarity matrix from file %s \n",fname.c_str() );
+      97           4 :   parse("WFILE",wfile);
+      98             : 
+      99           2 :   if( wfile.length()>0 ) log.printf("  reading weights of nodes from file named %s \n",wfile.c_str() );
+     100           2 :   else log.printf("  setting weights of all nodes equal to one\n");
+     101           2 : }
+     102             : 
+     103           7 : void ReadDissimilarityMatrix::update() { if(!my_input_data) plumed.stop(); }
+     104             : 
+     105           2 : void ReadDissimilarityMatrix::runFinalJobs() {
+     106           2 :   IFile mfile; mfile.open(fname);
+     107             :   // Read in first line
+     108           2 :   std::vector<std::string> words; nnodes=0;
+     109           4 :   while( nnodes==0 ) {
+     110           2 :     Tools::getParsedLine( mfile, words );
+     111           2 :     nnodes=words.size();
+     112             :   }
+     113             : 
+     114           2 :   std::vector<double> tmpdis( nnodes );
+     115          20 :   for(unsigned j=0; j<nnodes; ++j) Tools::convert( words[j], tmpdis[j] );
+     116           2 :   dissimilarities.push_back( tmpdis );
+     117             : 
+     118          18 :   while( Tools::getParsedLine( mfile, words ) ) {
+     119          16 :     if( words.size()!=nnodes ) error("bad formatting in matrix file");
+     120         192 :     for(unsigned j=0; j<nnodes; ++j) Tools::convert( words[j], tmpdis[j] );
+     121          16 :     dissimilarities.push_back( tmpdis );
+     122             :   }
+     123           2 :   mfile.close();
+     124           2 :   if( my_input_data && dissimilarities.size()!=getNumberOfDataPoints() ) {
+     125           0 :     error("mismatch between number of data points in trajectory and the dimensions of the dissimilarity matrix");
+     126             :   }
+     127           2 :   if( !my_input_data ) fake_data.resize( dissimilarities.size() );
+     128             : 
+     129           2 :   weights.resize( dissimilarities.size() );
+     130           2 :   if( wfile.length()>0 ) {
+     131           0 :     IFile wfilef; wfilef.open(wfile);
+     132           0 :     for(unsigned i=0; i<weights.size(); ++i) {
+     133           0 :       Tools::getParsedLine( wfilef, words ); Tools::convert( words[0], weights[i] );
+     134             :     }
+     135           0 :     wfilef.close();
+     136           0 :   } else {
+     137           2 :     weights.assign(weights.size(),1.0);
+     138             :   }
+     139           2 : }
+     140             : 
+     141         257 : unsigned ReadDissimilarityMatrix::getNumberOfDataPoints() const {
+     142         302 :   if( my_input_data ) return AnalysisBase::getNumberOfDataPoints();
+     143         212 :   return dissimilarities.size();
+     144             : }
+     145             : 
+     146           0 : unsigned ReadDissimilarityMatrix::getDataPointIndexInBase( const unsigned& idata ) const {
+     147           0 :   return idata;
+     148             : }
+     149             : 
+     150         334 : double ReadDissimilarityMatrix::getDissimilarity( const unsigned& iframe, const unsigned& jframe ) {
+     151         334 :   return dissimilarities[iframe][jframe]*dissimilarities[iframe][jframe];
+     152             : }
+     153             : 
+     154           5 : DataCollectionObject& ReadDissimilarityMatrix::getStoredData( const unsigned& idata, const bool& calcdist ) {
+     155           5 :   plumed_massert( !calcdist, "cannot calc dist as this data was read in from input");
+     156          10 :   if( my_input_data ) return AnalysisBase::getStoredData( idata, calcdist );
+     157           0 :   return fake_data[idata];
+     158             : }
+     159             : 
+     160          18 : double ReadDissimilarityMatrix::getWeight( const unsigned& idata ) {
+     161          18 :   plumed_assert( idata<dissimilarities.size() ); return weights[idata];
+     162             : }
+     163             : 
+     164             : }
+     165             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7f8bfef120 --- /dev/null +++ b/coverage/analysis/ReselectLandmarks.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1717100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis17ReselectLandmarksC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe496createERKNS_13ActionOptionsE1
_ZN4PLMD8analysis17ReselectLandmarks15selectLandmarksEv1
_ZN4PLMD8analysis17ReselectLandmarksC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis17ReselectLandmarks16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe49C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe49D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/ReselectLandmarks.cpp.func.html b/coverage/analysis/ReselectLandmarks.cpp.func.html new file mode 100644 index 0000000000..aa4184b087 --- /dev/null +++ b/coverage/analysis/ReselectLandmarks.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1717100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe496createERKNS_13ActionOptionsE1
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe49C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe49D2Ev3473
_ZN4PLMD8analysis17ReselectLandmarks15selectLandmarksEv1
_ZN4PLMD8analysis17ReselectLandmarks16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8analysis17ReselectLandmarksC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis17ReselectLandmarksC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/ReselectLandmarks.cpp.gcov.html b/coverage/analysis/ReselectLandmarks.cpp.gcov.html new file mode 100644 index 0000000000..ecc186d23a --- /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:1717100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(ReselectLandmarks,"RESELECT_LANDMARKS")
+      50             : 
+      51           2 : void ReselectLandmarks::registerKeywords( Keywords& keys ) {
+      52           2 :   LandmarkSelectionBase::registerKeywords(keys);
+      53           2 :   keys.remove("NLANDMARKS");
+      54           4 :   keys.add("compulsory","LANDMARKS","the action that selects the landmarks that you want to reselect using this action");
+      55           2 : }
+      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.15
+
+ + + 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 0000000000..05f1f381cf --- /dev/null +++ b/coverage/analysis/SelectRandomFrames.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:52025.0 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe476createERKNS_13ActionOptionsE0
_ZN4PLMD8analysis18SelectRandomFrames15selectLandmarksEv0
_ZN4PLMD8analysis18SelectRandomFramesC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis18SelectRandomFramesC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis18SelectRandomFrames16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe47C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe47D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/SelectRandomFrames.cpp.func.html b/coverage/analysis/SelectRandomFrames.cpp.func.html new file mode 100644 index 0000000000..9a903690dc --- /dev/null +++ b/coverage/analysis/SelectRandomFrames.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:52025.0 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe476createERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe47C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe47D2Ev3473
_ZN4PLMD8analysis18SelectRandomFrames15selectLandmarksEv0
_ZN4PLMD8analysis18SelectRandomFrames16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD8analysis18SelectRandomFramesC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis18SelectRandomFramesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/SelectRandomFrames.cpp.gcov.html b/coverage/analysis/SelectRandomFrames.cpp.gcov.html new file mode 100644 index 0000000000..faad50967b --- /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:52025.0 %
Date:2024-06-10 08:19:14Functions:3742.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 "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       10419 : PLUMED_REGISTER_ACTION(SelectRandomFrames,"LANDMARK_SELECT_RANDOM")
+      48             : 
+      49           1 : void SelectRandomFrames::registerKeywords( Keywords& keys ) {
+      50           1 :   LandmarkSelectionBase::registerKeywords(keys);
+      51           2 :   keys.add("compulsory","SEED","1234","a random number seed");
+      52           1 : }
+      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.15
+
+ + + 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 0000000000..60baf919b3 --- /dev/null +++ b/coverage/analysis/SelectWithStride.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis16SelectWithStrideC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe446createERKNS_13ActionOptionsE8
_ZN4PLMD8analysis16SelectWithStrideC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis16SelectWithStride16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD8analysis16SelectWithStride15selectLandmarksEv10
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe44C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe44D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/SelectWithStride.cpp.func.html b/coverage/analysis/SelectWithStride.cpp.func.html new file mode 100644 index 0000000000..500658632e --- /dev/null +++ b/coverage/analysis/SelectWithStride.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe446createERKNS_13ActionOptionsE8
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe44C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe44D2Ev3473
_ZN4PLMD8analysis16SelectWithStride15selectLandmarksEv10
_ZN4PLMD8analysis16SelectWithStride16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD8analysis16SelectWithStrideC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis16SelectWithStrideC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/SelectWithStride.cpp.gcov.html b/coverage/analysis/SelectWithStride.cpp.gcov.html new file mode 100644 index 0000000000..c0766ed762 --- /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:1111100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10435 : PLUMED_REGISTER_ACTION(SelectWithStride,"LANDMARK_SELECT_STRIDE")
+      45             : 
+      46           9 : void SelectWithStride::registerKeywords( Keywords& keys ) {
+      47           9 :   LandmarkSelectionBase::registerKeywords( keys );
+      48           9 : }
+      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.15
+
+ + + 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 0000000000..4fd2e8c9a1 --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:3030100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13WhamHistogramC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe816createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13WhamHistogramC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13WhamHistogram16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe81C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe81D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.func.html b/coverage/analysis/WhamHistogram.cpp.func.html new file mode 100644 index 0000000000..c845d8effa --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:3030100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe816createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe81C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe81D2Ev3473
_ZN4PLMD8analysis13WhamHistogram16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8analysis13WhamHistogramC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13WhamHistogramC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.gcov.html b/coverage/analysis/WhamHistogram.cpp.gcov.html new file mode 100644 index 0000000000..3b725ff135 --- /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:3030100.0 %
Date:2024-06-10 08:19:14Functions:5683.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 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       10431 : PLUMED_REGISTER_ACTION(WhamHistogram,"WHAM_HISTOGRAM")
+      82             : 
+      83           7 : void WhamHistogram::registerKeywords( Keywords& keys ) {
+      84           7 :   ActionShortcut::registerKeywords( keys );
+      85          14 :   keys.add("compulsory","ARG","the arguments that you would like to make the histogram for");
+      86          14 :   keys.add("compulsory","BIAS","*.bias","the value of the biases to use when performing WHAM");
+      87          14 :   keys.add("compulsory","TEMP","the temperature at which the simulation was run");
+      88          14 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be stored to perform WHAM");
+      89          14 :   keys.add("compulsory","GRID_MIN","the minimum to use for the grid");
+      90          14 :   keys.add("compulsory","GRID_MAX","the maximum to use for the grid");
+      91          14 :   keys.add("compulsory","GRID_BIN","the number of bins to use for the grid");
+      92          14 :   keys.add("optional","BANDWIDTH","the bandwidth for kernel density estimation");
+      93           7 : }
+      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.15
+
+ + + 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 0000000000..ca0df1c483 --- /dev/null +++ b/coverage/analysis/WhamWeights.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:2323100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis11WhamWeightsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis11WhamWeightsC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe756createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis11WhamWeights16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe75C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe75D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/WhamWeights.cpp.func.html b/coverage/analysis/WhamWeights.cpp.func.html new file mode 100644 index 0000000000..2071b1536f --- /dev/null +++ b/coverage/analysis/WhamWeights.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:2323100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis11WhamWeights16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8analysis11WhamWeightsC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis11WhamWeightsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe756createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe75C2Ev3473
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe75D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/WhamWeights.cpp.gcov.html b/coverage/analysis/WhamWeights.cpp.gcov.html new file mode 100644 index 0000000000..fe574a716a --- /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:2323100.0 %
Date:2024-06-10 08:19:14Functions:5683.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 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       10431 : PLUMED_REGISTER_ACTION(WhamWeights,"WHAM_WEIGHTS")
+      76             : 
+      77           7 : void WhamWeights::registerKeywords( Keywords& keys ) {
+      78           7 :   ActionShortcut::registerKeywords( keys ); keys.remove("LABEL");
+      79          14 :   keys.add("compulsory","BIAS","*.bias","the value of the biases to use when performing WHAM");
+      80          14 :   keys.add("compulsory","TEMP","the temperature at which the simulation was run");
+      81          14 :   keys.add("compulsory","STRIDE","1","the frequency with which the bias should be stored to perform WHAM");
+      82          14 :   keys.add("compulsory","FILE","the file on which to output the WHAM weights");
+      83          14 :   keys.add("optional","FMT","the format to use for the real numbers in the output file");
+      84           7 : }
+      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.15
+
+ + + diff --git a/coverage/analysis/index-sort-f.html b/coverage/analysis/index-sort-f.html new file mode 100644 index 0000000000..56ec168810 --- /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:85997188.5 %
Date:2024-06-10 08:19:14Functions:15620277.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SelectRandomFrames.cpp +
25.0%25.0%
+
25.0 %5 / 2042.9 %3 / 7
LandmarkStaged.cpp +
12.8%12.8%
+
12.8 %6 / 4742.9 %3 / 7
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
Average.cpp +
84.8%84.8%
+
84.8 %28 / 3369.2 %9 / 13
OutputColvarFile.cpp +
97.9%97.9%
+
97.9 %47 / 4875.0 %6 / 8
OutputPDBFile.cpp +
96.7%96.7%
+
96.7 %29 / 3075.0 %6 / 8
PrintDissimilarityMatrix.cpp +
95.7%95.7%
+
95.7 %22 / 2375.0 %6 / 8
ReadDissimilarityMatrix.cpp +
82.3%82.3%
+
82.3 %51 / 6275.0 %12 / 16
EuclideanDissimilarityMatrix.cpp +
83.3%83.3%
+
83.3 %50 / 6081.8 %9 / 11
LandmarkSelectionBase.cpp +
100.0%
+
100.0 %41 / 4183.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
AverageVessel.cpp +
91.7%91.7%
+
91.7 %22 / 2483.3 %5 / 6
WhamWeights.cpp +
100.0%
+
100.0 %23 / 2383.3 %5 / 6
WhamHistogram.cpp +
100.0%
+
100.0 %30 / 3083.3 %5 / 6
ReselectLandmarks.cpp +
100.0%
+
100.0 %17 / 1785.7 %6 / 7
SelectWithStride.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
FarthestPointSampling.cpp +
100.0%
+
100.0 %26 / 2685.7 %6 / 7
Committor.cpp +
100.0%
+
100.0 %74 / 7487.5 %7 / 8
Histogram.cpp +
97.6%97.6%
+
97.6 %203 / 20887.5 %14 / 16
ReadAnalysisFrames.cpp +
94.9%94.9%
+
94.9 %74 / 7890.9 %10 / 11
AverageVessel.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
DataCollectionObject.h +
80.0%80.0%
+
80.0 %4 / 5100.0 %1 / 1
DataCollectionObject.cpp +
100.0%
+
100.0 %21 / 21100.0 %4 / 4
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/index-sort-l.html b/coverage/analysis/index-sort-l.html new file mode 100644 index 0000000000..0110ab54b8 --- /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:85997188.5 %
Date:2024-06-10 08:19:14Functions:15620277.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LandmarkStaged.cpp +
12.8%12.8%
+
12.8 %6 / 4742.9 %3 / 7
SelectRandomFrames.cpp +
25.0%25.0%
+
25.0 %5 / 2042.9 %3 / 7
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 / 6275.0 %12 / 16
EuclideanDissimilarityMatrix.cpp +
83.3%83.3%
+
83.3 %50 / 6081.8 %9 / 11
Average.cpp +
84.8%84.8%
+
84.8 %28 / 3369.2 %9 / 13
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.9%94.9%
+
94.9 %74 / 7890.9 %10 / 11
PrintDissimilarityMatrix.cpp +
95.7%95.7%
+
95.7 %22 / 2375.0 %6 / 8
OutputPDBFile.cpp +
96.7%96.7%
+
96.7 %29 / 3075.0 %6 / 8
AnalysisBase.cpp +
96.9%96.9%
+
96.9 %31 / 3283.3 %5 / 6
Histogram.cpp +
97.6%97.6%
+
97.6 %203 / 20887.5 %14 / 16
OutputColvarFile.cpp +
97.9%97.9%
+
97.9 %47 / 4875.0 %6 / 8
AverageVessel.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
SelectWithStride.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
ReselectLandmarks.cpp +
100.0%
+
100.0 %17 / 1785.7 %6 / 7
DataCollectionObject.cpp +
100.0%
+
100.0 %21 / 21100.0 %4 / 4
WhamWeights.cpp +
100.0%
+
100.0 %23 / 2383.3 %5 / 6
FarthestPointSampling.cpp +
100.0%
+
100.0 %26 / 2685.7 %6 / 7
WhamHistogram.cpp +
100.0%
+
100.0 %30 / 3083.3 %5 / 6
LandmarkSelectionBase.cpp +
100.0%
+
100.0 %41 / 4183.3 %5 / 6
Committor.cpp +
100.0%
+
100.0 %74 / 7487.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/analysis/index.html b/coverage/analysis/index.html new file mode 100644 index 0000000000..413af90719 --- /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:85997188.5 %
Date:2024-06-10 08:19:14Functions:15620277.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
84.8%84.8%
+
84.8 %28 / 3369.2 %9 / 13
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 %74 / 7487.5 %7 / 8
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.3%83.3%
+
83.3 %50 / 6081.8 %9 / 11
FarthestPointSampling.cpp +
100.0%
+
100.0 %26 / 2685.7 %6 / 7
Histogram.cpp +
97.6%97.6%
+
97.6 %203 / 20887.5 %14 / 16
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 +
12.8%12.8%
+
12.8 %6 / 4742.9 %3 / 7
OutputColvarFile.cpp +
97.9%97.9%
+
97.9 %47 / 4875.0 %6 / 8
OutputPDBFile.cpp +
96.7%96.7%
+
96.7 %29 / 3075.0 %6 / 8
PrintDissimilarityMatrix.cpp +
95.7%95.7%
+
95.7 %22 / 2375.0 %6 / 8
ReadAnalysisFrames.cpp +
94.9%94.9%
+
94.9 %74 / 7890.9 %10 / 11
ReadAnalysisFrames.h +
69.2%69.2%
+
69.2 %9 / 1357.1 %4 / 7
ReadDissimilarityMatrix.cpp +
82.3%82.3%
+
82.3 %51 / 6275.0 %12 / 16
ReselectLandmarks.cpp +
100.0%
+
100.0 %17 / 1785.7 %6 / 7
SelectRandomFrames.cpp +
25.0%25.0%
+
25.0 %5 / 2042.9 %3 / 7
SelectWithStride.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
WhamHistogram.cpp +
100.0%
+
100.0 %30 / 3083.3 %5 / 6
WhamWeights.cpp +
100.0%
+
100.0 %23 / 2383.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bfbc199652 --- /dev/null +++ b/coverage/annfunc/ANN.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:13413897.1 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7annfunc3ANNC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe1106createERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc3ANNC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc3ANN16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function7annfunc3ANN30calculate_output_of_each_layerERKSt6vectorIdSaIdEE1638
_ZN4PLMD8function7annfunc3ANN9calculateEv1638
_ZN4PLMD8function7annfunc3ANN9back_propERSt6vectorIS3_IdSaIdEESaIS5_EEi2184
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe110C2Ev3473
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe110D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/annfunc/ANN.cpp.func.html b/coverage/annfunc/ANN.cpp.func.html new file mode 100644 index 0000000000..56058542b8 --- /dev/null +++ b/coverage/annfunc/ANN.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:13413897.1 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe1106createERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe110C2Ev3473
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe110D2Ev3473
_ZN4PLMD8function7annfunc3ANN16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function7annfunc3ANN30calculate_output_of_each_layerERKSt6vectorIdSaIdEE1638
_ZN4PLMD8function7annfunc3ANN9back_propERSt6vectorIS3_IdSaIdEESaIS5_EEi2184
_ZN4PLMD8function7annfunc3ANN9calculateEv1638
_ZN4PLMD8function7annfunc3ANNC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc3ANNC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/annfunc/ANN.cpp.gcov.html b/coverage/annfunc/ANN.cpp.gcov.html new file mode 100644 index 0000000000..49752267c6 --- /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:13413897.1 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ + + + + + + + +

+
          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 "function/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       10429 : PLUMED_REGISTER_ACTION(ANN,"ANN")
+     111             : 
+     112           6 : void ANN::registerKeywords( Keywords& keys ) {
+     113           6 :   Function::registerKeywords(keys);
+     114          12 :   keys.use("ARG"); keys.use("PERIODIC");
+     115          12 :   keys.add("compulsory", "NUM_LAYERS", "number of layers of the neural network");
+     116          12 :   keys.add("compulsory", "NUM_NODES", "numbers of nodes in each layer of the neural network");
+     117          12 :   keys.add("compulsory", "ACTIVATIONS", "activation functions for the neural network");
+     118          12 :   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          12 :   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          12 :   keys.addOutputComponent("node", "default", "components of ANN outputs");
+     125           6 : }
+     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 (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.15
+
+ + + diff --git a/coverage/annfunc/index-sort-f.html b/coverage/annfunc/index-sort-f.html new file mode 100644 index 0000000000..2297e2959d --- /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:13413897.1 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ANN.cpp +
97.1%97.1%
+
97.1 %134 / 13888.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/annfunc/index-sort-l.html b/coverage/annfunc/index-sort-l.html new file mode 100644 index 0000000000..d108d424a7 --- /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:13413897.1 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ANN.cpp +
97.1%97.1%
+
97.1 %134 / 13888.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/annfunc/index.html b/coverage/annfunc/index.html new file mode 100644 index 0000000000..2aae6b9aff --- /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:13413897.1 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ANN.cpp +
97.1%97.1%
+
97.1 %134 / 13888.9 %8 / 9
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..d56c09ce5c --- /dev/null +++ b/coverage/bias/ABMD.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:6161100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4ABMDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe956createERKNS_13ActionOptionsE1
_ZN4PLMD4bias4ABMDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias4ABMD16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4bias4ABMD9calculateEv5
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe95C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe95D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ABMD.cpp.func.html b/coverage/bias/ABMD.cpp.func.html new file mode 100644 index 0000000000..8ae4a24b5e --- /dev/null +++ b/coverage/bias/ABMD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:6161100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe956createERKNS_13ActionOptionsE1
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe95C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe95D2Ev3473
_ZN4PLMD4bias4ABMD16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4bias4ABMD9calculateEv5
_ZN4PLMD4bias4ABMDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias4ABMDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ABMD.cpp.gcov.html b/coverage/bias/ABMD.cpp.gcov.html new file mode 100644 index 0000000000..0a6446bd28 --- /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:6161100.0 %
Date:2024-06-10 08:19:14Functions: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 "Bias.h"
+      23             : #include "tools/Random.h"
+      24             : #include "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       10421 : PLUMED_REGISTER_ACTION(ABMD,"ABMD")
+      96             : 
+      97           2 : void ABMD::registerKeywords(Keywords& keys) {
+      98           2 :   Bias::registerKeywords(keys);
+      99           2 :   keys.use("ARG");
+     100           4 :   keys.add("compulsory","TO","The array of target values");
+     101           4 :   keys.add("compulsory","KAPPA","The array of force constants.");
+     102           4 :   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           4 :   keys.add("optional","NOISE","Array of white noise intensities (add a temperature to the ABMD)");
+     104           4 :   keys.add("optional","SEED","Array of seeds for the white noise (add a temperature to the ABMD)");
+     105           4 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     106           4 :   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           2 : }
+     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           1 :     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             :       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             :   setBias(ene);
+     180           5 :   getPntrToComponent("force2")->set(totf2);
+     181           5 : }
+     182             : 
+     183             : }
+     184             : }
+     185             : 
+     186             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..56536a13c7 --- /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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE677
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE703
_ZN4PLMD4bias4Bias5applyEv78568
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/Bias.cpp.func.html b/coverage/bias/Bias.cpp.func.html new file mode 100644 index 0000000000..2d199d3f42 --- /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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE703
_ZN4PLMD4bias4Bias5applyEv78568
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE677
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/Bias.cpp.gcov.html b/coverage/bias/Bias.cpp.gcov.html new file mode 100644 index 0000000000..c46420c5f6 --- /dev/null +++ b/coverage/bias/Bias.cpp.gcov.html @@ -0,0 +1,171 @@ + + + + + + + + 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-06-10 08:19:14Functions: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         677 : Bias::Bias(const ActionOptions&ao):
+      29             :   Action(ao),
+      30             :   ActionPilot(ao),
+      31             :   ActionWithValue(ao),
+      32             :   ActionWithArguments(ao),
+      33         677 :   outputForces(getNumberOfArguments(),0.0)
+      34             : {
+      35         674 :   addComponentWithDerivatives("bias");
+      36         674 :   componentIsNotPeriodic("bias");
+      37         674 :   valueBias=getPntrToComponent("bias");
+      38             : 
+      39         674 :   if(getStride()>1) {
+      40           3 :     log<<"  multiple time step "<<getStride()<<" ";
+      41           9 :     log<<cite("Ferrarotti, Bottaro, Perez-Villa, and Bussi, J. Chem. Theory Comput. 11, 139 (2015)")<<"\n";
+      42             :   }
+      43        4478 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      44        3804 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+      45             :   }
+      46             : 
+      47         674 :   ActionWithValue::turnOnDerivatives();
+      48         677 : }
+      49             : 
+      50         703 : void Bias::registerKeywords( Keywords& keys ) {
+      51         703 :   Action::registerKeywords(keys);
+      52         703 :   ActionPilot::registerKeywords(keys);
+      53         703 :   ActionWithValue::registerKeywords(keys);
+      54         703 :   ActionWithArguments::registerKeywords(keys);
+      55        1406 :   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         703 :   componentsAreNotOptional(keys);
+      57        1406 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      58         703 : }
+      59             : 
+      60       78568 : void Bias::apply() {
+      61       78568 :   const unsigned noa=getNumberOfArguments();
+      62       78568 :   const unsigned ncp=getNumberOfComponents();
+      63             : 
+      64       78568 :   if(onStep()) {
+      65       78568 :     double gstr = static_cast<double>(getStride());
+      66      224452 :     for(unsigned i=0; i<noa; ++i) {
+      67      145884 :       getPntrToArgument(i)->addForce(gstr*outputForces[i]);
+      68             :     }
+      69             :   }
+      70             : 
+      71             :   // additional forces on the bias component
+      72       78568 :   std::vector<double> f(noa,0.0);
+      73       78568 :   std::vector<double> forces(noa);
+      74             : 
+      75             :   bool at_least_one_forced=false;
+      76      398265 :   for(unsigned i=0; i<ncp; ++i) {
+      77      319697 :     if(getPntrToComponent(i)->applyForce(forces)) {
+      78             :       at_least_one_forced=true;
+      79         913 :       for(unsigned j=0; j<noa; j++) f[j]+=forces[j];
+      80             :     }
+      81             :   }
+      82             : 
+      83       78568 :   if(at_least_one_forced && !onStep()) error("you are biasing a bias with an inconsistent STRIDE");
+      84             : 
+      85       79409 :   if(at_least_one_forced) for(unsigned i=0; i<noa; ++i) {
+      86         559 :       getPntrToArgument(i)->addForce(f[i]);
+      87             :     }
+      88             : 
+      89       78568 : }
+      90             : 
+      91             : }
+      92             : }
+      93             : 
+      94             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..76dd347d63 --- /dev/null +++ b/coverage/bias/Bias.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + 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:66100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv790
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/Bias.h.func.html b/coverage/bias/Bias.h.func.html new file mode 100644 index 0000000000..eb37fbda56 --- /dev/null +++ b/coverage/bias/Bias.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + 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:66100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv790
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/Bias.h.gcov.html b/coverage/bias/Bias.h.gcov.html new file mode 100644 index 0000000000..b745d2b5e0 --- /dev/null +++ b/coverage/bias/Bias.h.gcov.html @@ -0,0 +1,158 @@ + + + + + + + + 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:66100.0 %
Date:2024-06-10 08:19:14Functions: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             : #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             : protected:
+      50             : /// set the force from the bias on argument i, this automatically set the partial derivative of the bias with respect to i to -f
+      51             :   void setOutputForce(int i,double f);
+      52             : /// set the value of the bias
+      53             :   void setBias(double bias);
+      54             : public:
+      55             :   static void registerKeywords(Keywords&);
+      56             :   explicit Bias(const ActionOptions&ao);
+      57             :   void apply() override;
+      58             :   unsigned getNumberOfDerivatives() override;
+      59             : };
+      60             : 
+      61             : inline
+      62             : void Bias::setOutputForce(int i,double f) {
+      63      141261 :   outputForces[i]=f;
+      64      142327 :   valueBias->addDerivative(i,-f);
+      65             : }
+      66             : 
+      67             : inline
+      68             : void Bias::setBias(double bias) {
+      69       78315 :   valueBias->set(bias);
+      70       38413 : }
+      71             : 
+      72             : inline
+      73         790 : unsigned Bias::getNumberOfDerivatives() {
+      74         790 :   return getNumberOfArguments();
+      75             : }
+      76             : 
+      77             : }
+      78             : }
+      79             : 
+      80             : #endif
+      81             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..c53e605b1e --- /dev/null +++ b/coverage/bias/BiasValue.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9BiasValueC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe826createERKNS_13ActionOptionsE32
_ZN4PLMD4bias9BiasValueC1ERKNS_13ActionOptionsE32
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD4bias9BiasValue9calculateEv472
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe82C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe82D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.func.html b/coverage/bias/BiasValue.cpp.func.html new file mode 100644 index 0000000000..471f3fd5d0 --- /dev/null +++ b/coverage/bias/BiasValue.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe826createERKNS_13ActionOptionsE32
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe82C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe82D2Ev3473
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD4bias9BiasValue9calculateEv472
_ZN4PLMD4bias9BiasValueC1ERKNS_13ActionOptionsE32
_ZN4PLMD4bias9BiasValueC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.gcov.html b/coverage/bias/BiasValue.cpp.gcov.html new file mode 100644 index 0000000000..db6de18adf --- /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-06-10 08:19:14Functions: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 "Bias.h"
+      23             : #include "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       10483 : PLUMED_REGISTER_ACTION(BiasValue,"BIASVALUE")
+      83             : 
+      84          33 : void BiasValue::registerKeywords(Keywords& keys) {
+      85          33 :   Bias::registerKeywords(keys);
+      86          33 :   keys.use("ARG");
+      87             :   // Should be _bias below
+      88          66 :   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          33 : }
+      93             : 
+      94          32 : BiasValue::BiasValue(const ActionOptions&ao):
+      95          32 :   PLUMED_BIAS_INIT(ao)
+      96             : {
+      97          32 :   checkRead();
+      98             :   // add one bias for each argument
+      99          65 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     100          33 :     std::string ss=getPntrToArgument(i)->getName()+"_bias";
+     101          33 :     addComponent(ss); componentIsNotPeriodic(ss);
+     102             :   }
+     103          32 : }
+     104             : 
+     105         472 : void BiasValue::calculate() {
+     106             :   double bias=0.0;
+     107         950 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     108             :     double val; val=getArgument(i);
+     109         478 :     getPntrToComponent(i+1)->set(val);
+     110         478 :     setOutputForce(i,-1.);
+     111         478 :     bias+=val;
+     112             :   }
+     113             :   setBias(bias);
+     114         472 : }
+     115             : 
+     116             : }
+     117             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..40bb022c59 --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:939498.9 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias18ExtendedLagrangianC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_131ExtendedLagrangianRegisterMe1296createERKNS_13ActionOptionsE2
_ZN4PLMD4bias18ExtendedLagrangianC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias18ExtendedLagrangian16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias18ExtendedLagrangian6updateEv24
_ZN4PLMD4bias18ExtendedLagrangian9calculateEv24
_ZN4PLMD4bias12_GLOBAL__N_131ExtendedLagrangianRegisterMe129C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_131ExtendedLagrangianRegisterMe129D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ExtendedLagrangian.cpp.func.html b/coverage/bias/ExtendedLagrangian.cpp.func.html new file mode 100644 index 0000000000..e1dbf84f74 --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:939498.9 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias8ExternalC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe1216createERKNS_13ActionOptionsE2
_ZN4PLMD4bias8ExternalC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias8External16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias8External9calculateEv5
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe121C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe121D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/External.cpp.func.html b/coverage/bias/External.cpp.func.html new file mode 100644 index 0000000000..6707982a14 --- /dev/null +++ b/coverage/bias/External.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe1216createERKNS_13ActionOptionsE2
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe121C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe121D2Ev3473
_ZN4PLMD4bias8External16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias8External9calculateEv5
_ZN4PLMD4bias8ExternalC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias8ExternalC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/External.cpp.gcov.html b/coverage/bias/External.cpp.gcov.html new file mode 100644 index 0000000000..d3e8579651 --- /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-06-10 08:19:14Functions: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 "Bias.h"
+      23             : #include "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       10422 : PLUMED_REGISTER_ACTION(External,"EXTERNAL")
+     122             : 
+     123           3 : void External::registerKeywords(Keywords& keys) {
+     124           3 :   Bias::registerKeywords(keys);
+     125           3 :   keys.use("ARG");
+     126           6 :   keys.add("compulsory","FILE","the name of the file containing the external potential.");
+     127           6 :   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           6 :   keys.addFlag("SPARSE",false,"specifies that the external potential uses a sparse grid");
+     129           6 :   keys.add("compulsory","SCALE","1.0","a factor that multiplies the external potential, useful to invert free energies");
+     130           3 : }
+     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             :   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.15
+
+ + + 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 0000000000..7e1d43e651 --- /dev/null +++ b/coverage/bias/LWalls.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:5555100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6LWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe766createERKNS_13ActionOptionsE1
_ZN4PLMD4bias6LWallsC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias6LWalls16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4bias6LWalls9calculateEv5
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe76C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe76D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/LWalls.cpp.func.html b/coverage/bias/LWalls.cpp.func.html new file mode 100644 index 0000000000..f4150e9831 --- /dev/null +++ b/coverage/bias/LWalls.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:5555100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe766createERKNS_13ActionOptionsE1
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe76C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe76D2Ev3473
_ZN4PLMD4bias6LWalls16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4bias6LWalls9calculateEv5
_ZN4PLMD4bias6LWallsC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias6LWallsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/LWalls.cpp.gcov.html b/coverage/bias/LWalls.cpp.gcov.html new file mode 100644 index 0000000000..2e1023fca7 --- /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:5555100.0 %
Date:2024-06-10 08:19:14Functions: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 "Bias.h"
+      23             : #include "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       10421 : PLUMED_REGISTER_ACTION(LWalls,"LOWER_WALLS")
+      77             : 
+      78           2 : void LWalls::registerKeywords(Keywords& keys) {
+      79           2 :   Bias::registerKeywords(keys);
+      80           2 :   keys.use("ARG");
+      81           4 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      82           4 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      83           4 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      84           4 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      85           4 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      86           4 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      87           2 : }
+      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             :     setOutputForce(i,f);
+     142             :   }
+     143             :   setBias(ene);
+     144           5 :   getPntrToComponent("force2")->set(totf2);
+     145           5 : }
+     146             : 
+     147             : }
+     148             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..41f81b245d --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + 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:22723696.2 %
Date:2024-06-10 08:19:14Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6MaxEntC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias6MaxEnt15ReadLagrangiansERNS_5IFileE37
_ZN4PLMD4bias12_GLOBAL__N_119MaxEntRegisterMe1616createERKNS_13ActionOptionsE50
_ZN4PLMD4bias6MaxEntC1ERKNS_13ActionOptionsE50
_ZN4PLMD4bias6MaxEnt16registerKeywordsERNS_8KeywordsE51
_ZN4PLMD4bias6MaxEnt13update_lambdaEv550
_ZN4PLMD4bias6MaxEnt16WriteLagrangiansERSt6vectorIdSaIdEERNS_5OFileE550
_ZN4PLMD4bias12_GLOBAL__N_119MaxEntRegisterMe161C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_119MaxEntRegisterMe161D2Ev3473
_ZN4PLMD4bias6MaxEnt6updateEv5050
_ZN4PLMD4bias6MaxEnt9calculateEv5050
_ZN4PLMD4bias6MaxEnt13compute_errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd5302
_ZN4PLMD4bias6MaxEnt23check_lambda_boundariesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd5302
_ZN4PLMD4bias6MaxEnt14convert_lambdaERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd119118
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/MaxEnt.cpp.func.html b/coverage/bias/MaxEnt.cpp.func.html new file mode 100644 index 0000000000..ca54246e1c --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + 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:22723696.2 %
Date:2024-06-10 08:19:14Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias5MetaD24getGaussianNormalizationERKNS1_8GaussianE0
_ZN4PLMD4bias5MetaDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias5MetaD17logTemperingSpecsERKNS1_14TemperingSpecsE3
_ZN4PLMD4bias5MetaD11updateNlistEv4
_ZN4PLMD4bias5MetaD16noStretchWarningEv12
_ZN4PLMD4bias5MetaD12temperHeightERdRKNS1_14TemperingSpecsEd60
_ZN4PLMD4bias5MetaD24computeReweightingFactorEv102
_ZN4PLMD4bias5MetaD18readTemperingSpecsERNS1_14TemperingSpecsE149
_ZN4PLMD4bias5MetaD14TemperingSpecsC2EbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ddd154
_ZN4PLMD4bias5MetaD29updateFrequencyAdaptiveStrideEv154
_ZN4PLMD4bias12_GLOBAL__N_118MetaDRegisterMe5226createERKNS_13ActionOptionsE155
_ZN4PLMD4bias5MetaDC1ERKNS_13ActionOptionsE155
_ZN4PLMD4bias5MetaD16registerKeywordsERNS_8KeywordsE156
_ZN4PLMD4bias5MetaD25registerTemperingKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RNS_8KeywordsE156
_ZN4PLMD4bias5MetaD16evaluateGaussianERKSt6vectorIdSaIdEERKNS1_8GaussianE192
_ZN4PLMD4bias5MetaD24getTransitionBarrierBiasEv273
_ZN4PLMD4bias5MetaD7getBiasERKSt6vectorIdSaIdEE281
_ZN4PLMD4bias5MetaD18getGaussianSupportERKNS1_8GaussianE636
_ZN4PLMD4bias5MetaD9getHeightERKSt6vectorIdSaIdEE2732
_ZN4PLMD4bias5MetaD13writeGaussianERKNS1_8GaussianERNS_5OFileE2918
_ZN4PLMD4bias12_GLOBAL__N_118MetaDRegisterMe522C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_118MetaDRegisterMe522D2Ev3473
_ZN4PLMD4bias5MetaD11addGaussianERKNS1_8GaussianE5057
_ZN4PLMD4bias5MetaD8GaussianC2EbdRKSt6vectorIdSaIdEES7_5057
_ZN4PLMD4bias5MetaD13readGaussiansEPNS_5IFileE6037
_ZN4PLMD4bias5MetaD6updateEv6234
_ZN4PLMD4bias5MetaD11scanOneHillEPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb8014
_ZN4PLMD4bias5MetaD21getBiasAndDerivativesERKSt6vectorIdSaIdEERS4_8390
_ZN4PLMD4bias5MetaD9calculateEv8430
_ZNK4PLMD4bias5MetaD19checkNeedsGradientsEv8430
_ZN4PLMD4bias5MetaD30evaluateGaussianAndDerivativesERKSt6vectorIdSaIdEERKNS1_8GaussianERS4_SA_2409143
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/MetaD.cpp.func.html b/coverage/bias/MetaD.cpp.func.html new file mode 100644 index 0000000000..d926a80a0d --- /dev/null +++ b/coverage/bias/MetaD.cpp.func.html @@ -0,0 +1,197 @@ + + + + + + + + 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:951107988.1 %
Date:2024-06-10 08:19:14Functions:293193.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias15MovingRestraintC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe1176createERKNS_13ActionOptionsE4
_ZN4PLMD4bias15MovingRestraintC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias15MovingRestraint16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4bias15MovingRestraint9calculateEv566
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe117C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe117D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/MovingRestraint.cpp.func.html b/coverage/bias/MovingRestraint.cpp.func.html new file mode 100644 index 0000000000..8117a1da97 --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe1176createERKNS_13ActionOptionsE4
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe117C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe117D2Ev3473
_ZN4PLMD4bias15MovingRestraint16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4bias15MovingRestraint9calculateEv566
_ZN4PLMD4bias15MovingRestraintC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias15MovingRestraintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/MovingRestraint.cpp.gcov.html b/coverage/bias/MovingRestraint.cpp.gcov.html new file mode 100644 index 0000000000..c1c4d79d60 --- /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-06-10 08:19:14Functions: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 "Bias.h"
+      23             : #include "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 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       10427 : PLUMED_REGISTER_ACTION(MovingRestraint,"MOVINGRESTRAINT")
+     118             : 
+     119           5 : void MovingRestraint::registerKeywords( Keywords& keys ) {
+     120           5 :   Bias::registerKeywords(keys);
+     121           5 :   keys.use("ARG");
+     122          10 :   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          10 :   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          10 :   keys.reset_style("STEP","compulsory");
+     127          10 :   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          10 :   keys.reset_style("AT","compulsory");
+     131          10 :   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          10 :   keys.reset_style("KAPPA","compulsory");
+     135          10 :   keys.addOutputComponent("work","default","the total work performed changing this restraint");
+     136          10 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     137          10 :   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          10 :   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          10 :   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           5 : }
+     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 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 %ld\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           5 :     comp=getPntrToArgument(i)->getName()+"_cntr"; // each spring has its own center
+     192           5 :     addComponent(comp); componentIsNotPeriodic(comp);
+     193           5 :     comp=getPntrToArgument(i)->getName()+"_work"; // each spring has its own work
+     194           5 :     addComponent(comp); componentIsNotPeriodic(comp);
+     195           5 :     comp=getPntrToArgument(i)->getName()+"_kappa"; // each spring has its own kappa
+     196           5 :     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          12 :   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 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(); 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             :   setBias(ene);
+     260        1132 :   getPntrToComponent("force2")->set(totf2);
+     261         566 : }
+     262             : 
+     263             : }
+     264             : }
+     265             : 
+     266             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..0cf7797810 --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.func-sort-c.html @@ -0,0 +1,145 @@ + + + + + + + + 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:52860088.0 %
Date:2024-06-10 08:19:14Functions:161888.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias7PBMetaD16noStretchWarningEv0
_ZN4PLMD4bias7PBMetaDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias7PBMetaD13readGaussiansEjPNS_5IFileE2
_ZN4PLMD4bias7PBMetaD11scanOneHillEjPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb10
_ZN4PLMD4bias12_GLOBAL__N_120PBMetaDRegisterMe3036createERKNS_13ActionOptionsE38
_ZN4PLMD4bias7PBMetaDC1ERKNS_13ActionOptionsE38
_ZN4PLMD4bias7PBMetaD16registerKeywordsERNS_8KeywordsE39
_ZN4PLMD4bias7PBMetaD18getGaussianSupportEjRKNS1_8GaussianE160
_ZN4PLMD4bias7PBMetaD6updateEv320
_ZN4PLMD4bias7PBMetaD9calculateEv320
_ZNK4PLMD4bias7PBMetaD19checkNeedsGradientsEv320
_ZN4PLMD4bias7PBMetaD13writeGaussianEjRKNS1_8GaussianEPNS_5OFileE1064
_ZN4PLMD4bias7PBMetaD11addGaussianEjRKNS1_8GaussianE1072
_ZN4PLMD4bias7PBMetaD8GaussianC2ERKSt6vectorIdSaIdEES7_db1072
_ZN4PLMD4bias7PBMetaD21getBiasAndDerivativesEjRKSt6vectorIdSaIdEEPd1188
_ZN4PLMD4bias12_GLOBAL__N_120PBMetaDRegisterMe303C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_120PBMetaDRegisterMe303D2Ev3473
_ZN4PLMD4bias7PBMetaD16evaluateGaussianEjRKSt6vectorIdSaIdEERKNS1_8GaussianEPd7776
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/PBMetaD.cpp.func.html b/coverage/bias/PBMetaD.cpp.func.html new file mode 100644 index 0000000000..c81c4f883b --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.func.html @@ -0,0 +1,145 @@ + + + + + + + + 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:52860088.0 %
Date:2024-06-10 08:19:14Functions:161888.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9RestraintC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe706createERKNS_13ActionOptionsE178
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE178
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE179
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe70C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe70D2Ev3473
_ZN4PLMD4bias9Restraint9calculateEv4670
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/Restraint.cpp.func.html b/coverage/bias/Restraint.cpp.func.html new file mode 100644 index 0000000000..126291dfba --- /dev/null +++ b/coverage/bias/Restraint.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4040100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe706createERKNS_13ActionOptionsE178
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe70C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe70D2Ev3473
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE179
_ZN4PLMD4bias9Restraint9calculateEv4670
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE178
_ZN4PLMD4bias9RestraintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/Restraint.cpp.gcov.html b/coverage/bias/Restraint.cpp.gcov.html new file mode 100644 index 0000000000..d7852a8d6d --- /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:4040100.0 %
Date:2024-06-10 08:19:14Functions: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 "Bias.h"
+      23             : #include "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       10772 : PLUMED_REGISTER_ACTION(Restraint,"RESTRAINT")
+      71             : 
+      72         179 : void Restraint::registerKeywords(Keywords& keys) {
+      73         179 :   Bias::registerKeywords(keys);
+      74         179 :   keys.use("ARG");
+      75         358 :   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         358 :   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         358 :   keys.add("compulsory","AT","the position of the restraint");
+      78         358 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      79         179 : }
+      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         175 :   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        4937 :     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             :     setOutputForce(i,f);
+     118        4937 :     totf2+=f*f;
+     119             :   }
+     120             :   setBias(ene);
+     121        4670 :   valueForce2->set(totf2);
+     122        4670 : }
+     123             : 
+     124             : }
+     125             : 
+     126             : 
+     127             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..2c2ff4929d --- /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:192095.0 %
Date:2024-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBaseC2ERKNS_13ActionOptionsE20
_ZN4PLMD4bias12ReweightBase16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD4bias12ReweightBase9calculateEv6232
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.func.html b/coverage/bias/ReweightBase.cpp.func.html new file mode 100644 index 0000000000..10005fe783 --- /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:192095.0 %
Date:2024-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD4bias12ReweightBase9calculateEv6232
_ZN4PLMD4bias12ReweightBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBaseC2ERKNS_13ActionOptionsE20
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.gcov.html b/coverage/bias/ReweightBase.cpp.gcov.html new file mode 100644 index 0000000000..e1b881a7a3 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.gcov.html @@ -0,0 +1,134 @@ + + + + + + + + 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:192095.0 %
Date:2024-06-10 08:19:14Functions: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/PlumedMain.h"
+      24             : #include "core/Atoms.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace bias {
+      28             : 
+      29          24 : void ReweightBase::registerKeywords(Keywords& keys) {
+      30          24 :   Action::registerKeywords( keys );
+      31          24 :   ActionWithValue::registerKeywords( keys );
+      32          24 :   ActionWithArguments::registerKeywords( keys );
+      33          24 :   keys.setComponentsIntroduction("This action calculates the logarithm of a weight for reweighting");
+      34          48 :   keys.add("optional","TEMP","the system temperature.  This is not required if your MD code passes this quantity to PLUMED");
+      35          24 :   keys.remove("NUMERICAL_DERIVATIVES");
+      36          24 : }
+      37             : 
+      38          20 : ReweightBase::ReweightBase(const ActionOptions&ao):
+      39             :   Action(ao),
+      40             :   ActionWithValue(ao),
+      41          20 :   ActionWithArguments(ao)
+      42             : {
+      43          20 :   simtemp=0.; parse("TEMP",simtemp);
+      44          20 :   if(simtemp>0) simtemp*=plumed.getAtoms().getKBoltzmann();
+      45           0 :   else simtemp=plumed.getAtoms().getKbT();
+      46          20 :   if(simtemp==0) error("The MD engine does not pass the temperature to plumed so you have to specify it using TEMP");
+      47             :   // Create something to hold the weight
+      48          20 :   addValue(); setNotPeriodic();
+      49          20 : }
+      50             : 
+      51        6232 : void ReweightBase::calculate() {
+      52        6232 :   double weight = getLogWeight();
+      53        6232 :   setValue( weight );
+      54        6232 : }
+      55             : 
+      56             : }
+      57             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bc7bac6049 --- /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-06-10 08:19:14Functions:2633.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16calculateWeightsERKj0
_ZN4PLMD4bias12ReweightBase22getNumberOfDerivativesEv0
_ZN4PLMD4bias12ReweightBase9clearDataEv0
_ZNK4PLMD4bias12ReweightBase9getWeightERKj0
_ZNK4PLMD4bias12ReweightBase17buildsWeightStoreEv7
_ZN4PLMD4bias12ReweightBase5applyEv6232
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightBase.h.func.html b/coverage/bias/ReweightBase.h.func.html new file mode 100644 index 0000000000..73dcff50ee --- /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-06-10 08:19:14Functions:2633.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16calculateWeightsERKj0
_ZN4PLMD4bias12ReweightBase22getNumberOfDerivativesEv0
_ZN4PLMD4bias12ReweightBase5applyEv6232
_ZN4PLMD4bias12ReweightBase9clearDataEv0
_ZNK4PLMD4bias12ReweightBase17buildsWeightStoreEv7
_ZNK4PLMD4bias12ReweightBase9getWeightERKj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightBase.h.gcov.html b/coverage/bias/ReweightBase.h.gcov.html new file mode 100644 index 0000000000..0091aa572d --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..577e60f94e --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBiasC1ERKNS_13ActionOptionsE3
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe786createERKNS_13ActionOptionsE3
_ZN4PLMD4bias12ReweightBias16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias12ReweightBias12getLogWeightEv1007
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe78C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe78D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightBias.cpp.func.html b/coverage/bias/ReweightBias.cpp.func.html new file mode 100644 index 0000000000..cfb7d6d3bc --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBias12getLogWeightEv1007
_ZN4PLMD4bias12ReweightBias16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias12ReweightBiasC1ERKNS_13ActionOptionsE3
_ZN4PLMD4bias12ReweightBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe786createERKNS_13ActionOptionsE3
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe78C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe78D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightBias.cpp.gcov.html b/coverage/bias/ReweightBias.cpp.gcov.html new file mode 100644 index 0000000000..7a4dd58e85 --- /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:1111100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10425 : PLUMED_REGISTER_ACTION(ReweightBias,"REWEIGHT_BIAS")
+      79             : 
+      80           4 : void ReweightBias::registerKeywords(Keywords& keys ) {
+      81           4 :   ReweightBase::registerKeywords( keys ); keys.remove("ARG");
+      82           8 :   keys.add("compulsory","ARG","*.bias","the biases that must be taken into account when reweighting");
+      83           4 : }
+      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.15
+
+ + + 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 0000000000..93e5d2f3a5 --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias13ReweightMetadC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe756createERKNS_13ActionOptionsE1
_ZN4PLMD4bias13ReweightMetadC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias13ReweightMetad12getLogWeightEv2
_ZN4PLMD4bias13ReweightMetad16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe75C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe75D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightMetad.cpp.func.html b/coverage/bias/ReweightMetad.cpp.func.html new file mode 100644 index 0000000000..0adc4ce748 --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe756createERKNS_13ActionOptionsE1
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe75C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe75D2Ev3473
_ZN4PLMD4bias13ReweightMetad12getLogWeightEv2
_ZN4PLMD4bias13ReweightMetad16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4bias13ReweightMetadC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias13ReweightMetadC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightMetad.cpp.gcov.html b/coverage/bias/ReweightMetad.cpp.gcov.html new file mode 100644 index 0000000000..c41da096ca --- /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:1111100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(ReweightMetad,"REWEIGHT_METAD")
+      76             : 
+      77           2 : void ReweightMetad::registerKeywords(Keywords& keys ) {
+      78           2 :   ReweightBase::registerKeywords( keys ); keys.remove("ARG");
+      79           4 :   keys.add("compulsory","ARG","*.rbias","the biases that must be taken into account when reweighting");
+      80           2 : }
+      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.15
+
+ + + 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 0000000000..211960483e --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:464797.9 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias27ReweightTemperaturePressureC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe1906createERKNS_13ActionOptionsE4
_ZN4PLMD4bias27ReweightTemperaturePressureC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias27ReweightTemperaturePressure16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4bias27ReweightTemperaturePressure12getLogWeightEv1001
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe190C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe190D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightTemperaturePressure.cpp.func.html b/coverage/bias/ReweightTemperaturePressure.cpp.func.html new file mode 100644 index 0000000000..c99c74bea5 --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:464797.9 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe1906createERKNS_13ActionOptionsE4
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe190C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe190D2Ev3473
_ZN4PLMD4bias27ReweightTemperaturePressure12getLogWeightEv1001
_ZN4PLMD4bias27ReweightTemperaturePressure16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4bias27ReweightTemperaturePressureC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias27ReweightTemperaturePressureC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightTemperaturePressure.cpp.gcov.html b/coverage/bias/ReweightTemperaturePressure.cpp.gcov.html new file mode 100644 index 0000000000..fd36020edc --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.gcov.html @@ -0,0 +1,343 @@ + + + + + + + + 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:464797.9 %
Date:2024-06-10 08:19:14Functions:6785.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 "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/Atoms.h"
+      25             : #include "ReweightBase.h"
+      26             : 
+      27             : //+PLUMEDOC REWEIGHTING REWEIGHT_TEMP_PRESS
+      28             : /*
+      29             : Calculate weights for ensemble averages at temperatures and/or pressures different than those used in your original simulation.
+      30             : 
+      31             : 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
+      32             : contained in trajectories and obtain ensemble averages at different temperatures and/or pressures.
+      33             : 
+      34             : 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$.
+      35             : This observable is in practice any collective variable (CV) calculated by Plumed.
+      36             : 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:
+      37             : \f[
+      38             : \langle O(\mathbf{R},\mathcal{V}) \rangle_{\xi'} = \frac{\langle O(\mathbf{R},\mathcal{V}) w(\mathbf{R},\mathcal{V}) \rangle_{\xi}}
+      39             :                                                      {\langle w(\mathbf{R},\mathcal{V}) \rangle_{\xi}}
+      40             : \f]
+      41             : 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$.
+      42             : This action calculates the weights  \f$ w (\mathbf{R},\mathcal{V}) \f$ and handles 4 different cases:
+      43             :   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.
+      44             :   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$.
+      45             :   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$.
+      46             :   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$.
+      47             : 
+      48             : These weights can be used in any action that computes ensemble averages.
+      49             : For example this action can be used in tandem with \ref HISTOGRAM or \ref AVERAGE.
+      50             : 
+      51             : 
+      52             : 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.
+      53             : For this reason an unbiased simulation is of little use to reweight at different temperatures and/or pressures.
+      54             : A successful approach has been altering the probability of observing a configuration in order to increase this overlap \cite wanglandau.
+      55             : 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).
+      56             : In order to calculate ensemble averages, also the effect of this bias must be taken into account.
+      57             : 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:
+      58             : \f[
+      59             : \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}}
+      60             :                                                      {\langle w (\mathbf{R},\mathcal{V})  e^{\beta V(\mathbf{s})}  \rangle_{\xi,V}}
+      61             : \f]
+      62             : where \f$\langle \cdot \rangle_{\xi,V}\f$ is a mean value in the biased ensemble with static bias \f$ V(\mathbf{s}) \f$.
+      63             : 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).
+      64             : 
+      65             : The bias potential \f$ V(\mathbf{s}) \f$ can be constructed with \ref METAD using \ref ENERGY as a CV \cite mich+04prl.
+      66             : 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.
+      67             : In the latter algorithms the interval of temperatures and pressures in which the trajectory can be reweighted is chosen explicitly.
+      68             : 
+      69             : \par Examples
+      70             : 
+      71             : We consider the 4 cases described above.
+      72             : 
+      73             : 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.
+      74             : 
+      75             : \plumedfile
+      76             : energy: READ FILE=COLVAR VALUES=energy  IGNORE_TIME
+      77             : distance: READ FILE=COLVAR VALUES=distance  IGNORE_TIME
+      78             : mybias: READ FILE=COLVAR VALUES=mybias.bias  IGNORE_TIME
+      79             : 
+      80             : # Shift energy (to avoid numerical issues)
+      81             : renergy: COMBINE ARG=energy PARAMETERS=-13250 PERIODIC=NO
+      82             : 
+      83             : # Weights
+      84             : bias_weights: REWEIGHT_BIAS TEMP=500 ARG=mybias.bias
+      85             : temp_press_weights: REWEIGHT_TEMP_PRESS TEMP=500 REWEIGHT_TEMP=300 ENERGY=renergy
+      86             : 
+      87             : # Ensemble average of the distance at 300 K
+      88             : avg_dist: AVERAGE ARG=distance LOGWEIGHTS=bias_weights,temp_press_weights
+      89             : 
+      90             : PRINT ARG=avg_dist FILE=COLVAR_REWEIGHT STRIDE=1
+      91             : \endplumedfile
+      92             : 
+      93             : 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
+      94             : to calculate the ensemble average of the distance at 300 K.
+      95             : 
+      96             : \auxfile{COLVAR}
+      97             : #! FIELDS time energy volume mybias.bias distance
+      98             :  10000.000000 -13133.769283 7.488921 63.740530 0.10293
+      99             :  10001.000000 -13200.239722 7.116548 36.691988 0.16253
+     100             :  10002.000000 -13165.108850 7.202273 44.408815 0.17625
+     101             : \endauxfile
+     102             : 
+     103             : 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.
+     104             : 
+     105             : 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).
+     106             : 
+     107             : \plumedfile
+     108             : energy: READ FILE=COLVAR VALUES=energy  IGNORE_TIME
+     109             : volume: READ FILE=COLVAR VALUES=volume  IGNORE_TIME
+     110             : mybias: READ FILE=COLVAR VALUES=mybias.bias  IGNORE_TIME
+     111             : 
+     112             : # Shift energy and volume (to avoid numerical issues)
+     113             : rvol: COMBINE ARG=volume PARAMETERS=7.8 PERIODIC=NO
+     114             : renergy: COMBINE ARG=energy PARAMETERS=-13250 PERIODIC=NO
+     115             : 
+     116             : # Weights
+     117             : bias_weights: REWEIGHT_BIAS TEMP=500 ARG=mybias.bias
+     118             : temp_press_weights: REWEIGHT_TEMP_PRESS TEMP=500 REWEIGHT_TEMP=300 PRESSURE=0.06022140857 ENERGY=renergy VOLUME=rvol
+     119             : 
+     120             : # Ensemble average of the volume at 300 K
+     121             : avg_vol: AVERAGE ARG=volume LOGWEIGHTS=bias_weights,temp_press_weights
+     122             : # Ensemble average of the density at 300 K
+     123             : avg_density: CUSTOM ARG=avg_vol FUNC=1000/x PERIODIC=NO
+     124             : 
+     125             : PRINT ARG=avg_density FILE=COLVAR_REWEIGHT STRIDE=1
+     126             : \endplumedfile
+     127             : 
+     128             : 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).
+     129             : 
+     130             : \plumedfile
+     131             : volume: READ FILE=COLVAR VALUES=volume  IGNORE_TIME
+     132             : mybias: READ FILE=COLVAR VALUES=mybias.bias  IGNORE_TIME
+     133             : 
+     134             : # Shift volume (to avoid numerical issues)
+     135             : rvol: COMBINE ARG=volume PARAMETERS=7.8 PERIODIC=NO
+     136             : 
+     137             : # Weights
+     138             : bias_weights: REWEIGHT_BIAS TEMP=500 ARG=mybias.bias
+     139             : temp_press_weights: REWEIGHT_TEMP_PRESS TEMP=500 PRESSURE=0.06022140857 REWEIGHT_PRESSURE=180.66422571 VOLUME=volume
+     140             : 
+     141             : # Ensemble average of the volume at 300 K and 300 MPa
+     142             : avg_vol: AVERAGE ARG=volume LOGWEIGHTS=bias_weights,temp_press_weights
+     143             : # Ensemble average of the density at 300 K and 300 MPa
+     144             : avg_density: CUSTOM ARG=avg_vol FUNC=1000/x PERIODIC=NO
+     145             : 
+     146             : PRINT ARG=avg_density FILE=COLVAR_REWEIGHT STRIDE=1
+     147             : \endplumedfile
+     148             : 
+     149             : 
+     150             : 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).
+     151             : 
+     152             : \plumedfile
+     153             : energy: READ FILE=COLVAR VALUES=energy  IGNORE_TIME
+     154             : volume: READ FILE=COLVAR VALUES=volume  IGNORE_TIME
+     155             : mybias: READ FILE=COLVAR VALUES=mybias.bias  IGNORE_TIME
+     156             : 
+     157             : # Shift energy and volume (to avoid numerical issues)
+     158             : rvol: COMBINE ARG=volume PARAMETERS=7.8 PERIODIC=NO
+     159             : renergy: COMBINE ARG=energy PARAMETERS=-13250 PERIODIC=NO
+     160             : 
+     161             : # Weights
+     162             : bias_weights: REWEIGHT_BIAS TEMP=500 ARG=mybias.bias
+     163             : temp_press_weights: REWEIGHT_TEMP_PRESS TEMP=500 REWEIGHT_TEMP=300 PRESSURE=0.06022140857 REWEIGHT_PRESSURE=180.66422571 ENERGY=renergy VOLUME=rvol
+     164             : 
+     165             : # Ensemble average of the volume at 300 K and 300 MPa
+     166             : avg_vol: AVERAGE ARG=volume LOGWEIGHTS=bias_weights,temp_press_weights
+     167             : # Ensemble average of the density at 300 K and 300 MPa
+     168             : avg_density: CUSTOM ARG=avg_vol FUNC=1000/x PERIODIC=NO
+     169             : 
+     170             : PRINT ARG=avg_density FILE=COLVAR_REWEIGHT STRIDE=1
+     171             : \endplumedfile
+     172             : 
+     173             : */
+     174             : //+ENDPLUMEDOC
+     175             : 
+     176             : namespace PLMD {
+     177             : namespace bias {
+     178             : 
+     179             : class ReweightTemperaturePressure : public ReweightBase {
+     180             : private:
+     181             : ///
+     182             :   double rpress_, press_, rtemp_;
+     183             :   std::vector<Value*> myenergy, myvol;
+     184             : public:
+     185             :   static void registerKeywords(Keywords&);
+     186             :   explicit ReweightTemperaturePressure(const ActionOptions&ao);
+     187             :   double getLogWeight() override;
+     188             : };
+     189             : 
+     190       10427 : PLUMED_REGISTER_ACTION(ReweightTemperaturePressure,"REWEIGHT_TEMP_PRESS")
+     191             : 
+     192           5 : void ReweightTemperaturePressure::registerKeywords(Keywords& keys ) {
+     193           5 :   ReweightBase::registerKeywords( keys );
+     194           5 :   keys.remove("ARG");
+     195          10 :   keys.add("optional","ENERGY","Energy");
+     196          10 :   keys.add("optional","VOLUME","Volume");
+     197          15 :   keys.add("optional","REWEIGHT_PRESSURE","Reweighting pressure");
+     198          10 :   keys.add("optional","PRESSURE","The system pressure");
+     199          10 :   keys.add("optional","REWEIGHT_TEMP","Reweighting temperature");
+     200           5 : }
+     201             : 
+     202           4 : ReweightTemperaturePressure::ReweightTemperaturePressure(const ActionOptions&ao):
+     203             :   Action(ao),
+     204           4 :   ReweightBase(ao)
+     205             : {
+     206             :   // Initialize to not defined (negative)
+     207           4 :   rpress_=-1;
+     208           4 :   press_=-1;
+     209           4 :   rtemp_=-1;
+     210           4 :   parse("REWEIGHT_PRESSURE",rpress_);
+     211           4 :   parse("PRESSURE",press_);
+     212           4 :   parse("REWEIGHT_TEMP",rtemp_);
+     213           4 :   rtemp_*=plumed.getAtoms().getKBoltzmann();
+     214             : 
+     215           8 :   parseArgumentList("ENERGY",myenergy);
+     216           4 :   if(!myenergy.empty()) {
+     217           3 :     log.printf("  with energies: ");
+     218           6 :     for(unsigned i=0; i<myenergy.size(); i++) log.printf(" %s",myenergy[i]->getName().c_str());
+     219           3 :     log.printf("\n");
+     220             :   }
+     221             :   //requestArguments(myenergy);
+     222             : 
+     223           8 :   parseArgumentList("VOLUME",myvol);
+     224           4 :   if(!myvol.empty()) {
+     225           3 :     log.printf("  with volumes: ");
+     226           6 :     for(unsigned i=0; i<myvol.size(); i++) log.printf(" %s",myvol[i]->getName().c_str());
+     227           3 :     log.printf("\n");
+     228             :   }
+     229             : 
+     230             :   std::vector<Value*> conc;
+     231           4 :   conc.insert(conc.begin(), myenergy.begin(), myenergy.end());
+     232           4 :   conc.insert(conc.end(), myvol.begin(), myvol.end());
+     233           4 :   requestArguments(conc);
+     234             : 
+     235             :   // 4 possible cases
+     236             :   // Case 1) Reweight from T to T' with V=const (canonical)
+     237           4 :   if (rtemp_>=0 && press_<0 && rpress_<0 && !myenergy.empty() && myvol.empty() ) {
+     238           1 :     log.printf("  reweighting simulation from temperature %f to temperature %f at constant volume \n",simtemp/plumed.getAtoms().getKBoltzmann(),rtemp_/plumed.getAtoms().getKBoltzmann() );
+     239           1 :     log.printf("  WARNING: If the simulation is performed at constant pressure add the keywords PRESSURE and VOLUME \n" );
+     240             :   }
+     241             :   // Case 2) Reweight from T to T' with P=const (isothermal-isobaric)
+     242           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/plumed.getAtoms().getKBoltzmann(),rtemp_/plumed.getAtoms().getKBoltzmann(), press_ );
+     243             :   // Case 3) Reweight from P to P' with T=const (isothermal-isobaric)
+     244           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/plumed.getAtoms().getKBoltzmann() );
+     245             :   // Case 4) Reweight from T,P to T',P' (isothermal-isobaric)
+     246           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/plumed.getAtoms().getKBoltzmann(), press_, rtemp_/plumed.getAtoms().getKBoltzmann(), rpress_);
+     247           0 :   else error("Combination of ENERGY, VOLUME, REWEIGHT_PRESSURE, PRESSURE and REWEIGHT_TEMP not supported. Please refer to the manual for supported combinations.");
+     248           4 : }
+     249             : 
+     250        1001 : double ReweightTemperaturePressure::getLogWeight() {
+     251        2002 :   double energy=0.0; for(unsigned i=0; i<myenergy.size(); ++i) energy+=getArgument(i);
+     252        2002 :   double volume=0.0; for(unsigned i=0; i<myvol.size(); ++i) volume+=getArgument(myenergy.size()+i);
+     253             :   // 4 possible cases
+     254             :   // Case 1) Reweight from T to T' with V=const (canonical)
+     255        1001 :   if (rtemp_>=0 && press_<0 && rpress_<0) return ((1.0/simtemp)- (1.0/rtemp_) )*energy;
+     256             :   // Case 2) Reweight from T to T' with P=const (isothermal-isobaric)
+     257        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;
+     258             :   // Case 3) Reweight from P to P' with T=const (isothermal-isobaric)
+     259        1001 :   else if (rtemp_<0 && press_>=0 && rpress_>=0)  return (1.0/simtemp)*(press_ - rpress_)*volume;
+     260             :   // Case 4) Reweight from T,P to T',P' (isothermal-isobaric)
+     261        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;
+     262             :   else return 0;
+     263             : }
+     264             : 
+     265             : }
+     266             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..f8da452e2d --- /dev/null +++ b/coverage/bias/ReweightWham.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:454991.8 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightWham9clearDataEv0
_ZN4PLMD4bias12ReweightWhamC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightWham16calculateWeightsERKj7
_ZN4PLMD4bias12ReweightWhamC1ERKNS_13ActionOptionsE12
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe966createERKNS_13ActionOptionsE12
_ZNK4PLMD4bias12ReweightWham17buildsWeightStoreEv12
_ZN4PLMD4bias12ReweightWham16registerKeywordsERNS_8KeywordsE13
_ZNK4PLMD4bias12ReweightWham9getWeightERKj2457
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe96C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe96D2Ev3473
_ZN4PLMD4bias12ReweightWham12getLogWeightEv4224
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightWham.cpp.func.html b/coverage/bias/ReweightWham.cpp.func.html new file mode 100644 index 0000000000..f6285a406d --- /dev/null +++ b/coverage/bias/ReweightWham.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:454991.8 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightWham12getLogWeightEv4224
_ZN4PLMD4bias12ReweightWham16calculateWeightsERKj7
_ZN4PLMD4bias12ReweightWham16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4bias12ReweightWham9clearDataEv0
_ZN4PLMD4bias12ReweightWhamC1ERKNS_13ActionOptionsE12
_ZN4PLMD4bias12ReweightWhamC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe966createERKNS_13ActionOptionsE12
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe96C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe96D2Ev3473
_ZNK4PLMD4bias12ReweightWham17buildsWeightStoreEv12
_ZNK4PLMD4bias12ReweightWham9getWeightERKj2457
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/ReweightWham.cpp.gcov.html b/coverage/bias/ReweightWham.cpp.gcov.html new file mode 100644 index 0000000000..6f0b773f53 --- /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:454991.8 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ + + + + + + + +

+
          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       10443 : PLUMED_REGISTER_ACTION(ReweightWham,"REWEIGHT_WHAM")
+      97             : 
+      98          13 : void ReweightWham::registerKeywords(Keywords& keys ) {
+      99          13 :   ReweightBase::registerKeywords( keys ); keys.remove("ARG");
+     100          26 :   keys.add("compulsory","ARG","*.bias","the biases that must be taken into account when reweighting");
+     101          26 :   keys.add("compulsory","MAXITER","1000","maximum number of iterations for WHAM algorithm");
+     102          26 :   keys.add("compulsory","WHAMTOL","1e-10","threshold for convergence of WHAM algorithm");
+     103          13 : }
+     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.15
+
+ + + 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 0000000000..314ae06655 --- /dev/null +++ b/coverage/bias/UWalls.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:5555100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6UWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe756createERKNS_13ActionOptionsE17
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE17
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe75C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe75D2Ev3473
_ZN4PLMD4bias6UWalls9calculateEv28015
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/UWalls.cpp.func.html b/coverage/bias/UWalls.cpp.func.html new file mode 100644 index 0000000000..2cdd434b3a --- /dev/null +++ b/coverage/bias/UWalls.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:5555100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe756createERKNS_13ActionOptionsE17
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe75C2Ev3473
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe75D2Ev3473
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD4bias6UWalls9calculateEv28015
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE17
_ZN4PLMD4bias6UWallsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/UWalls.cpp.gcov.html b/coverage/bias/UWalls.cpp.gcov.html new file mode 100644 index 0000000000..8dcd7e28e2 --- /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:5555100.0 %
Date:2024-06-10 08:19:14Functions: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 "Bias.h"
+      23             : #include "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       10453 : PLUMED_REGISTER_ACTION(UWalls,"UPPER_WALLS")
+      76             : 
+      77          18 : void UWalls::registerKeywords(Keywords& keys) {
+      78          18 :   Bias::registerKeywords(keys);
+      79          18 :   keys.use("ARG");
+      80          36 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      81          36 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      82          36 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      83          36 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      84          36 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      85          36 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      86          18 : }
+      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             :     setOutputForce(i,f);
+     141             :   }
+     142             :   setBias(ene);
+     143       28015 :   getPntrToComponent("force2")->set(totf2);
+     144       28015 : }
+     145             : 
+     146             : }
+     147             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/index-sort-f.html b/coverage/bias/index-sort-f.html new file mode 100644 index 0000000000..443f0c1473 --- /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:2347256791.4 %
Date:2024-06-10 08:19:14Functions:14316785.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
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
ReweightBase.cpp +
95.0%95.0%
+
95.0 %19 / 2075.0 %3 / 4
ReweightWham.cpp +
91.8%91.8%
+
91.8 %45 / 4981.8 %9 / 11
MovingRestraint.cpp +
100.0%
+
100.0 %101 / 10185.7 %6 / 7
ABMD.cpp +
100.0%
+
100.0 %61 / 6185.7 %6 / 7
BiasValue.cpp +
100.0%
+
100.0 %19 / 1985.7 %6 / 7
ReweightMetad.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
UWalls.cpp +
100.0%
+
100.0 %55 / 5585.7 %6 / 7
Restraint.cpp +
100.0%
+
100.0 %40 / 4085.7 %6 / 7
LWalls.cpp +
100.0%
+
100.0 %55 / 5585.7 %6 / 7
ReweightBias.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
External.cpp +
100.0%
+
100.0 %40 / 4085.7 %6 / 7
ReweightTemperaturePressure.cpp +
97.9%97.9%
+
97.9 %46 / 4785.7 %6 / 7
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %93 / 9487.5 %7 / 8
PBMetaD.cpp +
88.0%88.0%
+
88.0 %528 / 60088.9 %16 / 18
MaxEnt.cpp +
96.2%96.2%
+
96.2 %227 / 23692.9 %13 / 14
MetaD.cpp +
88.1%88.1%
+
88.1 %951 / 107993.5 %29 / 31
Bias.h +
100.0%
+
100.0 %6 / 6100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/index-sort-l.html b/coverage/bias/index-sort-l.html new file mode 100644 index 0000000000..3a98a73912 --- /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:2347256791.4 %
Date:2024-06-10 08:19:14Functions:14316785.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.0%88.0%
+
88.0 %528 / 60088.9 %16 / 18
MetaD.cpp +
88.1%88.1%
+
88.1 %951 / 107993.5 %29 / 31
ReweightWham.cpp +
91.8%91.8%
+
91.8 %45 / 4981.8 %9 / 11
ReweightBase.cpp +
95.0%95.0%
+
95.0 %19 / 2075.0 %3 / 4
MaxEnt.cpp +
96.2%96.2%
+
96.2 %227 / 23692.9 %13 / 14
ReweightTemperaturePressure.cpp +
97.9%97.9%
+
97.9 %46 / 4785.7 %6 / 7
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %93 / 9487.5 %7 / 8
Bias.h +
100.0%
+
100.0 %6 / 6100.0 %1 / 1
ReweightMetad.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
ReweightBias.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
BiasValue.cpp +
100.0%
+
100.0 %19 / 1985.7 %6 / 7
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
Restraint.cpp +
100.0%
+
100.0 %40 / 4085.7 %6 / 7
External.cpp +
100.0%
+
100.0 %40 / 4085.7 %6 / 7
UWalls.cpp +
100.0%
+
100.0 %55 / 5585.7 %6 / 7
LWalls.cpp +
100.0%
+
100.0 %55 / 5585.7 %6 / 7
ABMD.cpp +
100.0%
+
100.0 %61 / 6185.7 %6 / 7
MovingRestraint.cpp +
100.0%
+
100.0 %101 / 10185.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/bias/index.html b/coverage/bias/index.html new file mode 100644 index 0000000000..41d6c5571c --- /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:2347256791.4 %
Date:2024-06-10 08:19:14Functions:14316785.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ABMD.cpp +
100.0%
+
100.0 %61 / 6185.7 %6 / 7
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
Bias.h +
100.0%
+
100.0 %6 / 6100.0 %1 / 1
BiasValue.cpp +
100.0%
+
100.0 %19 / 1985.7 %6 / 7
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %93 / 9487.5 %7 / 8
External.cpp +
100.0%
+
100.0 %40 / 4085.7 %6 / 7
LWalls.cpp +
100.0%
+
100.0 %55 / 5585.7 %6 / 7
MaxEnt.cpp +
96.2%96.2%
+
96.2 %227 / 23692.9 %13 / 14
MetaD.cpp +
88.1%88.1%
+
88.1 %951 / 107993.5 %29 / 31
MovingRestraint.cpp +
100.0%
+
100.0 %101 / 10185.7 %6 / 7
PBMetaD.cpp +
88.0%88.0%
+
88.0 %528 / 60088.9 %16 / 18
Restraint.cpp +
100.0%
+
100.0 %40 / 4085.7 %6 / 7
ReweightBase.cpp +
95.0%95.0%
+
95.0 %19 / 2075.0 %3 / 4
ReweightBase.h +
33.3%33.3%
+
33.3 %2 / 633.3 %2 / 6
ReweightBias.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
ReweightMetad.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
ReweightTemperaturePressure.cpp +
97.9%97.9%
+
97.9 %46 / 4785.7 %6 / 7
ReweightWham.cpp +
91.8%91.8%
+
91.8 %45 / 4981.8 %9 / 11
UWalls.cpp +
100.0%
+
100.0 %55 / 5585.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..741f9d749f --- /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-06-10 08:19:14Functions: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_8KeywordsE3473
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/Completion.cpp.func.html b/coverage/cltools/Completion.cpp.func.html new file mode 100644 index 0000000000..0152e6ab67 --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10Completion16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools10Completion4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools10CompletionC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev3473
_ZNK4PLMD7cltools10Completion11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/Completion.cpp.gcov.html b/coverage/cltools/Completion.cpp.gcov.html new file mode 100644 index 0000000000..c9342e9ef9 --- /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-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_CLTOOL(Completion,"completion")
+      65             : 
+      66        3473 : void Completion::registerKeywords( Keywords& keys ) {
+      67        3473 :   CLTool::registerKeywords( keys );
+      68        3473 : }
+      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.15
+
+ + + 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 0000000000..17570c01d8 --- /dev/null +++ b/coverage/cltools/Driver.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:53456794.2 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools6DriverIfE28evaluateNumericalDerivativesERKlRNS_10PlumedMainERKSt6vectorIfSaIfEESB_SB_RS9_RKdSC_0
_ZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorE0
_ZN4PLMD7cltools6DriverIfEC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools6DriverIdE11descriptionB5cxx11Ev4
_ZN4PLMD7cltools6DriverIdE28evaluateNumericalDerivativesERKlRNS_10PlumedMainERKSt6vectorIdSaIdEESB_SB_RS9_RKdSC_25
_ZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorE712
_ZN4PLMD7cltools6DriverIdEC2ERKNS_13CLToolOptionsE716
_ZN4PLMD7cltools6DriverIdE16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools6DriverIfE16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltoolsL11register_cbEPvPNS_7molfile11vmdplugin_tE62514
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/Driver.cpp.func.html b/coverage/cltools/Driver.cpp.func.html new file mode 100644 index 0000000000..3af9f2f8f6 --- /dev/null +++ b/coverage/cltools/Driver.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:53456794.2 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE716
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/DriverDouble.cpp.func.html b/coverage/cltools/DriverDouble.cpp.func.html new file mode 100644 index 0000000000..88647a7925 --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE716
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/DriverDouble.cpp.gcov.html b/coverage/cltools/DriverDouble.cpp.gcov.html new file mode 100644 index 0000000000..d8fb20a6ec --- /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-06-10 08:19:14Functions: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       11135 : PLUMED_REGISTER_CLTOOL(DriverDouble,"driver")
+      34             : 
+      35             : }
+      36             : }
+      37             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ae18757add --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools6DriverIfE11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.func.html b/coverage/cltools/DriverFloat.cpp.func.html new file mode 100644 index 0000000000..05940badf4 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev3473
_ZNK4PLMD7cltools6DriverIfE11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.gcov.html b/coverage/cltools/DriverFloat.cpp.gcov.html new file mode 100644 index 0000000000..98c93159b6 --- /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-06-10 08:19:14Functions: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       10423 : PLUMED_REGISTER_CLTOOL(DriverFloat,"driver-float")
+      39             : 
+      40             : }
+      41             : }
+      42             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..abbee4b368 --- /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-06-10 08:19:14Functions: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_8KeywordsE3473
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.func.html b/coverage/cltools/GenExample.cpp.func.html new file mode 100644 index 0000000000..2c1d2821c7 --- /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-06-10 08:19:14Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11GenTemplate16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools11GenTemplate4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools11GenTemplateC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeD2Ev3473
_ZNK4PLMD7cltools11GenTemplate11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/GenTemplate.cpp.gcov.html b/coverage/cltools/GenTemplate.cpp.gcov.html new file mode 100644 index 0000000000..f923bc0090 --- /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-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_CLTOOL(GenTemplate,"gentemplate")
+      64             : 
+      65        3473 : void GenTemplate::registerKeywords( Keywords& keys ) {
+      66        3473 :   CLTool::registerKeywords( keys );
+      67        6946 :   keys.add("optional","--action","print the template for this particular action");
+      68        6946 :   keys.addFlag("--list",false,"print a list of the available actions");
+      69        6946 :   keys.addFlag("--include-optional",false,"also print optional modifiers");
+      70        3473 : }
+      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.15
+
+ + + 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 0000000000..1ccfa21dc7 --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools4Info11descriptionB5cxx11Ev4
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE1212
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE1216
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE1216
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev3473
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/Info.cpp.func.html b/coverage/cltools/Info.cpp.func.html new file mode 100644 index 0000000000..0082d00f99 --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE1216
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev3473
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE1212
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE1216
_ZNK4PLMD7cltools4Info11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/Info.cpp.gcov.html b/coverage/cltools/Info.cpp.gcov.html new file mode 100644 index 0000000000..393af10602 --- /dev/null +++ b/coverage/cltools/Info.cpp.gcov.html @@ -0,0 +1,198 @@ + + + + + + + + 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-06-10 08:19:14Functions: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 "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       11635 : PLUMED_REGISTER_CLTOOL(Info,"info")
+      62             : 
+      63        3473 : void Info::registerKeywords( Keywords& keys ) {
+      64        3473 :   CLTool::registerKeywords( keys );
+      65        6946 :   keys.addFlag("--configuration",false,"prints the configuration file");
+      66        6946 :   keys.addFlag("--root",false,"print the location of the root directory for the plumed source");
+      67        6946 :   keys.addFlag("--user-doc",false,"print the location of user manual (html)");
+      68        6946 :   keys.addFlag("--developer-doc",false,"print the location of user manual (html)");
+      69        6946 :   keys.addFlag("--version",false,"print the version number");
+      70        6946 :   keys.addFlag("--long-version",false,"print the version number (long version)");
+      71        6946 :   keys.addFlag("--git-version",false,"print the version number (git version, if available)");
+      72        6946 :   keys.addFlag("--include-dir",false,"print the location of the include dir");
+      73        6946 :   keys.addFlag("--soext",false,"print the extension of shared libraries (so or dylib)");
+      74        3473 : }
+      75             : 
+      76        1216 : Info::Info(const CLToolOptions& co ):
+      77        1216 :   CLTool(co)
+      78             : {
+      79        1216 :   inputdata=commandline;
+      80        1216 : }
+      81             : 
+      82        1212 : int Info::main(FILE* in, FILE*out,Communicator& pc) {
+      83             : 
+      84        1212 :   bool printconfiguration; parseFlag("--configuration",printconfiguration);
+      85        1212 :   bool printroot; parseFlag("--root",printroot);
+      86        1212 :   bool printuserdoc; parseFlag("--user-doc",printuserdoc);
+      87        1212 :   bool printdeveloperdoc; parseFlag("--developer-doc",printdeveloperdoc);
+      88        1212 :   bool printversion; parseFlag("--version",printversion);
+      89        1212 :   bool printlongversion; parseFlag("--long-version",printlongversion);
+      90        1212 :   bool printgitversion; parseFlag("--git-version",printgitversion);
+      91        1212 :   bool printincludedir; parseFlag("--include-dir",printincludedir);
+      92        1212 :   bool printsoext; parseFlag("--soext",printsoext);
+      93        1805 :   if(printroot) std::fprintf(out,"%s\n",config::getPlumedRoot().c_str());
+      94        1239 :   if(printconfiguration) std::fprintf(out,"%s",config::getMakefile().c_str());
+      95        1212 :   if(printincludedir) std::fprintf(out,"%s\n",config::getPlumedIncludedir().c_str());
+      96        1212 :   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           0 :     if(ff) std::fclose(ff);
+     100           0 :     else userdoc="http://www.plumed.org/doc-v" + config::getVersion() + "/user-doc/html/index.html";
+     101             :     std::fprintf(out,"%s\n",userdoc.c_str());
+     102             :   }
+     103        1212 :   if(printdeveloperdoc) {
+     104           0 :     std::string developerdoc=config::getPlumedHtmldir()+"/developer-doc/html/index.html";
+     105           0 :     FILE *ff=std::fopen(developerdoc.c_str(),"r");
+     106           0 :     if(ff) std::fclose(ff);
+     107           0 :     else developerdoc="http://www.plumed.org/doc-v" + config::getVersion() + "/developer-doc/html/index.html";
+     108             :     std::fprintf(out,"%s\n",developerdoc.c_str());
+     109             :   }
+     110        1212 :   if(printversion) std::fprintf(out,"%s\n",config::getVersion().c_str());
+     111        1212 :   if(printlongversion) std::fprintf(out,"%s\n",config::getVersionLong().c_str());
+     112        1212 :   if(printgitversion) std::fprintf(out,"%s\n",config::getVersionGit().c_str());
+     113        1804 :   if(printsoext) std::fprintf(out,"%s\n",config::getSoExt().c_str());
+     114             : 
+     115        1212 :   return 0;
+     116             : }
+     117             : 
+     118             : 
+     119             : 
+     120             : }
+     121             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..4a7cd55829 --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools6Manual11descriptionB5cxx11Ev4
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE288
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE292
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE292
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev3473
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/Manual.cpp.func.html b/coverage/cltools/Manual.cpp.func.html new file mode 100644 index 0000000000..5d3a097d08 --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE292
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev3473
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE288
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE292
_ZNK4PLMD7cltools6Manual11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/Manual.cpp.gcov.html b/coverage/cltools/Manual.cpp.gcov.html new file mode 100644 index 0000000000..0e5d210e03 --- /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-06-10 08:19:14Functions: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 "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       10711 : PLUMED_REGISTER_CLTOOL(Manual,"manual")
+      67             : 
+      68        3473 : void Manual::registerKeywords( Keywords& keys ) {
+      69        3473 :   CLTool::registerKeywords( keys );
+      70        6946 :   keys.add("compulsory","--action","print the manual for this particular action");
+      71        6946 :   keys.addFlag("--vim",false,"print the keywords in vim syntax");
+      72        6946 :   keys.addFlag("--spelling",false,"print a list of the keywords and component names for the spell checker");
+      73        3473 : }
+      74             : 
+      75         292 : Manual::Manual(const CLToolOptions& co ):
+      76         292 :   CLTool(co)
+      77             : {
+      78         292 :   inputdata=commandline;
+      79         292 : }
+      80             : 
+      81         288 : int Manual::main(FILE* in, FILE*out,Communicator& pc) {
+      82             : 
+      83             :   std::string action;
+      84         576 :   if( !parse("--action",action) ) return 1;
+      85         288 :   std::cerr<<"LIST OF DOCUMENTED ACTIONS:\n";
+      86         288 :   std::cerr<<actionRegister()<<"\n";
+      87         288 :   std::cerr<<"LIST OF DOCUMENTED COMMAND LINE TOOLS:\n";
+      88         288 :   std::cerr<<cltoolRegister()<<"\n\n";
+      89         288 :   bool vimout; parseFlag("--vim",vimout);
+      90         288 :   bool spellout; parseFlag("--spelling",spellout);
+      91         288 :   if( vimout && spellout ) error("can only use one of --vim and --spelling at a time");
+      92         288 :   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.15
+
+ + + 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 0000000000..474ebe6114 --- /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-06-10 08:19:14Functions: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_8KeywordsE3473
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/PdbRenumber.cpp.func.html b/coverage/cltools/PdbRenumber.cpp.func.html new file mode 100644 index 0000000000..e1c7c52f3c --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11PdbRenumber16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools11PdbRenumber4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZN4PLMD7cltools11PdbRenumberC2ERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeD2Ev3473
_ZNK4PLMD7cltools11PdbRenumber11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/PdbRenumber.cpp.gcov.html b/coverage/cltools/PdbRenumber.cpp.gcov.html new file mode 100644 index 0000000000..ff0f960353 --- /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-06-10 08:19:14Functions: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 "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       10426 : PLUMED_REGISTER_CLTOOL(PdbRenumber,"pdbrenumber")
+     113             : 
+     114        3473 : void PdbRenumber::registerKeywords( Keywords& keys ) {
+     115        3473 :   CLTool::registerKeywords( keys );
+     116        6946 :   keys.add("compulsory","--ipdb","specify the name of the input PDB file");
+     117        6946 :   keys.add("compulsory","--opdb","specify the name of the output PDB file");
+     118       10419 :   keys.add("optional","--firstatomnumber","specify the desired serial number of the first atom of the output file");
+     119        6946 :   keys.add("optional","--atomnumbers","specify the desired serial numbers of the atoms of the output file using a separate list");
+     120        3473 : }
+     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.15
+
+ + + 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 0000000000..ad9aa1d8c3 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + 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:26727098.9 %
Date:2024-06-10 08:19:14Functions:1919100.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_S3_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
_ZN4PLMD7cltools8SimpleMD15write_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb39
_ZN4PLMD7cltools8SimpleMD16write_statisticsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEidiiddd174
_ZN4PLMD7cltools8SimpleMD12compute_listEiiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRS2_IiSaIiEESD_458
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeD2Ev3473
_ZN4PLMD7cltools8SimpleMD16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools8SimpleMD10check_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EES8_ddRb5700
_ZN4PLMD7cltools8SimpleMD14compute_engkinEiRKSt6vectorIdSaIdEERKS2_INS_13VectorGenericILj3EEESaIS8_EERd5700
_ZN4PLMD7cltools8SimpleMD14compute_forcesEiiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRKS2_IiSaIiEESE_RS6_Rd5709
_ZN4PLMD7cltools8SimpleMD10thermostatEiiRKSt6vectorIdSaIdEEdddRS2_INS_13VectorGenericILj3EEESaIS8_EERdRNS_6RandomE11400
_ZN4PLMD7cltools8SimpleMD3pbcEPKdRKNS_13VectorGenericILj3EEERS5_9982883
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.func.html b/coverage/cltools/SimpleMD.cpp.func.html new file mode 100644 index 0000000000..489e383d41 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func.html @@ -0,0 +1,149 @@ + + + + + + + + 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:26727098.9 %
Date:2024-06-10 08:19:14Functions:1919100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools14CLToolSumHills11descriptionB5cxx11Ev4
_ZN4PLMD7cltools14CLToolSumHills18findCvsAndPeriodicENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS8_IS7_SaIS7_EESaISA_EERSA_SE_RbRS7_SG_9
_ZN4PLMD7cltools14CLToolSumHills4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools14CLToolSumHillsC2ERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev3473
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.func.html b/coverage/cltools/SumHills.cpp.func.html new file mode 100644 index 0000000000..9702e29a4e --- /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:19421789.4 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev3473
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools14CLToolSumHills18findCvsAndPeriodicENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS8_IS7_SaIS7_EESaISA_EERSA_SE_RbRS7_SG_9
_ZN4PLMD7cltools14CLToolSumHills4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools14CLToolSumHillsC2ERKNS_13CLToolOptionsE13
_ZNK4PLMD7cltools14CLToolSumHills11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.gcov.html b/coverage/cltools/SumHills.cpp.gcov.html new file mode 100644 index 0000000000..f7c731aa08 --- /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:19421789.4 %
Date:2024-06-10 08:19:14Functions: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 "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(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        3473 : void CLToolSumHills::registerKeywords( Keywords& keys ) {
+     199        3473 :   CLTool::registerKeywords( keys );
+     200        6946 :   keys.addFlag("--help-debug",false,"print special options that can be used to create regtests");
+     201        6946 :   keys.add("optional","--hills","specify the name of the hills file");
+     202        6946 :   keys.add("optional","--histo","specify the name of the file for histogram a colvar/hills file is good");
+     203        6946 :   keys.add("optional","--stride","specify the stride for integrating hills file (default 0=never)");
+     204        6946 :   keys.add("optional","--min","the lower bounds for the grid");
+     205        6946 :   keys.add("optional","--max","the upper bounds for the grid");
+     206        6946 :   keys.add("optional","--bin","the number of bins for the grid");
+     207        6946 :   keys.add("optional","--spacing","grid spacing, alternative to the number of bins");
+     208        6946 :   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        6946 :   keys.add("optional","--outfile","specify the output file for sumhills");
+     210        6946 :   keys.add("optional","--outhisto","specify the output file for the histogram");
+     211        6946 :   keys.add("optional","--kt","specify temperature in energy units for integrating out variables");
+     212        6946 :   keys.add("optional","--sigma"," a vector that specify the sigma for binning (only needed when doing histogram ");
+     213        6946 :   keys.addFlag("--negbias",false," print the negative bias instead of the free energy (only needed with well tempered runs and flexible hills) ");
+     214        6946 :   keys.addFlag("--nohistory",false," to be used with --stride:  it splits the bias/histogram in pieces without previous history ");
+     215        6946 :   keys.addFlag("--mintozero",false," it translate all the minimum value in bias/histogram to zero (useful to compare results) ");
+     216        6946 :   keys.add("optional","--fmt","specify the output format");
+     217        3473 : }
+     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          16 :     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           6 :     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           0 :     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          18 :   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);
+     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          11 :     addme="GRID_BIN="; for(unsigned i=0; i<(ncv-1); i++)addme+=gbin[i]+","; addme+=gbin[ncv-1];
+     463           6 :     actioninput.push_back(addme);
+     464             :   }
+     465           9 :   if(grid_has_spacing) {
+     466           0 :     addme="GRID_SPACING="; for(unsigned i=0; i<(ncv-1); i++)addme+=gspacing[i]+","; addme+=gspacing[ncv-1];
+     467           0 :     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);
+     531             :   // if not a grid, then set it up automatically
+     532           9 :   return 0;
+     533          27 : }
+     534             : 
+     535           9 : bool CLToolSumHills::findCvsAndPeriodic(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           9 :     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       10432 : PLUMED_REGISTER_CLTOOL(CLToolSumHills,"sum_hills")
+     621             : 
+     622             : 
+     623             : 
+     624             : }
+     625             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/index-sort-f.html b/coverage/cltools/index-sort-f.html new file mode 100644 index 0000000000..f1840cb7f6 --- /dev/null +++ b/coverage/cltools/index-sort-f.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1292160780.4 %
Date:2024-06-10 08:19:14Functions:9410292.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
Driver.cpp +
94.2%94.2%
+
94.2 %534 / 56780.0 %8 / 10
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
GenTemplate.cpp +
56.5%56.5%
+
56.5 %13 / 2385.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
pesmd.cpp +
100.0%
+
100.0 %128 / 128100.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
SumHills.cpp +
89.4%89.4%
+
89.4 %194 / 217100.0 %8 / 8
SimpleMD.cpp +
98.9%98.9%
+
98.9 %267 / 270100.0 %19 / 19
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/index-sort-l.html b/coverage/cltools/index-sort-l.html new file mode 100644 index 0000000000..246a247f27 --- /dev/null +++ b/coverage/cltools/index-sort-l.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1292160780.4 %
Date:2024-06-10 08:19:14Functions:9410292.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
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
SumHills.cpp +
89.4%89.4%
+
89.4 %194 / 217100.0 %8 / 8
Driver.cpp +
94.2%94.2%
+
94.2 %534 / 56780.0 %8 / 10
PdbRenumber.cpp +
96.2%96.2%
+
96.2 %51 / 53100.0 %7 / 7
SimpleMD.cpp +
98.9%98.9%
+
98.9 %267 / 270100.0 %19 / 19
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
pesmd.cpp +
100.0%
+
100.0 %128 / 128100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/index.html b/coverage/cltools/index.html new file mode 100644 index 0000000000..867fce8ef7 --- /dev/null +++ b/coverage/cltools/index.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1292160780.4 %
Date:2024-06-10 08:19:14Functions:9410292.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Completion.cpp +
27.8%27.8%
+
27.8 %10 / 3685.7 %6 / 7
Driver.cpp +
94.2%94.2%
+
94.2 %534 / 56780.0 %8 / 10
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
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 +
98.9%98.9%
+
98.9 %267 / 270100.0 %19 / 19
SumHills.cpp +
89.4%89.4%
+
89.4 %194 / 217100.0 %8 / 8
kT.cpp +
63.2%63.2%
+
63.2 %12 / 1985.7 %6 / 7
pesmd.cpp +
100.0%
+
100.0 %128 / 128100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7f278e008f --- /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-06-10 08:19:14Functions: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_112ktRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev3473
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/kT.cpp.func.html b/coverage/cltools/kT.cpp.func.html new file mode 100644 index 0000000000..00db44d9e1 --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev3473
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools2kt4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools2ktC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools2kt11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/kT.cpp.gcov.html b/coverage/cltools/kT.cpp.gcov.html new file mode 100644 index 0000000000..8dcb256e96 --- /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-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_CLTOOL(kt,"kt")
+      63             : 
+      64        3473 : void kt::registerKeywords( Keywords& keys ) {
+      65        3473 :   CLTool::registerKeywords( keys );
+      66        6946 :   keys.add("compulsory","--temp","print the manual for this particular action");
+      67        6946 :   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        3473 : }
+      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.15
+
+ + + 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 0000000000..4a5ef78290 --- /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:128128100.0 %
Date:2024-06-10 08:19:14Functions: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_115PesMDRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev3473
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.func.html b/coverage/cltools/pesmd.cpp.func.html new file mode 100644 index 0000000000..cb64f7eedb --- /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:128128100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeC2Ev3473
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev3473
_ZN4PLMD7cltools5PesMD10read_inputERdS2_S2_RiRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEES3_RbSE_S3_3
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7cltools5PesMD4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZNK4PLMD7cltools5PesMD11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.gcov.html b/coverage/cltools/pesmd.cpp.gcov.html new file mode 100644 index 0000000000..1ac2dc71b9 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.gcov.html @@ -0,0 +1,390 @@ + + + + + + + + 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:128128100.0 %
Date:2024-06-10 08:19:14Functions: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 "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        3473 :   static void registerKeywords( Keywords& keys ) {
+     104        6946 :     keys.add("compulsory","nstep","The number of steps of dynamics you want to run");
+     105        6946 :     keys.add("compulsory","temperature","NVE","the temperature at which you wish to run the simulation in LJ units");
+     106        6946 :     keys.add("compulsory","friction","off","The friction (in LJ units) for the Langevin thermostat that is used to keep the temperature constant");
+     107        6946 :     keys.add("compulsory","tstep","0.005","the integration timestep in LJ units");
+     108        6946 :     keys.add("compulsory","dimension","the dimension of your energy landscape");
+     109        6946 :     keys.add("compulsory","plumed","plumed.dat","the name of the plumed input file containing the potential");
+     110        6946 :     keys.add("compulsory","ipos","0.0","the initial position of the system");
+     111        6946 :     keys.add("compulsory","idum","0","The random number seed");
+     112        6946 :     keys.addFlag("periodic",false,"are your input coordinates periodic");
+     113        6946 :     keys.add("optional","min","minimum value the coordinates can take for a periodic domain");
+     114        6946 :     keys.add("optional","max","maximum value the coordinates can take for a periodic domain");
+     115        3473 :   }
+     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           3 :     auto plumed=Tools::make_unique<PLMD::PlumedMain>();
+     185           3 :     int s=sizeof(double);
+     186           9 :     plumed->cmd("setRealPrecision",&s);
+     187           3 :     if(Communicator::initialized()) plumed->cmd("setMPIComm",&pc.Get_comm());
+     188           6 :     plumed->cmd("setNoVirial");
+     189           3 :     int natoms=( std::floor(dim/3) +  2 );
+     190           6 :     plumed->cmd("setNatoms",&natoms);
+     191           6 :     plumed->cmd("setMDEngine","pesmd");
+     192           6 :     plumed->cmd("setTimestep",&tstep);
+     193           6 :     plumed->cmd("setPlumedDat",plumedin.c_str());
+     194           6 :     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           6 :     plumed->cmd("setStep",&istep);
+     220           6 :     plumed->cmd("setMasses",&masses[0]);
+     221          10 :     for(unsigned i=0; i<forces.size(); ++i) forces[i].zero();
+     222           6 :     plumed->cmd("setForces",&forces[0][0]);
+     223           6 :     plumed->cmd("setEnergy",&zero);
+     224           5 :     if( lperiod ) plumed->cmd("setBox",&box[0]);
+     225           6 :     plumed->cmd("setPositions",&positions[0][0]);
+     226           6 :     plumed->cmd("calc");
+     227             : 
+     228             : 
+     229             :     double therm_eng=0;
+     230           3 :     FILE* fp=fopen("stats.out","w+");
+     231             : 
+     232         153 :     for(int istep=0; istep<nsteps; ++istep) {
+     233             : 
+     234         150 :       if( istep%20==0 && pc.Get_rank()==0 ) std::printf("Doing step %i\n",istep);
+     235             : 
+     236             :       // Langevin thermostat
+     237         150 :       double lscale=std::exp(-0.5*tstep/friction);
+     238         150 :       double lrand=std::sqrt((1.-lscale*lscale)*temp);
+     239         350 :       for(int j=0; j<nat; ++j) {
+     240         500 :         for(int k=0; k<3; ++k) {
+     241         450 :           if( 3*j+k>dim-1 ) break;
+     242         300 :           therm_eng=therm_eng+0.5*velocities[j][k]*velocities[j][k];
+     243         300 :           velocities[j][k]=lscale*velocities[j][k]+lrand*random.Gaussian();
+     244         300 :           therm_eng=therm_eng-0.5*velocities[j][k]*velocities[0][k];
+     245             :         }
+     246             :       }
+     247             : 
+     248             :       // First step of velocity verlet
+     249         350 :       for(int j=0; j<nat; ++j) {
+     250         500 :         for(int k=0; k<3; ++k) {
+     251         450 :           if( 3*j+k>dim-1 ) break;
+     252         300 :           velocities[j][k] = velocities[j][k] + 0.5*tstep*forces[1+j][k];
+     253         300 :           positions[1+j][k] = positions[1+j][k] + tstep*velocities[j][k];
+     254             :         }
+     255             :       }
+     256             : 
+     257         150 :       int istepplusone=istep+1;
+     258         150 :       plumedWantsToStop=0;
+     259         300 :       plumed->cmd("setStep",&istepplusone);
+     260         300 :       plumed->cmd("setMasses",&masses[0]);
+     261         500 :       for(unsigned i=0; i<forces.size(); ++i) forces[i].zero();
+     262         300 :       plumed->cmd("setForces",&forces[0][0]);
+     263         150 :       double fenergy=0.0;
+     264         300 :       plumed->cmd("setEnergy",&fenergy);
+     265         300 :       plumed->cmd("setPositions",&positions[0][0]);
+     266         300 :       plumed->cmd("setStopFlag",&plumedWantsToStop);
+     267         300 :       plumed->cmd("calc");
+     268             :       // if(istep%2000==0) plumed->cmd("writeCheckPointFile");
+     269         150 :       if(plumedWantsToStop) nsteps=istep;
+     270             : 
+     271             :       // Second step of velocity verlet
+     272         350 :       for(int j=0; j<nat; ++j) {
+     273         500 :         for(int k=0; k<3; ++k) {
+     274         450 :           if( 3*j+k>dim-1 ) break;
+     275         300 :           velocities[j][k] = velocities[j][k] + 0.5*tstep*forces[1+j][k];
+     276             :         }
+     277             :       }
+     278             : 
+     279             :       // Langevin thermostat
+     280         150 :       lscale=std::exp(-0.5*tstep/friction);
+     281         150 :       lrand=std::sqrt((1.-lscale*lscale)*temp);
+     282         350 :       for(int j=0; j<nat; ++j) {
+     283         500 :         for(int k=0; k<3; ++k) {
+     284         450 :           if( 3*j+k>dim-1) break;
+     285         300 :           therm_eng=therm_eng+0.5*velocities[j][k]*velocities[j][k];
+     286         300 :           velocities[j][k]=lscale*velocities[j][k]+lrand*random.Gaussian();
+     287         300 :           therm_eng=therm_eng-0.5*velocities[j][k]*velocities[j][k];
+     288             :         }
+     289             :       }
+     290             :       // Calculate total kinetic energy
+     291             :       tke=0;
+     292         350 :       for(int i=0; i<nat; ++i) {
+     293         500 :         for(int j=0; j<3; ++j) {
+     294         450 :           if( 3*i+j>dim-1 ) break;
+     295         300 :           tke += 0.5*velocities[i][j]*velocities[i][j];
+     296             :         }
+     297             :       }
+     298             : 
+     299             :       // Print everything
+     300             :       // conserved = potential+1.5*ttt+therm_eng;
+     301         150 :       if( pc.Get_rank()==0 ) std::fprintf(fp,"%i %f %f %f \n", istep, istep*tstep, tke, therm_eng );
+     302             :     }
+     303             : 
+     304           3 :     fclose(fp);
+     305             : 
+     306           3 :     return 0;
+     307           3 :   }
+     308             : };
+     309             : 
+     310       10426 : PLUMED_REGISTER_CLTOOL(PesMD,"pesmd")
+     311             : 
+     312             : }
+     313             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..4894df8fe7 --- /dev/null +++ b/coverage/colvar/Angle.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:383997.4 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5AngleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe916createERKNS_13ActionOptionsE18
_ZN4PLMD6colvar5AngleC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar5Angle16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD6colvar5Angle9calculateEv304
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe91C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe91D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Angle.cpp.func.html b/coverage/colvar/Angle.cpp.func.html new file mode 100644 index 0000000000..f6a59c0856 --- /dev/null +++ b/coverage/colvar/Angle.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:383997.4 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe916createERKNS_13ActionOptionsE18
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe91C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe91D2Ev3473
_ZN4PLMD6colvar5Angle16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD6colvar5Angle9calculateEv304
_ZN4PLMD6colvar5AngleC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar5AngleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Angle.cpp.gcov.html b/coverage/colvar/Angle.cpp.gcov.html new file mode 100644 index 0000000000..916a0f4664 --- /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:383997.4 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "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       10454 : PLUMED_REGISTER_ACTION(Angle,"ANGLE")
+      92             : 
+      93          19 : void Angle::registerKeywords( Keywords& keys ) {
+      94          19 :   Colvar::registerKeywords(keys);
+      95          38 :   keys.add("atoms","ATOMS","the list of atoms involved in this collective variable (either 3 or 4 atoms)");
+      96          19 : }
+      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           2 :   } 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          17 :   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         304 :   setAtomsDerivatives(2,-ddij);
+     139         304 :   setAtomsDerivatives(3,ddij);
+     140         304 :   setValue           (angle);
+     141         304 :   setBoxDerivativesNoPbc();
+     142         304 : }
+     143             : 
+     144             : }
+     145             : }
+     146             : 
+     147             : 
+     148             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..1f98062636 --- /dev/null +++ b/coverage/colvar/Cell.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4CellC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe586createERKNS_13ActionOptionsE9
_ZN4PLMD6colvar4CellC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar4Cell16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6colvar4Cell9calculateEv150
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe58C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe58D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Cell.cpp.func.html b/coverage/colvar/Cell.cpp.func.html new file mode 100644 index 0000000000..511a57f930 --- /dev/null +++ b/coverage/colvar/Cell.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe586createERKNS_13ActionOptionsE9
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe58C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe58D2Ev3473
_ZN4PLMD6colvar4Cell16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6colvar4Cell9calculateEv150
_ZN4PLMD6colvar4CellC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar4CellC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Cell.cpp.gcov.html b/coverage/colvar/Cell.cpp.gcov.html new file mode 100644 index 0000000000..cc17c21bdb --- /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:3636100.0 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "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       10437 : 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          10 : void Cell::registerKeywords( Keywords& keys ) {
+      79          10 :   Action::registerKeywords( keys );
+      80          10 :   ActionWithValue::registerKeywords( keys );
+      81          10 :   ActionAtomistic::registerKeywords( keys );
+      82          10 :   componentsAreNotOptional(keys);
+      83          20 :   keys.addOutputComponent("ax","default","the ax component of the cell matrix");
+      84          20 :   keys.addOutputComponent("ay","default","the ay component of the cell matrix");
+      85          20 :   keys.addOutputComponent("az","default","the az component of the cell matrix");
+      86          20 :   keys.addOutputComponent("bx","default","the bx component of the cell matrix");
+      87          20 :   keys.addOutputComponent("by","default","the by component of the cell matrix");
+      88          20 :   keys.addOutputComponent("bz","default","the bz component of the cell matrix");
+      89          20 :   keys.addOutputComponent("cx","default","the cx component of the cell matrix");
+      90          20 :   keys.addOutputComponent("cy","default","the cy component of the cell matrix");
+      91          20 :   keys.addOutputComponent("cz","default","the cz component of the cell matrix");
+      92          10 : }
+      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.15
+
+ + + 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 0000000000..f94ff93a52 --- /dev/null +++ b/coverage/colvar/Constant.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:434595.6 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8ConstantC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe696createERKNS_13ActionOptionsE39
_ZN4PLMD6colvar8ConstantC1ERKNS_13ActionOptionsE39
_ZN4PLMD6colvar8Constant16registerKeywordsERNS_8KeywordsE40
_ZN4PLMD6colvar8Constant9calculateEv3401
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe69C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe69D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Constant.cpp.func.html b/coverage/colvar/Constant.cpp.func.html new file mode 100644 index 0000000000..728dfb20cb --- /dev/null +++ b/coverage/colvar/Constant.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:434595.6 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe696createERKNS_13ActionOptionsE39
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe69C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe69D2Ev3473
_ZN4PLMD6colvar8Constant16registerKeywordsERNS_8KeywordsE40
_ZN4PLMD6colvar8Constant9calculateEv3401
_ZN4PLMD6colvar8ConstantC1ERKNS_13ActionOptionsE39
_ZN4PLMD6colvar8ConstantC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Constant.cpp.gcov.html b/coverage/colvar/Constant.cpp.gcov.html new file mode 100644 index 0000000000..797ac19a59 --- /dev/null +++ b/coverage/colvar/Constant.cpp.gcov.html @@ -0,0 +1,210 @@ + + + + + + + + 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:434595.6 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/Atoms.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30             : //+PLUMEDOC COLVAR CONSTANT
+      31             : /*
+      32             : Return one or more constant quantities with or without derivatives.
+      33             : 
+      34             : Useful in combination with functions that
+      35             : takes in input constants or parameters.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : The following input instructs plumed to compute the distance
+      40             : between atoms 1 and 2. If this distance is between 1.0 and 2.0, it is
+      41             : printed. If it is lower than 1.0 (larger than 2.0), 1.0 (2.0) is printed
+      42             : 
+      43             : \plumedfile
+      44             : cn: CONSTANT VALUES=1.0,2.0
+      45             : dis: DISTANCE ATOMS=1,2
+      46             : sss: SORT ARG=cn.v-0,dis,cn.v-1
+      47             : PRINT ARG=sss.2
+      48             : \endplumedfile
+      49             : 
+      50             : In case you want to pass a single value you can use VALUE:
+      51             : \plumedfile
+      52             : cn: CONSTANT VALUE=1.0
+      53             : dis: DISTANCE ATOMS=1,2
+      54             : sss: SORT ARG=cn,dis
+      55             : PRINT ARG=sss.1
+      56             : \endplumedfile
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : class Constant : public Colvar {
+      62             :   std::vector<double> values;
+      63             : public:
+      64             :   explicit Constant(const ActionOptions&);
+      65             :   void calculate() override;
+      66             :   static void registerKeywords( Keywords& keys );
+      67             : };
+      68             : 
+      69       10497 : PLUMED_REGISTER_ACTION(Constant,"CONSTANT")
+      70             : 
+      71          39 : Constant::Constant(const ActionOptions&ao):
+      72          39 :   PLUMED_COLVAR_INIT(ao)
+      73             : {
+      74          39 :   bool noderiv=false;
+      75          39 :   parseFlag("NODERIV",noderiv);
+      76          78 :   parseVector("VALUES",values);
+      77             :   std::vector<double> value;
+      78          78 :   parseVector("VALUE",value);
+      79          39 :   if(values.size()==0&&value.size()==0) error("One should use either VALUE or VALUES");
+      80          39 :   if(values.size()!=0&&value.size()!=0) error("One should use either VALUE or VALUES");
+      81          39 :   if(value.size()>1) error("VALUE cannot take more than one number");
+      82          39 :   if(values.size()==0) {
+      83          11 :     values.resize(1);
+      84          11 :     values[0]=value[0];
+      85             :   }
+      86          39 :   checkRead();
+      87          39 :   if(values.size()==1) {
+      88          38 :     if(!noderiv) addValueWithDerivatives();
+      89           0 :     else addValue();
+      90          38 :     setNotPeriodic();
+      91          38 :     setValue(values[0]);
+      92           1 :   } else if(values.size()>1) {
+      93           3 :     for(unsigned i=0; i<values.size(); i++) {
+      94           2 :       std::string num; Tools::convert(i,num);
+      95           4 :       if(!noderiv) addComponentWithDerivatives("v-"+num);
+      96           0 :       else addComponent("v-"+num);
+      97           2 :       componentIsNotPeriodic("v-"+num);
+      98           2 :       Value* comp=getPntrToComponent("v-"+num);
+      99           2 :       comp->set(values[i]);
+     100             :     }
+     101             :   }
+     102             : // fake request to avoid errors:
+     103             :   std::vector<AtomNumber> atoms;
+     104          39 :   requestAtoms(atoms);
+     105          39 : }
+     106             : 
+     107          40 : void Constant::registerKeywords( Keywords& keys ) {
+     108          40 :   Colvar::registerKeywords( keys );
+     109          40 :   componentsAreNotOptional(keys);
+     110          40 :   keys.remove("NUMERICAL_DERIVATIVES");
+     111          80 :   keys.add("optional","VALUES","The values of the constants");
+     112          80 :   keys.add("optional","VALUE","The value of the constant");
+     113          80 :   keys.addFlag("NODERIV",false,"Set to TRUE if you want values without derivatives.");
+     114          80 :   keys.addOutputComponent("v","default","the # value");
+     115          40 : }
+     116             : 
+     117             : // calculator
+     118        3401 : void Constant::calculate() {
+     119        3401 :   if(values.size()==1) {
+     120        3396 :     setValue(values[0]);
+     121        3396 :     return;
+     122             :   }
+     123          15 :   for(unsigned i=0; i<values.size(); i++) {
+     124          10 :     Value* comp=getPntrToComponent(i);
+     125          10 :     comp->set(values[i]);
+     126             :   }
+     127             : }
+     128             : 
+     129             : }
+     130             : }
+     131             : 
+     132             : 
+     133             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..82f545dea3 --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:12113291.7 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ContactMap18checkFieldsAllowedEv0
_ZN4PLMD6colvar10ContactMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar10ContactMapC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar12_GLOBAL__N_123ContactMapRegisterMe1186createERKNS_13ActionOptionsE8
_ZN4PLMD6colvar10ContactMap16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6colvar10ContactMap9calculateEv2215
_ZN4PLMD6colvar12_GLOBAL__N_123ContactMapRegisterMe118C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_123ContactMapRegisterMe118D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/ContactMap.cpp.func.html b/coverage/colvar/ContactMap.cpp.func.html new file mode 100644 index 0000000000..627c0a0ebb --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:12113291.7 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12CoordinationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12CoordinationC1ERKNS_13ActionOptionsE185
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe1056createERKNS_13ActionOptionsE185
_ZN4PLMD6colvar12Coordination16registerKeywordsERNS_8KeywordsE186
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe105C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe105D2Ev3473
_ZNK4PLMD6colvar12Coordination7pairingEdRdjj15263796
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.func.html b/coverage/colvar/Coordination.cpp.func.html new file mode 100644 index 0000000000..eea7396dd8 --- /dev/null +++ b/coverage/colvar/Coordination.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3030100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12Coordination16registerKeywordsERNS_8KeywordsE186
_ZN4PLMD6colvar12CoordinationC1ERKNS_13ActionOptionsE185
_ZN4PLMD6colvar12CoordinationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe1056createERKNS_13ActionOptionsE185
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe105C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe105D2Ev3473
_ZNK4PLMD6colvar12Coordination7pairingEdRdjj15263796
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.gcov.html b/coverage/colvar/Coordination.cpp.gcov.html new file mode 100644 index 0000000000..f87215f0df --- /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:3030100.0 %
Date:2024-06-10 08:19:14Functions: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 "CoordinationBase.h"
+      23             : #include "tools/SwitchingFunction.h"
+      24             : #include "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       10784 : PLUMED_REGISTER_ACTION(Coordination,"COORDINATION")
+     106             : 
+     107         186 : void Coordination::registerKeywords( Keywords& keys ) {
+     108         186 :   CoordinationBase::registerKeywords(keys);
+     109         372 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     110         372 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     111         372 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     112         372 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     113         372 :   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         186 : }
+     117             : 
+     118         185 : Coordination::Coordination(const ActionOptions&ao):
+     119             :   Action(ao),
+     120         185 :   CoordinationBase(ao)
+     121             : {
+     122             : 
+     123             :   std::string sw,errors;
+     124         370 :   parse("SWITCH",sw);
+     125         185 :   if(sw.length()>0) {
+     126         136 :     switchingFunction.set(sw,errors);
+     127         134 :     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         180 :   checkRead();
+     142             : 
+     143         365 :   log<<"  contacts are counted with cutoff "<<switchingFunction.description()<<"\n";
+     144         195 : }
+     145             : 
+     146    15263796 : double Coordination::pairing(double distance,double&dfunc,unsigned i,unsigned j)const {
+     147             :   (void) i; // avoid warnings
+     148             :   (void) j; // avoid warnings
+     149    15263796 :   return switchingFunction.calculateSqr(distance,dfunc);
+     150             : }
+     151             : 
+     152             : }
+     153             : 
+     154             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..4bccab0ceb --- /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-06-10 08:19:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16CoordinationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16CoordinationBaseD0Ev0
_ZN4PLMD6colvar16CoordinationBaseD1Ev0
_ZN4PLMD6colvar16CoordinationBaseC2ERKNS_13ActionOptionsE194
_ZN4PLMD6colvar16CoordinationBaseD2Ev194
_ZN4PLMD6colvar16CoordinationBase16registerKeywordsERNS_8KeywordsE197
_ZN4PLMD6colvar16CoordinationBase9calculateEv3132
_ZN4PLMD6colvar16CoordinationBase7prepareEv3357
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.func.html b/coverage/colvar/CoordinationBase.cpp.func.html new file mode 100644 index 0000000000..65a081e5c4 --- /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-06-10 08:19:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16CoordinationBase16registerKeywordsERNS_8KeywordsE197
_ZN4PLMD6colvar16CoordinationBase7prepareEv3357
_ZN4PLMD6colvar16CoordinationBase9calculateEv3132
_ZN4PLMD6colvar16CoordinationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16CoordinationBaseC2ERKNS_13ActionOptionsE194
_ZN4PLMD6colvar16CoordinationBaseD0Ev0
_ZN4PLMD6colvar16CoordinationBaseD1Ev0
_ZN4PLMD6colvar16CoordinationBaseD2Ev194
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.gcov.html b/coverage/colvar/CoordinationBase.cpp.gcov.html new file mode 100644 index 0000000000..e1e1e68409 --- /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-06-10 08:19:14Functions: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         194 : CoordinationBase::CoordinationBase(const ActionOptions&ao):
+      42             :   PLUMED_COLVAR_INIT(ao),
+      43         194 :   pbc(true),
+      44         194 :   serial(false),
+      45         194 :   invalidateList(true),
+      46         194 :   firsttime(true)
+      47             : {
+      48             : 
+      49         388 :   parseFlag("SERIAL",serial);
+      50             : 
+      51             :   std::vector<AtomNumber> ga_lista,gb_lista;
+      52         194 :   parseAtomList("GROUPA",ga_lista);
+      53         194 :   parseAtomList("GROUPB",gb_lista);
+      54             : 
+      55         194 :   bool nopbc=!pbc;
+      56         194 :   parseFlag("NOPBC",nopbc);
+      57         194 :   pbc=!nopbc;
+      58             : 
+      59             : // pair stuff
+      60         194 :   bool dopair=false;
+      61         194 :   parseFlag("PAIR",dopair);
+      62             : 
+      63             : // neighbor list stuff
+      64         194 :   bool doneigh=false;
+      65         194 :   double nl_cut=0.0;
+      66         194 :   int nl_st=0;
+      67         194 :   parseFlag("NLIST",doneigh);
+      68         194 :   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         194 :   addValueWithDerivatives(); setNotPeriodic();
+      76         194 :   if(gb_lista.size()>0) {
+      77         207 :     if(doneigh)  nl=Tools::make_unique<NeighborList>(ga_lista,gb_lista,serial,dopair,pbc,getPbc(),comm,nl_cut,nl_st);
+      78         318 :     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         194 :   requestAtoms(nl->getFullAtomList());
+      85             : 
+      86         194 :   log.printf("  between two groups of %u and %u atoms\n",static_cast<unsigned>(ga_lista.size()),static_cast<unsigned>(gb_lista.size()));
+      87         194 :   log.printf("  first group:\n");
+      88        5465 :   for(unsigned int i=0; i<ga_lista.size(); ++i) {
+      89        5271 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      90        5271 :     log.printf("  %d", ga_lista[i].serial());
+      91             :   }
+      92         194 :   log.printf("  \n  second group:\n");
+      93       10817 :   for(unsigned int i=0; i<gb_lista.size(); ++i) {
+      94       10623 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      95       10623 :     log.printf("  %d", gb_lista[i].serial());
+      96             :   }
+      97         194 :   log.printf("  \n");
+      98         194 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+      99           0 :   else    log.printf("  without periodic boundary conditions\n");
+     100         194 :   if(dopair) log.printf("  with PAIR option\n");
+     101         194 :   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         194 : }
+     106             : 
+     107         194 : CoordinationBase::~CoordinationBase() {
+     108             : // destructor required to delete forward declared class
+     109         194 : }
+     110             : 
+     111        3357 : void CoordinationBase::prepare() {
+     112        3357 :   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        3357 : }
+     125             : 
+     126             : // calculator
+     127        3132 : void CoordinationBase::calculate()
+     128             : {
+     129             : 
+     130        3132 :   double ncoord=0.;
+     131        3132 :   Tensor virial;
+     132        3132 :   std::vector<Vector> deriv(getNumberOfAtoms());
+     133             : 
+     134        3132 :   if(nl->getStride()>0 && invalidateList) {
+     135         143 :     nl->update(getPositions());
+     136             :   }
+     137             : 
+     138             :   unsigned stride;
+     139             :   unsigned rank;
+     140        3132 :   if(serial) {
+     141             :     stride=1;
+     142             :     rank=0;
+     143             :   } else {
+     144        3132 :     stride=comm.Get_size();
+     145        3132 :     rank=comm.Get_rank();
+     146             :   }
+     147             : 
+     148        3132 :   unsigned nt=OpenMP::getNumThreads();
+     149        3132 :   const unsigned nn=nl->size();
+     150        3132 :   if(nt*stride*10>nn) nt=1;
+     151             : 
+     152        3132 :   #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        3132 :   if(!serial) {
+     196        3132 :     comm.Sum(ncoord);
+     197        3132 :     if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size());
+     198        3132 :     comm.Sum(virial);
+     199             :   }
+     200             : 
+     201      378180 :   for(unsigned i=0; i<deriv.size(); ++i) setAtomsDerivatives(i,deriv[i]);
+     202        3132 :   setValue           (ncoord);
+     203        3132 :   setBoxDerivatives  (virial);
+     204             : 
+     205        3132 : }
+     206             : }
+     207             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9b66296033 --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:323494.1 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8DHEnergyC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe756createERKNS_13ActionOptionsE8
_ZN4PLMD6colvar8DHEnergyC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar8DHEnergy16registerKeywordsERNS_8KeywordsE9
_ZNK4PLMD6colvar8DHEnergy7pairingEdRdjj840
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe75C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe75D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/DHEnergy.cpp.func.html b/coverage/colvar/DHEnergy.cpp.func.html new file mode 100644 index 0000000000..7966b2b647 --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:323494.1 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe756createERKNS_13ActionOptionsE8
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe75C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe75D2Ev3473
_ZN4PLMD6colvar8DHEnergy16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6colvar8DHEnergyC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar8DHEnergyC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar8DHEnergy7pairingEdRdjj840
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/DHEnergy.cpp.gcov.html b/coverage/colvar/DHEnergy.cpp.gcov.html new file mode 100644 index 0000000000..5541f638ac --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.gcov.html @@ -0,0 +1,221 @@ + + + + + + + + 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:323494.1 %
Date:2024-06-10 08:19:14Functions: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 "CoordinationBase.h"
+      23             : #include "tools/SwitchingFunction.h"
+      24             : #include "ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Atoms.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace colvar {
+      30             : 
+      31             : //+PLUMEDOC COLVAR DHENERGY
+      32             : /*
+      33             : Calculate Debye-Huckel interaction energy among GROUPA and GROUPB.
+      34             : 
+      35             : This variable calculates the electrostatic interaction among GROUPA and GROUPB
+      36             : using a Debye-Huckel approximation defined as
+      37             : \f[
+      38             : \frac{1}{4\pi\epsilon_r\epsilon_0}
+      39             : \sum_{i\in A} \sum_{j \in B} q_i q_j
+      40             : \frac{e^{-\kappa |{\bf r}_{ij}|}}{|{\bf r}_{ij}|}
+      41             : \f]
+      42             : 
+      43             : This collective variable can be used to analyze or induce electrostatically driven reactions \cite do13jctc.
+      44             : Notice that the value of the DHENERGY is returned in plumed units (see \ref UNITS).
+      45             : 
+      46             : If GROUPB is empty, it will sum the N*(N-1)/2 pairs in GROUPA. This avoids computing
+      47             : twice permuted indexes (e.g. pair (i,j) and (j,i)) thus running at twice the speed.
+      48             : 
+      49             : Notice that if there are common atoms between GROUPA and GROUPB their interaction is discarded.
+      50             : 
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : \plumedfile
+      55             : # this is printing the electrostatic interaction between two groups of atoms
+      56             : dh: DHENERGY GROUPA=1-10 GROUPB=11-20 EPSILON=80.0 I=0.1 TEMP=300.0
+      57             : PRINT ARG=dh
+      58             : \endplumedfile
+      59             : 
+      60             : */
+      61             : //+ENDPLUMEDOC
+      62             : 
+      63             : class DHEnergy : public CoordinationBase {
+      64             :   double k; // Inverse Debye screening length
+      65             :   double constant;
+      66             :   double epsilon;
+      67             : 
+      68             : public:
+      69             :   explicit DHEnergy(const ActionOptions&);
+      70             : // active methods:
+      71             :   static void registerKeywords( Keywords& keys );
+      72             :   double pairing(double distance,double&dfunc,unsigned i,unsigned j)const override;
+      73             : };
+      74             : 
+      75       10435 : PLUMED_REGISTER_ACTION(DHEnergy,"DHENERGY")
+      76             : 
+      77           9 : void DHEnergy::registerKeywords( Keywords& keys ) {
+      78           9 :   CoordinationBase::registerKeywords(keys);
+      79          18 :   keys.add("compulsory","I","1.0","Ionic strength (M)");
+      80          18 :   keys.add("compulsory","TEMP","300.0","Simulation temperature (K)");
+      81          18 :   keys.add("compulsory","EPSILON","80.0","Dielectric constant of solvent");
+      82           9 : }
+      83             : 
+      84             : /*
+      85             : Global constants in SI unit used in this calculation:
+      86             :       N_A = 6.0221412927 * 10^(23) mol^(-1) : Avogadro number
+      87             :       q = 1.60217656535 * 10^(-19) C : proton charge
+      88             :       e_0 = 8.854187817620 * 10^(-12) C^2/(N*m^2) : vacuum's dielectric constant
+      89             :       k_B = 1.380648813 * 10^(-23) N*m/K : Boltzmann constant
+      90             : In SI unit, Debye Huckel CV is defined as:
+      91             :       DHen = \sum_i\sum_j (q_i*q_j*q^2*N_A)/(4*pi*eps*e_0) * exp(-k*|f_ij|)/(|f_ij|)
+      92             :              + \sum_i\sum_j (q_i*q_j*q^2*N_A)/(4*pi*epp*e_0) * (1/|r_ij| - 1/|f_ij|)
+      93             :            = (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|))
+      94             : (in which |f_ij| = \sqrt(|r_ij|^2+\sigma_i*\sigma_j*exp(-|r_ij|^2/4*\sigma_i*\sigma_j)),
+      95             :  \sigma_i and \sigma_j are the effective Born radius.)
+      96             : For an efficient calculation, we group constants and variables into groups:
+      97             :       constant = (q^2*N_A)/(4*pi*e_0)
+      98             :       tmp = 1/eps*exp(-k*|f_ij|)/(|f_ij|) + 1/epp*(1/|r_ij| - 1/|f_ij|)
+      99             : 
+     100             : To speed up the loop calculation, constant can be modified as followed:
+     101             :       constant= (q^2*N_A)/(4*pi*e_0*10^(-9))*10^(-3) (kJ/mol)
+     102             :               = ((1.60217656535*10^(-19))^2*6.0221412927*10^(23)*10^(-3))/(4*3.14159265*8.854187817620*10^(-12)*10^(-9))
+     103             :               = 138.935458111 (kJ/mol)
+     104             : 
+     105             : */
+     106             : 
+     107           8 : DHEnergy::DHEnergy(const ActionOptions&ao):
+     108             :   Action(ao),
+     109             :   CoordinationBase(ao),
+     110           8 :   k(0.0),
+     111           8 :   constant(0.0)
+     112             : {
+     113             :   double I,T;
+     114           8 :   parse("I",I);
+     115           8 :   parse("TEMP",T);
+     116           8 :   parse("EPSILON",epsilon);
+     117           8 :   checkRead();
+     118           8 :   if( plumed.getAtoms().usingNaturalUnits() ) error("DHENERGY cannot be used for calculations performed with natural units");
+     119           8 :   constant=138.935458111/atoms.getUnits().getEnergy()/atoms.getUnits().getLength()*atoms.getUnits().getCharge()*atoms.getUnits().getCharge();
+     120           8 :   k=std::sqrt(I/(epsilon*T))*502.903741125*atoms.getUnits().getLength();
+     121           8 :   checkRead();
+     122           8 :   log<<"  with solvent dielectric constant "<<epsilon<<"\n";
+     123           8 :   log<<"  at temperature "<<T<<" K\n";
+     124           8 :   log<<"  at ionic strength "<<I<< "M\n";
+     125           8 :   log<<"  these parameters correspond to a screening length of "<<(1.0/k)<<"\n";
+     126          16 :   log<<"  Bibliography "<<plumed.cite("Do, Carloni, Varani and Bussi, J. Chem. Theory Comput. 9, 1720 (2013)")<<" \n";
+     127           8 : }
+     128             : 
+     129         840 : double DHEnergy::pairing(double distance2,double&dfunc,unsigned i,unsigned j)const {
+     130         840 :   double distance=std::sqrt(distance2);
+     131         840 :   if(getAbsoluteIndex(i)==getAbsoluteIndex(j)) {
+     132           0 :     dfunc=0.0;
+     133           0 :     return 0.0;
+     134             :   }
+     135         840 :   double invdistance=1.0/distance;
+     136         840 :   double tmp=std::exp(-k*distance)*invdistance*constant*getCharge(i)*getCharge(j)/epsilon;
+     137         840 :   double dtmp=-(k+invdistance)*tmp;
+     138         840 :   dfunc=dtmp*invdistance;
+     139         840 :   return tmp;
+     140             : }
+     141             : 
+     142             : }
+     143             : 
+     144             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..61c46eab1c --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4444100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118DRMSDRegisterMe1226createERKNS_13ActionOptionsE12
_ZN4PLMD6colvar5DRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD6colvar5DRMSD16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD6colvar5DRMSD9calculateEv595
_ZN4PLMD6colvar12_GLOBAL__N_118DRMSDRegisterMe122C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118DRMSDRegisterMe122D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.func.html b/coverage/colvar/DRMSD.cpp.func.html new file mode 100644 index 0000000000..3fe83349c7 --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4444100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DimerC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe1436createERKNS_13ActionOptionsE2
_ZN4PLMD6colvar5Dimer16consistencyCheckEv2
_ZN4PLMD6colvar5DimerC1ERKNS_13ActionOptionsE2
_ZN4PLMD6colvar5Dimer16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar5Dimer9calculateEv4
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe143C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe143D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Dimer.cpp.func.html b/coverage/colvar/Dimer.cpp.func.html new file mode 100644 index 0000000000..b44cc9d8b0 --- /dev/null +++ b/coverage/colvar/Dimer.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:839092.2 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe1436createERKNS_13ActionOptionsE2
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe143C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe143D2Ev3473
_ZN4PLMD6colvar5Dimer16consistencyCheckEv2
_ZN4PLMD6colvar5Dimer16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar5Dimer9calculateEv4
_ZN4PLMD6colvar5DimerC1ERKNS_13ActionOptionsE2
_ZN4PLMD6colvar5DimerC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Dimer.cpp.gcov.html b/coverage/colvar/Dimer.cpp.gcov.html new file mode 100644 index 0000000000..8a170ec91a --- /dev/null +++ b/coverage/colvar/Dimer.cpp.gcov.html @@ -0,0 +1,394 @@ + + + + + + + + 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:839092.2 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6DipoleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe716createERKNS_13ActionOptionsE53
_ZN4PLMD6colvar6DipoleC1ERKNS_13ActionOptionsE53
_ZN4PLMD6colvar6Dipole16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD6colvar6Dipole9calculateEv918
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe71C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe71D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.func.html b/coverage/colvar/Dipole.cpp.func.html new file mode 100644 index 0000000000..091ce4972b --- /dev/null +++ b/coverage/colvar/Dipole.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:6161100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe716createERKNS_13ActionOptionsE53
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe71C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe71D2Ev3473
_ZN4PLMD6colvar6Dipole16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD6colvar6Dipole9calculateEv918
_ZN4PLMD6colvar6DipoleC1ERKNS_13ActionOptionsE53
_ZN4PLMD6colvar6DipoleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.gcov.html b/coverage/colvar/Dipole.cpp.gcov.html new file mode 100644 index 0000000000..2da27c04ff --- /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:6161100.0 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "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       10525 : PLUMED_REGISTER_ACTION(Dipole,"DIPOLE")
+      72             : 
+      73          54 : void Dipole::registerKeywords(Keywords& keys) {
+      74          54 :   Colvar::registerKeywords(keys);
+      75         108 :   keys.add("atoms","GROUP","the group of atoms we are calculating the dipole moment for");
+      76         108 :   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         108 :   keys.addOutputComponent("x","COMPONENTS","the x-component of the dipole");
+      78         108 :   keys.addOutputComponent("y","COMPONENTS","the y-component of the dipole");
+      79         108 :   keys.addOutputComponent("z","COMPONENTS","the z-component of the dipole");
+      80          54 : }
+      81             : 
+      82          53 : Dipole::Dipole(const ActionOptions&ao):
+      83             :   PLUMED_COLVAR_INIT(ao),
+      84          53 :   components(false)
+      85             : {
+      86          53 :   parseAtomList("GROUP",ga_lista);
+      87          53 :   parseFlag("COMPONENTS",components);
+      88          53 :   parseFlag("NOPBC",nopbc);
+      89          53 :   checkRead();
+      90          53 :   if(components) {
+      91           4 :     addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+      92           4 :     addComponentWithDerivatives("y"); componentIsNotPeriodic("y");
+      93           6 :     addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+      94             :   } else {
+      95          51 :     addValueWithDerivatives(); setNotPeriodic();
+      96             :   }
+      97             : 
+      98          53 :   log.printf("  of %u atoms\n",static_cast<unsigned>(ga_lista.size()));
+      99         376 :   for(unsigned int i=0; i<ga_lista.size(); ++i) {
+     100         323 :     log.printf("  %d", ga_lista[i].serial());
+     101             :   }
+     102          53 :   log.printf("  \n");
+     103          53 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     104          15 :   else      log.printf("  using periodic boundary conditions\n");
+     105             : 
+     106          53 :   requestAtoms(ga_lista);
+     107          53 : }
+     108             : 
+     109             : // calculator
+     110         918 : void Dipole::calculate()
+     111             : {
+     112         918 :   if(!nopbc) makeWhole();
+     113             :   double ctot=0.;
+     114             :   unsigned N=getNumberOfAtoms();
+     115         918 :   std::vector<double> charges(N);
+     116         918 :   Vector dipje;
+     117             : 
+     118        7243 :   for(unsigned i=0; i<N; ++i) {
+     119        6325 :     charges[i]=getCharge(i);
+     120        6325 :     ctot+=charges[i];
+     121             :   }
+     122         918 :   ctot/=(double)N;
+     123             : 
+     124        7243 :   for(unsigned i=0; i<N; ++i) {
+     125        6325 :     charges[i]-=ctot;
+     126        6325 :     dipje += charges[i]*getPosition(i);
+     127             :   }
+     128             : 
+     129         918 :   if(!components) {
+     130         773 :     double dipole = dipje.modulo();
+     131         773 :     double idip = 1./dipole;
+     132             : 
+     133        6228 :     for(unsigned i=0; i<N; i++) {
+     134        5455 :       double dfunc=charges[i]*idip;
+     135        5455 :       setAtomsDerivatives(i,dfunc*dipje);
+     136             :     }
+     137         773 :     setBoxDerivativesNoPbc();
+     138         773 :     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         918 : }
+     156             : 
+     157             : }
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e80ed22326 --- /dev/null +++ b/coverage/colvar/Distance.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:8282100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8DistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe1186createERKNS_13ActionOptionsE455
_ZN4PLMD6colvar8DistanceC1ERKNS_13ActionOptionsE455
_ZN4PLMD6colvar8Distance16registerKeywordsERNS_8KeywordsE456
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe118C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe118D2Ev3473
_ZN4PLMD6colvar8Distance9calculateEv42339
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Distance.cpp.func.html b/coverage/colvar/Distance.cpp.func.html new file mode 100644 index 0000000000..823d6f4697 --- /dev/null +++ b/coverage/colvar/Distance.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:8282100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe1186createERKNS_13ActionOptionsE455
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe118C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe118D2Ev3473
_ZN4PLMD6colvar8Distance16registerKeywordsERNS_8KeywordsE456
_ZN4PLMD6colvar8Distance9calculateEv42339
_ZN4PLMD6colvar8DistanceC1ERKNS_13ActionOptionsE455
_ZN4PLMD6colvar8DistanceC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Distance.cpp.gcov.html b/coverage/colvar/Distance.cpp.gcov.html new file mode 100644 index 0000000000..a741afac97 --- /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:8282100.0 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "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       11327 : PLUMED_REGISTER_ACTION(Distance,"DISTANCE")
+     119             : 
+     120         456 : void Distance::registerKeywords( Keywords& keys ) {
+     121         456 :   Colvar::registerKeywords( keys );
+     122         912 :   keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
+     123         912 :   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         912 :   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         912 :   keys.addOutputComponent("x","COMPONENTS","the x-component of the vector connecting the two atoms");
+     126         912 :   keys.addOutputComponent("y","COMPONENTS","the y-component of the vector connecting the two atoms");
+     127         912 :   keys.addOutputComponent("z","COMPONENTS","the z-component of the vector connecting the two atoms");
+     128        1368 :   keys.addOutputComponent("a","SCALED_COMPONENTS","the normalized projection on the first lattice vector of the vector connecting the two atoms");
+     129        1368 :   keys.addOutputComponent("b","SCALED_COMPONENTS","the normalized projection on the second lattice vector of the vector connecting the two atoms");
+     130        1368 :   keys.addOutputComponent("c","SCALED_COMPONENTS","the normalized projection on the third lattice vector of the vector connecting the two atoms");
+     131         456 : }
+     132             : 
+     133         455 : Distance::Distance(const ActionOptions&ao):
+     134             :   PLUMED_COLVAR_INIT(ao),
+     135         455 :   components(false),
+     136         455 :   scaled_components(false),
+     137         455 :   pbc(true)
+     138             : {
+     139             :   std::vector<AtomNumber> atoms;
+     140         910 :   parseAtomList("ATOMS",atoms);
+     141         455 :   if(atoms.size()!=2)
+     142           1 :     error("Number of specified atoms should be 2");
+     143         454 :   parseFlag("COMPONENTS",components);
+     144         454 :   parseFlag("SCALED_COMPONENTS",scaled_components);
+     145         454 :   bool nopbc=!pbc;
+     146         454 :   parseFlag("NOPBC",nopbc);
+     147         454 :   pbc=!nopbc;
+     148         454 :   checkRead();
+     149             : 
+     150         454 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+     151         454 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     152           4 :   else    log.printf("  without periodic boundary conditions\n");
+     153             : 
+     154         454 :   if(components && scaled_components) error("COMPONENTS and SCALED_COMPONENTS are not compatible");
+     155             : 
+     156         453 :   if(components) {
+     157          62 :     addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+     158          62 :     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         422 :   } 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           8 :     addComponentWithDerivatives("c"); componentIsPeriodic("c","-0.5","+0.5");
+     165             :   } else {
+     166         420 :     addValueWithDerivatives(); setNotPeriodic();
+     167             :   }
+     168             : 
+     169             : 
+     170         453 :   requestAtoms(atoms);
+     171         457 : }
+     172             : 
+     173             : 
+     174             : // calculator
+     175       42339 : void Distance::calculate() {
+     176             : 
+     177       42339 :   if(pbc) makeWhole();
+     178             : 
+     179       42339 :   Vector distance=delta(getPosition(0),getPosition(1));
+     180       42339 :   const double value=distance.modulo();
+     181       42339 :   const double invvalue=1.0/value;
+     182             : 
+     183       42339 :   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       41945 :   } 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       41934 :     setAtomsDerivatives(0,-invvalue*distance);
+     218       41934 :     setAtomsDerivatives(1,invvalue*distance);
+     219       41934 :     setBoxDerivativesNoPbc();
+     220       41934 :     setValue           (value);
+     221             :   }
+     222             : 
+     223       42339 : }
+     224             : 
+     225             : }
+     226             : }
+     227             : 
+     228             : 
+     229             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e329868e5b --- /dev/null +++ b/coverage/colvar/EEFSolv.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:11412889.1 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7EEFSolvC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120EEFSolvRegisterMe1026createERKNS_13ActionOptionsE5
_ZN4PLMD6colvar7EEFSolv12setupTypeMapB5cxx11Ev5
_ZN4PLMD6colvar7EEFSolv13setupValueMapB5cxx11Ev5
_ZN4PLMD6colvar7EEFSolv14setupConstantsERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IdSaIdEESaIS9_EEb5
_ZN4PLMD6colvar7EEFSolvC1ERKNS_13ActionOptionsE5
_ZN4PLMD6colvar7EEFSolv16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6colvar7EEFSolv13update_neighbEv30
_ZN4PLMD6colvar7EEFSolv9calculateEv30
_ZN4PLMD6colvar12_GLOBAL__N_120EEFSolvRegisterMe102C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120EEFSolvRegisterMe102D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/EEFSolv.cpp.func.html b/coverage/colvar/EEFSolv.cpp.func.html new file mode 100644 index 0000000000..8705c3f9f5 --- /dev/null +++ b/coverage/colvar/EEFSolv.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:11412889.1 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5ERMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe1166createERKNS_13ActionOptionsE4
_ZN4PLMD6colvar5ERMSDC1ERKNS_13ActionOptionsE4
_ZN4PLMD6colvar5ERMSD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar5ERMSD9calculateEv222
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe116C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe116D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/ERMSD.cpp.func.html b/coverage/colvar/ERMSD.cpp.func.html new file mode 100644 index 0000000000..432a248c7c --- /dev/null +++ b/coverage/colvar/ERMSD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:515298.1 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe1166createERKNS_13ActionOptionsE4
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe116C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe116D2Ev3473
_ZN4PLMD6colvar5ERMSD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar5ERMSD9calculateEv222
_ZN4PLMD6colvar5ERMSDC1ERKNS_13ActionOptionsE4
_ZN4PLMD6colvar5ERMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/ERMSD.cpp.gcov.html b/coverage/colvar/ERMSD.cpp.gcov.html new file mode 100644 index 0000000000..384ada3b5d --- /dev/null +++ b/coverage/colvar/ERMSD.cpp.gcov.html @@ -0,0 +1,292 @@ + + + + + + + + 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:515298.1 %
Date:2024-06-10 08:19:14Functions: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             : 
+      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 "ActionRegister.h"
+      31             : #include "tools/PDB.h"
+      32             : #include "tools/ERMSD.h"
+      33             : #include "core/Atoms.h"
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace colvar {
+      37             : 
+      38             : 
+      39             : //+PLUMEDOC COLVAR ERMSD
+      40             : /*
+      41             : Calculate eRMSD with respect to a reference structure.
+      42             : 
+      43             : eRMSD is a metric developed for measuring distances between three-dimensional RNA structures.
+      44             : The standard RMSD measure is highly inaccurate when measuring distances among three-dimensional
+      45             : structures of nucleic acids.
+      46             : 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.
+      47             : 
+      48             : 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:
+      49             : 
+      50             : 1. Set up a local reference system in the center of the six-membered ring of each nucleobase in a molecule.
+      51             :    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$.
+      52             : 
+      53             : 2. Calculate all pairwise distance vectors \f$\vec{r}_{i,j}\f$ among base centers.
+      54             : 
+      55             : 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.
+      56             : 
+      57             : 4. Calculate the G vectors
+      58             : 
+      59             : \f[
+      60             : \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
+      61             : \frac{\Theta(\tilde{r}_{cutoff}-\tilde{r})}{\gamma}
+      62             : \f]
+      63             : 
+      64             : 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.
+      65             : 
+      66             : 5. The eRMSD between two structures \f$ \alpha \f$ and \f$ \beta \f$ reads
+      67             : 
+      68             : \f[
+      69             : 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 }
+      70             : \f]
+      71             : 
+      72             : 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
+      73             : 
+      74             : ERMSD is computed using the position of three atoms on the 6-membered ring of each involved nucleobase. The atoms should be:
+      75             : - C2,C4,C6 for pyrimdines
+      76             : - C2,C6,C4 for purines
+      77             : 
+      78             : The different order for purines and pyrimidines is fundamental and allows you to compute ERMSD between structures with different
+      79             : sequences as well! Notice that the simplest way to avoid mistakes in choosing these atoms is to use the `@lcs-#` strings
+      80             : as shown in the examples (see also \ref MOLINFO).
+      81             : 
+      82             : \warning Notice that the ERMSD implemented here is not integrated with the other metrics in plumed. As a consequence, it is not (yet) possible
+      83             : to e.g. build path collective variables using ERMSD
+      84             : 
+      85             : \warning Notice that ERMSD expect a single molecule and makes coordinate whole before anything else. As such, results might be unexpected
+      86             : for a multi molecular system.
+      87             : 
+      88             : \par Examples
+      89             : 
+      90             : 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
+      91             : considering residues 1,2,3,4,5,6.
+      92             : 
+      93             : \plumedfile
+      94             : #SETTINGS MOLFILE=regtest/basic/rt-ermsd/ref.pdb
+      95             : MOLINFO STRUCTURE=reference.pdb
+      96             : eRMSD1: ERMSD REFERENCE=reference.pdb ATOMS=@lcs-1,@lcs-2,@lcs-3,@lcs-4,@lcs-5,@lcs-6
+      97             : \endplumedfile
+      98             : 
+      99             : */
+     100             : //+ENDPLUMEDOC
+     101             : 
+     102             : 
+     103             : class ERMSD : public Colvar {
+     104             : 
+     105             : 
+     106             :   std::vector<Vector> derivs;
+     107             :   PLMD::ERMSD ermsd;
+     108             :   bool pbc;
+     109             : 
+     110             : public:
+     111             :   explicit ERMSD(const ActionOptions&);
+     112             :   void calculate() override;
+     113             :   static void registerKeywords(Keywords& keys);
+     114             : };
+     115             : 
+     116       10427 : PLUMED_REGISTER_ACTION(ERMSD,"ERMSD")
+     117             : 
+     118           5 : void ERMSD::registerKeywords(Keywords& keys) {
+     119           5 :   Colvar::registerKeywords(keys);
+     120             : 
+     121          10 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     122          10 :   keys.add("compulsory","CUTOFF","2.4","only pairs of atoms closer than CUTOFF are considered in the calculation.");
+     123          10 :   keys.add("atoms","ATOMS","the list of atoms (use lcs)");
+     124          10 :   keys.add("optional","PAIRS","List of pairs considered. All pairs are considered if this value is not specified.");
+     125             : 
+     126           5 : }
+     127             : 
+     128           4 : ERMSD::ERMSD(const ActionOptions&ao):
+     129           4 :   PLUMED_COLVAR_INIT(ao), pbc(true)
+     130             : {
+     131             :   std::string reference;
+     132           4 :   parse("REFERENCE",reference);
+     133           4 :   double cutoff=2.4;
+     134           4 :   parse("CUTOFF",cutoff);
+     135             : 
+     136             : 
+     137           4 :   bool nopbc(false);
+     138           4 :   parseFlag("NOPBC",nopbc);
+     139           4 :   pbc=!nopbc;
+     140             : 
+     141             :   std::vector<AtomNumber> atoms_;
+     142           8 :   parseAtomList("ATOMS",atoms_);
+     143             : 
+     144             :   std::vector<unsigned> pairs_;
+     145           4 :   parseVector("PAIRS",pairs_);
+     146           4 :   checkRead();
+     147             : 
+     148           4 :   addValueWithDerivatives(); setNotPeriodic();
+     149             : 
+     150           4 :   if(atoms_.size()<6) error("at least six atoms should be specified");
+     151           4 :   if(atoms_.size()%3!=0) error("Atoms are not multiple of 3");
+     152           4 :   if(pairs_.size()%2!=0) error("pairs are not multiple of 2");
+     153             : 
+     154             : 
+     155             :   //checkRead();
+     156             :   //log.printf("  of atoms");
+     157             :   //for(unsigned i=0;i<atoms.size();++i) log.printf(" %d",atoms[i].serial());
+     158             :   //requestAtoms(atoms);
+     159             : 
+     160             :   // read everything in ang and transform to nm if we are not in natural units
+     161           4 :   PDB pdb;
+     162           8 :   if( !pdb.read(reference,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength()) )
+     163           0 :     error("missing input file " + reference );
+     164             :   // store target_ distance
+     165             :   std::vector <Vector> reference_positions;
+     166           4 :   unsigned natoms = atoms_.size();
+     167           4 :   log.printf("Read %u atoms\n",natoms);
+     168             : 
+     169           4 :   reference_positions.resize(natoms);
+     170         856 :   for(unsigned i=0; i<natoms; i++) {
+     171         852 :     reference_positions[i] = pdb.getPosition(atoms_[i]);
+     172             :     //log.printf("%f %f %f \n",reference_positions[i][0],reference_positions[i][1],reference_positions[i][2]);
+     173             :   }
+     174             : 
+     175             : // shift to count from zero
+     176          28 :   for(unsigned i=0; i<pairs_.size(); ++i) pairs_[i]--;
+     177             : 
+     178           4 :   ermsd.setReference(reference_positions,pairs_,cutoff/atoms.getUnits().getLength());
+     179             : 
+     180           4 :   requestAtoms(atoms_);
+     181           4 :   derivs.resize(natoms);
+     182             : 
+     183           4 :   log.printf("  reference from file %s\n",reference.c_str());
+     184           4 :   log.printf("  which contains %u atoms\n",natoms);
+     185             : 
+     186           4 :   log<<"  Bibliography "
+     187          12 :      <<plumed.cite("Bottaro, Di Palma, and Bussi, Nucleic Acids Res. 42, 13306 (2014)")
+     188          16 :      <<plumed.cite("Bottaro, Banas, Sponer, and Bussi, J. Phys. Chem. Lett. 7, 4032 (2016)")<<"\n";
+     189             : 
+     190           8 : }
+     191             : 
+     192             : // calculator
+     193         222 : void ERMSD::calculate() {
+     194             : // set derivatives to zero
+     195       47508 :   for(unsigned i=0; i<derivs.size(); ++i) {derivs[i].zero();}
+     196             :   double ermsdist;
+     197         222 :   Tensor virial;
+     198             : // This is a trick to avoid explicit virial calculation
+     199             : // 1. we make the molecule whole
+     200         222 :   makeWhole();
+     201             : // 2. we ignore pbcs
+     202         222 :   Pbc fake_pbc;
+     203             : // Notice that this might have problems when having 2 RNA molecules (hybridization).
+     204             : 
+     205         222 :   ermsdist=ermsd.calculate(getPositions(),fake_pbc,derivs,virial);
+     206         222 :   const double scale=atoms.getUnits().getLength();
+     207         222 :   setValue(ermsdist*scale);
+     208             : 
+     209       47508 :   for(unsigned i=0; i<derivs.size(); ++i) {setAtomsDerivatives(i,derivs[i]*scale);}
+     210             : 
+     211         222 :   setBoxDerivativesNoPbc();
+     212         222 : }
+     213             : 
+     214             : }
+     215             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..22ed46d1cd --- /dev/null +++ b/coverage/colvar/Energy.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6EnergyC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar6Energy22getNumberOfDerivativesEv2
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe756createERKNS_13ActionOptionsE40
_ZN4PLMD6colvar6EnergyC1ERKNS_13ActionOptionsE40
_ZN4PLMD6colvar6Energy16registerKeywordsERNS_8KeywordsE41
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe75C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe75D2Ev3473
_ZN4PLMD6colvar6Energy7prepareEv3989
_ZN4PLMD6colvar6Energy9calculateEv3989
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Energy.cpp.func.html b/coverage/colvar/Energy.cpp.func.html new file mode 100644 index 0000000000..ec2176aa33 --- /dev/null +++ b/coverage/colvar/Energy.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe756createERKNS_13ActionOptionsE40
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe75C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe75D2Ev3473
_ZN4PLMD6colvar6Energy16registerKeywordsERNS_8KeywordsE41
_ZN4PLMD6colvar6Energy22getNumberOfDerivativesEv2
_ZN4PLMD6colvar6Energy7prepareEv3989
_ZN4PLMD6colvar6Energy9calculateEv3989
_ZN4PLMD6colvar6EnergyC1ERKNS_13ActionOptionsE40
_ZN4PLMD6colvar6EnergyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Energy.cpp.gcov.html b/coverage/colvar/Energy.cpp.gcov.html new file mode 100644 index 0000000000..4736e6386a --- /dev/null +++ b/coverage/colvar/Energy.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions: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             : #include "Colvar.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/Atoms.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30             : //+PLUMEDOC COLVAR ENERGY
+      31             : /*
+      32             : Calculate the total potential energy of the simulation box.
+      33             : 
+      34             : The potential energy can be biased e.g. with umbrella sampling \cite bart-karp98jpcb or with well-tempered metadynamics \cite Bonomi:2009p17935.
+      35             : 
+      36             : Notice that this CV could be unavailable with some MD code. When
+      37             : it is available, and when also replica exchange is available,
+      38             : metadynamics applied to ENERGY can be used to decrease the
+      39             : number of required replicas.
+      40             : 
+      41             : \bug This \ref ENERGY does not include long tail corrections.
+      42             : Thus when using e.g. LAMMPS `"pair_modify tail yes"` or GROMACS `"DispCorr Ener"` (or `"DispCorr EnerPres"`),
+      43             : the potential energy from \ref ENERGY will be slightly different form the one of the MD code.
+      44             : You should still be able to use \ref ENERGY and then reweight your simulation with the correct MD energy value.
+      45             : 
+      46             : \bug Acceptance for replica exchange when \ref ENERGY is biased
+      47             : is computed correctly only if all the replicas have the same
+      48             : potential energy function. This is for instance not true when
+      49             : using GROMACS with lambda replica exchange or with plumed-hrex branch.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : The following input instructs plumed to print the energy of the system
+      54             : \plumedfile
+      55             : ene: ENERGY
+      56             : PRINT ARG=ene
+      57             : \endplumedfile
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : 
+      63             : class Energy : public Colvar {
+      64             : 
+      65             : public:
+      66             :   explicit Energy(const ActionOptions&);
+      67             : // active methods:
+      68             :   void prepare() override;
+      69             :   void calculate() override;
+      70             :   unsigned getNumberOfDerivatives() override;
+      71             :   static void registerKeywords( Keywords& keys );
+      72             : };
+      73             : 
+      74             : 
+      75       10499 : PLUMED_REGISTER_ACTION(Energy,"ENERGY")
+      76             : 
+      77          40 : Energy::Energy(const ActionOptions&ao):
+      78          40 :   PLUMED_COLVAR_INIT(ao)
+      79             : {
+      80             : //  if(checkNumericalDerivatives())
+      81             : //    error("Cannot use NUMERICAL_DERIVATIVES with ENERGY");
+      82          40 :   isEnergy=true;
+      83          40 :   addValueWithDerivatives(); setNotPeriodic();
+      84          40 :   getPntrToValue()->resizeDerivatives(1);
+      85          40 :   log<<"  Bibliography ";
+      86          80 :   log<<plumed.cite("Bartels and Karplus, J. Phys. Chem. B 102, 865 (1998)");
+      87          80 :   log<<plumed.cite("Bonomi and Parrinello, J. Comp. Chem. 30, 1615 (2009)");
+      88          40 :   log<<"\n";
+      89          40 : }
+      90             : 
+      91          41 : void Energy::registerKeywords( Keywords& keys ) {
+      92          41 :   Action::registerKeywords( keys );
+      93          41 :   ActionAtomistic::registerKeywords( keys );
+      94          41 :   ActionWithValue::registerKeywords( keys );
+      95          41 :   keys.remove("NUMERICAL_DERIVATIVES");
+      96          41 : }
+      97             : 
+      98           2 : unsigned Energy::getNumberOfDerivatives() {
+      99           2 :   return 1;
+     100             : }
+     101             : 
+     102        3989 : void Energy::prepare() {
+     103        3989 :   plumed.getAtoms().setCollectEnergy(true);
+     104        3989 : }
+     105             : 
+     106             : // calculator
+     107        3989 : void Energy::calculate() {
+     108        3989 :   setValue( getEnergy() );
+     109        3989 :   getPntrToComponent(0)->addDerivative(0,1.0);
+     110        3989 : }
+     111             : 
+     112             : }
+     113             : }
+     114             : 
+     115             : 
+     116             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..191aa65409 --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:2525100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7ExtraCVC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe646createERKNS_13ActionOptionsE2
_ZN4PLMD6colvar7ExtraCVC1ERKNS_13ActionOptionsE2
_ZN4PLMD6colvar7ExtraCV16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar7ExtraCV22getNumberOfDerivativesEv4
_ZN4PLMD6colvar7ExtraCV7prepareEv60
_ZN4PLMD6colvar7ExtraCV9calculateEv60
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe64C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe64D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/ExtraCV.cpp.func.html b/coverage/colvar/ExtraCV.cpp.func.html new file mode 100644 index 0000000000..b359c6d2be --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:2525100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe646createERKNS_13ActionOptionsE2
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe64C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe64D2Ev3473
_ZN4PLMD6colvar7ExtraCV16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar7ExtraCV22getNumberOfDerivativesEv4
_ZN4PLMD6colvar7ExtraCV7prepareEv60
_ZN4PLMD6colvar7ExtraCV9calculateEv60
_ZN4PLMD6colvar7ExtraCVC1ERKNS_13ActionOptionsE2
_ZN4PLMD6colvar7ExtraCVC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/ExtraCV.cpp.gcov.html b/coverage/colvar/ExtraCV.cpp.gcov.html new file mode 100644 index 0000000000..eaf08ebb08 --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.gcov.html @@ -0,0 +1,181 @@ + + + + + + + + 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:2525100.0 %
Date:2024-06-10 08:19:14Functions:8988.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 "Colvar.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/Atoms.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30             : //+PLUMEDOC COLVAR EXTRACV
+      31             : /*
+      32             : Allow PLUMED to use collective variables computed in the MD engine.
+      33             : 
+      34             : This feature requires the MD engine to use special instructions to pass to PLUMED the value of
+      35             : some pre-computed collective variable. Check the documentation of the MD code to find out which
+      36             : collective variables can be computed and passed to PLUMED. These variables can then be accessed by
+      37             : name using the EXTRACV action.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : This example takes the lambda variable pre-computed in GROMACS and apply to it a restraint to keep
+      42             : it close to the value 3.
+      43             : \plumedfile
+      44             : l: EXTRACV NAME=lambda
+      45             : RESTRAINT ARG=l KAPPA=10 AT=3
+      46             : \endplumedfile
+      47             : 
+      48             : 
+      49             : */
+      50             : //+ENDPLUMEDOC
+      51             : 
+      52             : 
+      53             : class ExtraCV : public Colvar {
+      54             :   std::string name;
+      55             : public:
+      56             :   explicit ExtraCV(const ActionOptions&);
+      57             : // active methods:
+      58             :   void prepare() override;
+      59             :   void calculate() override;
+      60             :   unsigned getNumberOfDerivatives() override;
+      61             :   static void registerKeywords( Keywords& keys );
+      62             : };
+      63             : 
+      64       10423 : PLUMED_REGISTER_ACTION(ExtraCV,"EXTRACV")
+      65             : 
+      66           2 : ExtraCV::ExtraCV(const ActionOptions&ao):
+      67           2 :   PLUMED_COLVAR_INIT(ao)
+      68             : {
+      69           2 :   addValueWithDerivatives(); setNotPeriodic();
+      70           2 :   getPntrToValue()->resizeDerivatives(1);
+      71           2 :   parse("NAME",name);
+      72           2 :   log<<"  name: "<<name<<"\n";
+      73           2 :   isExtraCV=true;
+      74             :   setExtraCV(name);
+      75           2 : }
+      76             : 
+      77           3 : void ExtraCV::registerKeywords( Keywords& keys ) {
+      78           3 :   Action::registerKeywords( keys );
+      79           3 :   ActionAtomistic::registerKeywords( keys );
+      80           3 :   ActionWithValue::registerKeywords( keys );
+      81           3 :   keys.remove("NUMERICAL_DERIVATIVES");
+      82           6 :   keys.add("compulsory","NAME","name of the CV as computed by the MD engine");
+      83           3 : }
+      84             : 
+      85           4 : unsigned ExtraCV::getNumberOfDerivatives() {
+      86           4 :   return 1;
+      87             : }
+      88             : 
+      89          60 : void ExtraCV::prepare() {
+      90             : /// \todo: notify Atoms that this is requested
+      91          60 : }
+      92             : 
+      93             : // calculator
+      94          60 : void ExtraCV::calculate() {
+      95          60 :   double value=plumed.getAtoms().getExtraCV(name);
+      96          60 :   setValue( value );
+      97          60 :   getPntrToComponent(0)->addDerivative(0,1.0);
+      98          60 : }
+      99             : 
+     100             : }
+     101             : }
+     102             : 
+     103             : 
+     104             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..8c666b6935 --- /dev/null +++ b/coverage/colvar/Fake.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:313881.6 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ColvarFake9calculateEv0
_ZN4PLMD6colvar10ColvarFakeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar10ColvarFakeC1ERKNS_13ActionOptionsE17
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe506createERKNS_13ActionOptionsE17
_ZN4PLMD6colvar10ColvarFake16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe50C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe50D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Fake.cpp.func.html b/coverage/colvar/Fake.cpp.func.html new file mode 100644 index 0000000000..20cc2ec5d5 --- /dev/null +++ b/coverage/colvar/Fake.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:313881.6 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ColvarFake16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD6colvar10ColvarFake9calculateEv0
_ZN4PLMD6colvar10ColvarFakeC1ERKNS_13ActionOptionsE17
_ZN4PLMD6colvar10ColvarFakeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe506createERKNS_13ActionOptionsE17
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe50C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe50D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Fake.cpp.gcov.html b/coverage/colvar/Fake.cpp.gcov.html new file mode 100644 index 0000000000..f6615c1adb --- /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:313881.6 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ + + + + + + + +

+
          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 "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       10453 : PLUMED_REGISTER_ACTION(ColvarFake,"FAKE")
+      51             : 
+      52          18 : void ColvarFake::registerKeywords( Keywords& keys ) {
+      53          18 :   Colvar::registerKeywords( keys );
+      54          36 :   keys.add("atoms","ATOMS","the fake atom index, a number is enough");
+      55          36 :   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          18 :   keys.use("PERIODIC");
+      57          36 :   keys.add("optional","COMPONENTS","additional components that this variable is supposed to have. Periodicity is ruled by PERIODIC keyword ");
+      58          18 :   useCustomisableComponents(keys);
+      59          18 : }
+      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           1 :       addComponentWithDerivatives(comps[i]);
+      73             :     }
+      74             :     // periodicity
+      75             :   } else {
+      76             :     // only one component for this variable
+      77          16 :     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.15
+
+ + + 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 0000000000..26bb9d4d33 --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:7777100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6GHBFIXC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe856createERKNS_13ActionOptionsE1
_ZN4PLMD6colvar6GHBFIXC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar6GHBFIX16registerKeywordsERNS_8KeywordsE2
_ZNK4PLMD6colvar6GHBFIX7pairingEdRdjj150
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe85C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe85D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/GHBFIX.cpp.func.html b/coverage/colvar/GHBFIX.cpp.func.html new file mode 100644 index 0000000000..5f15619d5b --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:7777100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe856createERKNS_13ActionOptionsE1
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe85C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe85D2Ev3473
_ZN4PLMD6colvar6GHBFIX16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6colvar6GHBFIXC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar6GHBFIXC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar6GHBFIX7pairingEdRdjj150
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/GHBFIX.cpp.gcov.html b/coverage/colvar/GHBFIX.cpp.gcov.html new file mode 100644 index 0000000000..b378fb4e71 --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.gcov.html @@ -0,0 +1,295 @@ + + + + + + + + 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:7777100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ + + + + + + + +

+
          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 "ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Atoms.h"
+      27             : #include "tools/IFile.h"
+      28             : 
+      29             : #include <iostream>
+      30             : 
+      31             : #include <string>
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace colvar {
+      35             : 
+      36             : //+PLUMEDOC COLVAR GHBFIX
+      37             : /*
+      38             : Calculate the GHBFIX interaction energy among GROUPA and GROUPB
+      39             : using a potential defined in KührovaÌ et al., Improving the performance of the AMBER RNA force field by
+      40             : 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.
+      41             : 
+      42             : This collective variable can be used to analyze hydrogen bond interactions, or to generate bias potentials.
+      43             : Notice that the value of the GHBFIX is returned in plumed units (see \ref UNITS), if not specified differently via ENERGY_UNITS.
+      44             : 
+      45             : \par Examples
+      46             : This example prints the GHBFIX interaction in kcal/mol between two groups of atoms using D_0, D_MAX and C
+      47             : It is applied in the functional form introduced in the pioneering paper.
+      48             : 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.
+      49             : 
+      50             : \plumedfile
+      51             : #SETTINGS AUXFOLDER=regtest/basic/rt-ghbfix
+      52             : 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
+      53             : PRINT FILE=output ARG=gh
+      54             : \endplumedfile
+      55             : 
+      56             : */
+      57             : //+ENDPLUMEDOC
+      58             : 
+      59             : class GHBFIX : public CoordinationBase {
+      60             : 
+      61             :   double dmax;
+      62             :   double dmax_squared;
+      63             :   double d0;
+      64             :   double c;
+      65             : 
+      66             :   std::vector<unsigned> typesTable;
+      67             : 
+      68             :   std::vector<double> etas;
+      69             : 
+      70             :   unsigned n;
+      71             : 
+      72             :   double dmax2;
+      73             :   double A;
+      74             :   double B;
+      75             :   double C;
+      76             :   double D;
+      77             : 
+      78             : public:
+      79             :   explicit GHBFIX(const ActionOptions&);
+      80             : // active methods:
+      81             :   static void registerKeywords( Keywords& keys );
+      82             :   double pairing(double distance,double&dfunc,unsigned i,unsigned j)const override;
+      83             : };
+      84             : 
+      85       10421 : PLUMED_REGISTER_ACTION(GHBFIX,"GHBFIX")
+      86             : 
+      87           2 : void GHBFIX::registerKeywords( Keywords& keys ) {
+      88           2 :   CoordinationBase::registerKeywords(keys);
+      89             : 
+      90           4 :   keys.add("optional","ENERGY_UNITS","the value of ENERGY_UNITS in the switching function");
+      91           4 :   keys.add("compulsory","TYPES","the value of TYPES in the switching function");
+      92           4 :   keys.add("compulsory","PARAMS","the value of PARAMS in the switching function");
+      93           4 :   keys.add("compulsory","D_MAX","the value of D_MAX in the switching function");
+      94           4 :   keys.add("compulsory","D_0","the value of D_0 in the switching function");
+      95           4 :   keys.add("compulsory","C","the value of C in the switching function");
+      96           2 : }
+      97             : 
+      98           1 : GHBFIX::GHBFIX(const ActionOptions&ao):
+      99             :   Action(ao),
+     100           1 :   CoordinationBase(ao)
+     101             : {
+     102             :   std::string types;
+     103             :   std::string params;
+     104           1 :   std::string energy_units ="plumed" ;
+     105             : 
+     106           1 :   parse("D_MAX",dmax);
+     107           1 :   dmax_squared = dmax*dmax;
+     108           1 :   parse("D_0",d0);
+     109           1 :   parse("C",c);
+     110           1 :   parse("TYPES",types);
+     111           1 :   parse("PARAMS",params);
+     112           1 :   parse("ENERGY_UNITS",energy_units);
+     113             : 
+     114           1 :   dmax2 = dmax-d0;
+     115             : 
+     116           1 :   A = (-c*dmax2*dmax2)/((1-c)*dmax2*dmax2);
+     117           1 :   B = (2*dmax2)/((1-c)*dmax2*dmax2);
+     118           1 :   C = -1/((1-c)*dmax2*dmax2);
+     119           1 :   D = 1/(c*dmax2*dmax2);
+     120             : 
+     121             :   std::map<std::string,unsigned> MapTypesTable;
+     122             : 
+     123             :   //typesTable
+     124           1 :   IFile typesfile;
+     125           1 :   typesfile.link(*this);
+     126           1 :   typesfile.open(types);
+     127             :   std::string itype;
+     128           6 :   while(typesfile.scanField("itype",itype).scanField()) {
+     129           2 :     plumed_assert(itype.empty()==false)<<"itype is empty";
+     130             : 
+     131           2 :     if (MapTypesTable.empty()) {
+     132           1 :       MapTypesTable.insert({itype, 0});
+     133             :     }
+     134             :     else if (MapTypesTable.count(itype) == 0) {
+     135             :       unsigned currentMax = 0;
+     136           2 :       for(auto it = MapTypesTable.cbegin(); it != MapTypesTable.cend(); ++it ) {
+     137           1 :         if (it ->second > currentMax) {
+     138             :           currentMax = it->second;
+     139             :         }
+     140             :       }
+     141           2 :       MapTypesTable.insert({itype, currentMax+1});
+     142             :     }
+     143             : 
+     144           2 :     typesTable.push_back(MapTypesTable[itype]);
+     145             :   }
+     146             : 
+     147           1 :   n = (int)*std::max_element(std::begin(typesTable), std::end(typesTable));
+     148           1 :   n+=1;
+     149             : 
+     150             :   //scalingParameters
+     151           1 :   etas.resize(n*n,0.0);
+     152           1 :   IFile etafile;
+     153           1 :   etafile.open(params);
+     154             :   std::string it,jt;
+     155             :   double eta;
+     156          14 :   while(etafile.scanField("itype",it).scanField("jtype",jt).scanField("eta",eta).scanField()) {
+     157           6 :     plumed_assert(it.empty()==false)<<"itype is empty";
+     158           6 :     plumed_assert(jt.empty()==false)<<"jtype is empty";
+     159           6 :     etas[n*MapTypesTable[it]+MapTypesTable[jt]]=eta;
+     160             :   }
+     161             : 
+     162           1 :   if(energy_units!="plumed") {
+     163           1 :     Units units;
+     164           1 :     units.setEnergy(energy_units);
+     165           5 :     for(auto i=0; i<etas.size(); i++) etas[i]*=units.getEnergy()/atoms.getUnits().getEnergy();
+     166           1 :   }
+     167             : 
+     168           3 : }
+     169             : 
+     170             : 
+     171         150 : double GHBFIX::pairing(double distance2,double&dfunc,unsigned i,unsigned j)const {
+     172             : 
+     173         150 :   const auto i1=getAbsoluteIndex(i).index();
+     174         150 :   plumed_assert(i1<typesTable.size())<<"your types table only covers "<<typesTable.size()<<" atoms, but you are trying to access atom number "<<(i1+1);
+     175         150 :   const auto t1=typesTable[i1];
+     176             : 
+     177         150 :   const auto i2=getAbsoluteIndex(j).index();
+     178         150 :   plumed_assert(i2<typesTable.size())<<"your types table only covers "<<typesTable.size()<<" atoms, but you are trying to access atom number "<<(i2+1);
+     179         150 :   const auto t2=typesTable[i2];
+     180             : 
+     181         150 :   const double scale=etas[n*t1+t2];
+     182             : 
+     183             :   double result;
+     184         150 :   if(distance2>dmax_squared) {
+     185             :     result=0.;
+     186           1 :     dfunc=0.0;
+     187           1 :     return result;
+     188             :   }
+     189         149 :   double distance=std::sqrt(distance2);
+     190         149 :   const double rdist = (distance-d0);
+     191             : 
+     192         149 :   if(rdist<=0.) {
+     193             :     result=-1.;
+     194         100 :     dfunc=0.0;
+     195             :   } else {
+     196             :     result=-1.;
+     197          49 :     dfunc=0.0;
+     198             : 
+     199          49 :     if (rdist > c*dmax2) {
+     200           9 :       result+=(A + B*rdist + C*rdist*rdist);
+     201           9 :       dfunc+=B+2*C*rdist;
+     202          40 :     } else if (rdist > 0.0) {
+     203          40 :       result+=D*(rdist*rdist);
+     204          40 :       dfunc+=2*D*rdist;
+     205             :     }
+     206             : 
+     207          49 :     dfunc/=distance;
+     208             :   }
+     209             : 
+     210         149 :   result*=scale;
+     211         149 :   dfunc*=scale;
+     212             : 
+     213         149 :   return result;
+     214             : }
+     215             : 
+     216             : }
+     217             : 
+     218             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bdf810a41a --- /dev/null +++ b/coverage/colvar/Gyration.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:14418677.4 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8GyrationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe926createERKNS_13ActionOptionsE33
_ZN4PLMD6colvar8GyrationC1ERKNS_13ActionOptionsE33
_ZN4PLMD6colvar8Gyration16registerKeywordsERNS_8KeywordsE34
_ZN4PLMD6colvar8Gyration9calculateEv1195
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe92C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe92D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Gyration.cpp.func.html b/coverage/colvar/Gyration.cpp.func.html new file mode 100644 index 0000000000..43700223b2 --- /dev/null +++ b/coverage/colvar/Gyration.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:14418677.4 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe926createERKNS_13ActionOptionsE33
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe92C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe92D2Ev3473
_ZN4PLMD6colvar8Gyration16registerKeywordsERNS_8KeywordsE34
_ZN4PLMD6colvar8Gyration9calculateEv1195
_ZN4PLMD6colvar8GyrationC1ERKNS_13ActionOptionsE33
_ZN4PLMD6colvar8GyrationC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Gyration.cpp.gcov.html b/coverage/colvar/Gyration.cpp.gcov.html new file mode 100644 index 0000000000..5d13025ec4 --- /dev/null +++ b/coverage/colvar/Gyration.cpp.gcov.html @@ -0,0 +1,449 @@ + + + + + + + + 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:14418677.4 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "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             : public:
+      87             :   static void registerKeywords(Keywords& keys);
+      88             :   explicit Gyration(const ActionOptions&);
+      89             :   void calculate() override;
+      90             : };
+      91             : 
+      92       10483 : PLUMED_REGISTER_ACTION(Gyration,"GYRATION")
+      93             : 
+      94          34 : void Gyration::registerKeywords(Keywords& keys) {
+      95          34 :   Colvar::registerKeywords(keys);
+      96          68 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the Gyration Tensor for");
+      97          68 :   keys.add("compulsory","TYPE","RADIUS","The type of calculation relative to the Gyration Tensor you want to perform");
+      98          68 :   keys.addFlag("MASS_WEIGHTED",false,"set the masses of all the atoms equal to one");
+      99          34 : }
+     100             : 
+     101          33 : Gyration::Gyration(const ActionOptions&ao):
+     102             :   PLUMED_COLVAR_INIT(ao),
+     103          33 :   use_masses(false),
+     104          33 :   nopbc(false)
+     105             : {
+     106             :   std::vector<AtomNumber> atoms;
+     107          65 :   parseAtomList("ATOMS",atoms);
+     108          32 :   if(atoms.size()==0) error("no atoms specified");
+     109          66 :   parseFlag("MASS_WEIGHTED",use_masses);
+     110             :   std::string Type;
+     111          32 :   parse("TYPE",Type);
+     112          32 :   parseFlag("NOPBC",nopbc);
+     113          32 :   checkRead();
+     114             : 
+     115          32 :   if(Type=="RADIUS") rg_type=RADIUS;
+     116          21 :   else if(Type=="TRACE") rg_type=TRACE;
+     117          19 :   else if(Type=="GTPC_1") rg_type=GTPC_1;
+     118          17 :   else if(Type=="GTPC_2") rg_type=GTPC_2;
+     119          15 :   else if(Type=="GTPC_3") rg_type=GTPC_3;
+     120          13 :   else if(Type=="ASPHERICITY") rg_type=ASPHERICITY;
+     121          11 :   else if(Type=="ACYLINDRICITY") rg_type=ACYLINDRICITY;
+     122           9 :   else if(Type=="KAPPA2") rg_type=KAPPA2;
+     123           7 :   else if(Type=="RGYR_3") rg_type=GYRATION_3;
+     124           5 :   else if(Type=="RGYR_2") rg_type=GYRATION_2;
+     125           3 :   else if(Type=="RGYR_1") rg_type=GYRATION_1;
+     126           1 :   else error("Unknown GYRATION type");
+     127             : 
+     128          31 :   switch(rg_type)
+     129             :   {
+     130          11 :   case RADIUS:   log.printf("  GYRATION RADIUS (Rg);"); break;
+     131           2 :   case TRACE:  log.printf("  TRACE OF THE GYRATION TENSOR;"); break;
+     132           2 :   case GTPC_1: log.printf("  THE LARGEST PRINCIPAL MOMENT OF THE GYRATION TENSOR (S'_1);"); break;
+     133           2 :   case GTPC_2: log.printf("  THE MIDDLE PRINCIPAL MOMENT OF THE GYRATION TENSOR (S'_2);");  break;
+     134           2 :   case GTPC_3: log.printf("  THE SMALLEST PRINCIPAL MOMENT OF THE GYRATION TENSOR (S'_3);"); break;
+     135           2 :   case ASPHERICITY: log.printf("  THE ASPHERICITY (b');"); break;
+     136           2 :   case ACYLINDRICITY: log.printf("  THE ACYLINDRICITY (c');"); break;
+     137           2 :   case KAPPA2: log.printf("  THE RELATIVE SHAPE ANISOTROPY (kappa^2);"); break;
+     138           2 :   case GYRATION_3: log.printf("  THE SMALLEST PRINCIPAL RADIUS OF GYRATION (r_g3);"); break;
+     139           2 :   case GYRATION_2: log.printf("  THE MIDDLE PRINCIPAL RADIUS OF GYRATION (r_g2);"); break;
+     140           2 :   case GYRATION_1: log.printf("  THE LARGEST PRINCIPAL RADIUS OF GYRATION (r_g1);"); break;
+     141             :   }
+     142          68 :   if(rg_type>TRACE) log<<"  Bibliography "<<plumed.cite("JiriÌ Vymetal and JiriÌ Vondrasek, J. Phys. Chem. A 115, 11455 (2011)");
+     143          31 :   log<<"\n";
+     144             : 
+     145          31 :   log.printf("  atoms involved : ");
+     146         233 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial());
+     147          31 :   log.printf("\n");
+     148             : 
+     149          31 :   if(nopbc) {
+     150           4 :     log<<"  PBC will be ignored\n";
+     151             :   } else {
+     152          27 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     153             :   }
+     154             : 
+     155          31 :   addValueWithDerivatives(); setNotPeriodic();
+     156          31 :   requestAtoms(atoms);
+     157          35 : }
+     158             : 
+     159        1195 : void Gyration::calculate() {
+     160             : 
+     161        1195 :   if(!nopbc) makeWhole();
+     162             : 
+     163        1195 :   Vector com;
+     164             :   double totmass = 0.;
+     165        1195 :   if( use_masses ) {
+     166           0 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     167           0 :       totmass+=getMass(i);
+     168           0 :       com+=getMass(i)*getPosition(i);
+     169             :     }
+     170             :   } else {
+     171        1195 :     totmass = static_cast<double>(getNumberOfAtoms());
+     172       10373 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     173        9178 :       com+=getPosition(i);
+     174             :     }
+     175             :   }
+     176        1195 :   com /= totmass;
+     177             : 
+     178        1195 :   double rgyr=0.;
+     179        1195 :   std::vector<Vector> derivatives( getNumberOfAtoms() );
+     180        1195 :   Tensor virial;
+     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           0 :         virial        -= Tensor(getPosition(i),derivatives[i]);
+     189             :       }
+     190             :     } else {
+     191        7973 :       for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     192        7178 :         const Vector diff = delta( com, getPosition(i) );
+     193        7178 :         rgyr          += diff.modulo2();
+     194        7178 :         derivatives[i] = diff;
+     195        7178 :         virial        -= Tensor(getPosition(i),derivatives[i]);
+     196             :       }
+     197             :     }
+     198             :     double fact;
+     199         795 :     if(rg_type==RADIUS) {
+     200         665 :       rgyr = std::sqrt(rgyr/totmass);
+     201         665 :       fact = 1./(rgyr*totmass);
+     202             :     } else {
+     203         130 :       rgyr = 2.*rgyr;
+     204             :       fact = 4;
+     205             :     }
+     206         795 :     setValue(rgyr);
+     207        7973 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) setAtomsDerivatives(i,fact*derivatives[i]);
+     208         795 :     setBoxDerivatives(fact*virial);
+     209             :     return;
+     210             :   }
+     211             : 
+     212             : 
+     213         400 :   Tensor3d gyr_tens;
+     214             :   //calculate gyration tensor
+     215         400 :   if( use_masses ) {
+     216           0 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     217           0 :       const Vector diff=delta( com, getPosition(i) );
+     218           0 :       gyr_tens[0][0]+=getMass(i)*diff[0]*diff[0];
+     219           0 :       gyr_tens[1][1]+=getMass(i)*diff[1]*diff[1];
+     220           0 :       gyr_tens[2][2]+=getMass(i)*diff[2]*diff[2];
+     221           0 :       gyr_tens[0][1]+=getMass(i)*diff[0]*diff[1];
+     222           0 :       gyr_tens[0][2]+=getMass(i)*diff[0]*diff[2];
+     223           0 :       gyr_tens[1][2]+=getMass(i)*diff[1]*diff[2];
+     224             :     }
+     225             :   } else {
+     226        2400 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     227        2000 :       const Vector diff=delta( com, getPosition(i) );
+     228        2000 :       gyr_tens[0][0]+=diff[0]*diff[0];
+     229        2000 :       gyr_tens[1][1]+=diff[1]*diff[1];
+     230        2000 :       gyr_tens[2][2]+=diff[2]*diff[2];
+     231        2000 :       gyr_tens[0][1]+=diff[0]*diff[1];
+     232        2000 :       gyr_tens[0][2]+=diff[0]*diff[2];
+     233        2000 :       gyr_tens[1][2]+=diff[1]*diff[2];
+     234             :     }
+     235             :   }
+     236             : 
+     237             :   // first make the matrix symmetric
+     238         400 :   gyr_tens[1][0] = gyr_tens[0][1];
+     239         400 :   gyr_tens[2][0] = gyr_tens[0][2];
+     240         400 :   gyr_tens[2][1] = gyr_tens[1][2];
+     241         400 :   Tensor3d ttransf,transf;
+     242         400 :   Vector princ_comp,prefactor;
+     243             :   //diagonalize gyration tensor
+     244         400 :   diagMatSym(gyr_tens, princ_comp, ttransf);
+     245         400 :   transf=transpose(ttransf);
+     246             :   //sort eigenvalues and eigenvectors
+     247         400 :   if (princ_comp[0]<princ_comp[1]) {
+     248         400 :     double tmp=princ_comp[0]; princ_comp[0]=princ_comp[1]; princ_comp[1]=tmp;
+     249        1600 :     for (unsigned i=0; i<3; i++) {tmp=transf[i][0]; transf[i][0]=transf[i][1]; transf[i][1]=tmp;}
+     250             :   }
+     251         400 :   if (princ_comp[1]<princ_comp[2]) {
+     252         400 :     double tmp=princ_comp[1]; princ_comp[1]=princ_comp[2]; princ_comp[2]=tmp;
+     253        1600 :     for (unsigned i=0; i<3; i++) {tmp=transf[i][1]; transf[i][1]=transf[i][2]; transf[i][2]=tmp;}
+     254             :   }
+     255         400 :   if (princ_comp[0]<princ_comp[1]) {
+     256         400 :     double tmp=princ_comp[0]; princ_comp[0]=princ_comp[1]; princ_comp[1]=tmp;
+     257        1600 :     for (unsigned i=0; i<3; i++) {tmp=transf[i][0]; transf[i][0]=transf[i][1]; transf[i][1]=tmp;}
+     258             :   }
+     259             :   //calculate determinant of transformation matrix
+     260             :   double det = determinant(transf);
+     261             :   // transformation matrix for rotation must have positive determinant, otherwise multiply one column by (-1)
+     262         400 :   if(det<0) {
+     263        1600 :     for(unsigned j=0; j<3; j++) transf[j][2]=-transf[j][2];
+     264         400 :     det = -det;
+     265             :   }
+     266         400 :   if(std::abs(det-1.)>0.0001) error("Plumed Error: Cannot diagonalize gyration tensor\n");
+     267         400 :   switch(rg_type) {
+     268         135 :   case GTPC_1:
+     269             :   case GTPC_2:
+     270             :   case GTPC_3:
+     271             :   {
+     272         135 :     int pc_index = rg_type-2; //index of principal component
+     273         135 :     rgyr=std::sqrt(princ_comp[pc_index]/totmass);
+     274         135 :     double rm = rgyr*totmass;
+     275         135 :     if(rm>1e-6) prefactor[pc_index]=1.0/rm; //some parts of derivate
+     276             :     break;
+     277             :   }
+     278           0 :   case GYRATION_3:        //the smallest principal radius of gyration
+     279             :   {
+     280           0 :     rgyr=std::sqrt((princ_comp[1]+princ_comp[2])/totmass);
+     281           0 :     double rm = rgyr*totmass;
+     282           0 :     if (rm>1e-6) {
+     283           0 :       prefactor[1]=1.0/rm;
+     284           0 :       prefactor[2]=1.0/rm;
+     285             :     }
+     286             :     break;
+     287             :   }
+     288         130 :   case GYRATION_2:       //the midle principal radius of gyration
+     289             :   {
+     290         130 :     rgyr=std::sqrt((princ_comp[0]+princ_comp[2])/totmass);
+     291         130 :     double rm = rgyr*totmass;
+     292         130 :     if (rm>1e-6) {
+     293         130 :       prefactor[0]=1.0/rm;
+     294         130 :       prefactor[2]=1.0/rm;
+     295             :     }
+     296             :     break;
+     297             :   }
+     298           0 :   case GYRATION_1:      //the largest principal radius of gyration
+     299             :   {
+     300           0 :     rgyr=std::sqrt((princ_comp[0]+princ_comp[1])/totmass);
+     301           0 :     double rm = rgyr*totmass;
+     302           0 :     if (rm>1e-6) {
+     303           0 :       prefactor[0]=1.0/rm;
+     304           0 :       prefactor[1]=1.0/rm;
+     305             :     }
+     306             :     break;
+     307             :   }
+     308           5 :   case ASPHERICITY:
+     309             :   {
+     310           5 :     rgyr=std::sqrt((princ_comp[0]-0.5*(princ_comp[1]+princ_comp[2]))/totmass);
+     311           5 :     double rm = rgyr*totmass;
+     312           5 :     if (rm>1e-6) {
+     313           5 :       prefactor[0]= 1.0/rm;
+     314           5 :       prefactor[1]=-0.5/rm;
+     315           5 :       prefactor[2]=-0.5/rm;
+     316             :     }
+     317             :     break;
+     318             :   }
+     319           0 :   case ACYLINDRICITY:
+     320             :   {
+     321           0 :     rgyr=std::sqrt((princ_comp[1]-princ_comp[2])/totmass);
+     322           0 :     double rm = rgyr*totmass;
+     323           0 :     if (rm>1e-6) {  //avoid division by zero
+     324           0 :       prefactor[1]= 1.0/rm;
+     325           0 :       prefactor[2]=-1.0/rm;
+     326             :     }
+     327             :     break;
+     328             :   }
+     329         130 :   case KAPPA2: // relative shape anisotropy
+     330             :   {
+     331         130 :     double trace = princ_comp[0]+princ_comp[1]+princ_comp[2];
+     332         130 :     double tmp=princ_comp[0]*princ_comp[1]+ princ_comp[1]*princ_comp[2]+ princ_comp[0]*princ_comp[2];
+     333         130 :     rgyr=1.0-3*(tmp/(trace*trace));
+     334         130 :     if (rgyr>1e-6) {
+     335         130 :       prefactor[0]= -3*((princ_comp[1]+princ_comp[2])-2*tmp/trace)/(trace*trace) *2;
+     336         130 :       prefactor[1]= -3*((princ_comp[0]+princ_comp[2])-2*tmp/trace)/(trace*trace) *2;
+     337         130 :       prefactor[2]= -3*((princ_comp[0]+princ_comp[1])-2*tmp/trace)/(trace*trace) *2;
+     338             :     }
+     339             :     break;
+     340             :   }
+     341             :   }
+     342             : 
+     343         400 :   if(use_masses) {
+     344           0 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     345           0 :       Vector tX;
+     346           0 :       const Vector diff=delta( com,getPosition(i) );
+     347             :       //project atomic postional vectors to diagonalized frame
+     348           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];
+     349           0 :       for(unsigned j=0; j<3; j++) derivatives[i][j]=getMass(i)*(prefactor[0]*transf[j][0]*tX[0]+
+     350           0 :             prefactor[1]*transf[j][1]*tX[1]+
+     351           0 :             prefactor[2]*transf[j][2]*tX[2]);
+     352           0 :       setAtomsDerivatives(i,derivatives[i]);
+     353             :     }
+     354             :   } else {
+     355        2400 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     356        2000 :       Vector tX;
+     357        2000 :       const Vector diff=delta( com,getPosition(i) );
+     358             :       //project atomic postional vectors to diagonalized frame
+     359        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];
+     360        8000 :       for(unsigned j=0; j<3; j++) derivatives[i][j]=prefactor[0]*transf[j][0]*tX[0]+
+     361       12000 :             prefactor[1]*transf[j][1]*tX[1]+
+     362        6000 :             prefactor[2]*transf[j][2]*tX[2];
+     363        2000 :       setAtomsDerivatives(i,derivatives[i]);
+     364             :     }
+     365             :   }
+     366             : 
+     367         400 :   setValue(rgyr);
+     368         400 :   setBoxDerivativesNoPbc();
+     369             : }
+     370             : 
+     371             : }
+     372             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..5e47829e44 --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:424397.7 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9MultiRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe1436createERKNS_13ActionOptionsE3
_ZN4PLMD6colvar9MultiRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar9MultiRMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar9MultiRMSD9calculateEv15
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe143C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe143D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.func.html b/coverage/colvar/MultiRMSD.cpp.func.html new file mode 100644 index 0000000000..a542793c71 --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:424397.7 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe1436createERKNS_13ActionOptionsE3
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe143C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe143D2Ev3473
_ZN4PLMD6colvar9MultiRMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar9MultiRMSD9calculateEv15
_ZN4PLMD6colvar9MultiRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar9MultiRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.gcov.html b/coverage/colvar/MultiRMSD.cpp.gcov.html new file mode 100644 index 0000000000..4ca3a13779 --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.gcov.html @@ -0,0 +1,287 @@ + + + + + + + + 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:424397.7 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "ActionRegister.h"
+      25             : #include "tools/PDB.h"
+      26             : #include "reference/MultiDomainRMSD.h"
+      27             : #include "reference/MetricRegister.h"
+      28             : #include "core/Atoms.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace colvar {
+      32             : 
+      33             : class MultiRMSD : public Colvar {
+      34             : 
+      35             :   std::unique_ptr<PLMD::MultiDomainRMSD> rmsd;
+      36             :   bool squared;
+      37             :   MultiValue myvals;
+      38             :   ReferenceValuePack mypack;
+      39             :   bool nopbc;
+      40             : 
+      41             : public:
+      42             :   explicit MultiRMSD(const ActionOptions&);
+      43             :   void calculate() override;
+      44             :   static void registerKeywords(Keywords& keys);
+      45             : };
+      46             : 
+      47             : //+PLUMEDOC DCOLVAR MULTI_RMSD
+      48             : /*
+      49             : Calculate the RMSD distance moved by a number of separated domains from their positions in a reference structure.
+      50             : 
+      51             : 
+      52             : When you have large proteins the calculation of the root mean squared deviation between all the atoms in a reference
+      53             : structure and the instantaneous configuration becomes prohibitively expensive.  You may thus instead want to calculate
+      54             : the RMSD between the atoms in a set of domains of your protein and your reference structure.  That is to say:
+      55             : 
+      56             : \f[
+      57             : d(X,X_r) = \sqrt{ \sum_{i} w_i\vert X_i - X_i' \vert^2 }
+      58             : \f]
+      59             : 
+      60             : 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$
+      61             : in the instantaneous configuration and \f$X_i'\f$ is the positions of the atoms in domain \f$i\f$ in the reference
+      62             : configuration.  \f$w_i\f$ is an optional weight.
+      63             : 
+      64             : The distances for each of the domains in the above sum can be calculated using the \ref DRMSD or \ref RMSD measures or
+      65             : using a combination of these distance.  The reference configuration is specified in a pdb file like the one below:
+      66             : 
+      67             : \auxfile{file1.pdb}
+      68             : ATOM      2  O   ALA     2      -0.926  -2.447  -0.497  1.00  1.00      DIA  O
+      69             : ATOM      4  HNT ALA     2       0.533  -0.396   1.184  1.00  1.00      DIA  H
+      70             : ATOM      6  HT1 ALA     2      -0.216  -2.590   1.371  1.00  1.00      DIA  H
+      71             : ATOM      7  HT2 ALA     2      -0.309  -1.255   2.315  1.00  1.00      DIA  H
+      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             : TER
+      76             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      77             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      78             : ATOM     16  HN  ALA     2       1.713   1.021  -0.873  1.00  1.00      DIA  H
+      79             : ATOM     18  HA  ALA     2       0.099  -0.774  -2.218  1.00  1.00      DIA  H
+      80             : ATOM     19  CB  ALA     2       2.063  -1.223  -1.276  1.00  1.00      DIA  C
+      81             : ATOM     20  HB1 ALA     2       2.670  -0.716  -2.057  1.00  1.00      DIA  H
+      82             : ATOM     21  HB2 ALA     2       2.556  -1.051  -0.295  1.00  1.00      DIA  H
+      83             : ATOM     22  HB3 ALA     2       2.070  -2.314  -1.490  1.00  1.00      DIA  H
+      84             : END
+      85             : \endauxfile
+      86             : 
+      87             : with the TER keyword being used to separate the various domains in you protein.
+      88             : 
+      89             : 
+      90             : \par Examples
+      91             : 
+      92             : The following tells plumed to calculate the RMSD distance between
+      93             : the positions of the atoms in the reference file and their instantaneous
+      94             : position.  The Kearsley algorithm for each of the domains.
+      95             : 
+      96             : \plumedfile
+      97             : MULTI_RMSD REFERENCE=file1.pdb TYPE=MULTI-OPTIMAL
+      98             : \endplumedfile
+      99             : 
+     100             : The following tells plumed to calculate the RMSD distance between the positions of
+     101             : the atoms in the domains of reference the reference structure and their instantaneous
+     102             : positions.  Here distances are calculated using the \ref DRMSD measure.
+     103             : 
+     104             : \plumedfile
+     105             : MULTI_RMSD REFERENCE=file1.pdb TYPE=MULTI-DRMSD
+     106             : \endplumedfile
+     107             : 
+     108             : in this case it is possible to use the following DRMSD options in the pdb file using the REMARK syntax:
+     109             : \verbatim
+     110             : NOPBC to calculate distances without PBC
+     111             : LOWER_CUTOFF=# only pairs of atoms further than LOWER_CUTOFF are considered in the calculation
+     112             : UPPER_CUTOFF=# only pairs of atoms further than UPPER_CUTOFF are considered in the calculation
+     113             : \endverbatim
+     114             : as shown in the following example
+     115             : 
+     116             : \auxfile{file2.pdb}
+     117             : REMARK NOPBC
+     118             : REMARK LOWER_CUTOFF=0.1
+     119             : REMARK UPPER_CUTOFF=0.8
+     120             : ATOM      2  O   ALA     2      -0.926  -2.447  -0.497  1.00  1.00      DIA  O
+     121             : ATOM      4  HNT ALA     2       0.533  -0.396   1.184  1.00  1.00      DIA  H
+     122             : ATOM      6  HT1 ALA     2      -0.216  -2.590   1.371  1.00  1.00      DIA  H
+     123             : ATOM      7  HT2 ALA     2      -0.309  -1.255   2.315  1.00  1.00      DIA  H
+     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             : TER
+     128             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+     129             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+     130             : ATOM     16  HN  ALA     2       1.713   1.021  -0.873  1.00  1.00      DIA  H
+     131             : ATOM     18  HA  ALA     2       0.099  -0.774  -2.218  1.00  1.00      DIA  H
+     132             : ATOM     19  CB  ALA     2       2.063  -1.223  -1.276  1.00  1.00      DIA  C
+     133             : ATOM     20  HB1 ALA     2       2.670  -0.716  -2.057  1.00  1.00      DIA  H
+     134             : ATOM     21  HB2 ALA     2       2.556  -1.051  -0.295  1.00  1.00      DIA  H
+     135             : ATOM     22  HB3 ALA     2       2.070  -2.314  -1.490  1.00  1.00      DIA  H
+     136             : END
+     137             : \endauxfile
+     138             : 
+     139             : 
+     140             : */
+     141             : //+ENDPLUMEDOC
+     142             : 
+     143       10425 : PLUMED_REGISTER_ACTION(MultiRMSD,"MULTI_RMSD")
+     144             : 
+     145           4 : void MultiRMSD::registerKeywords(Keywords& keys) {
+     146           4 :   Colvar::registerKeywords(keys);
+     147           8 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     148           8 :   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.");
+     149           8 :   keys.addFlag("SQUARED",false," This should be set if you want the mean squared displacement instead of the root mean squared displacement");
+     150           4 : }
+     151             : 
+     152           3 : MultiRMSD::MultiRMSD(const ActionOptions&ao):
+     153           3 :   PLUMED_COLVAR_INIT(ao),squared(false),myvals(1,0), mypack(0,0,myvals),nopbc(false)
+     154             : {
+     155             :   std::string reference;
+     156           6 :   parse("REFERENCE",reference);
+     157             :   std::string type;
+     158           3 :   type.assign("SIMPLE");
+     159           3 :   parse("TYPE",type);
+     160           3 :   parseFlag("SQUARED",squared);
+     161           3 :   parseFlag("NOPBC",nopbc);
+     162           3 :   checkRead();
+     163             : 
+     164           3 :   addValueWithDerivatives(); setNotPeriodic();
+     165           3 :   PDB pdb;
+     166             : 
+     167             :   // read everything in ang and transform to nm if we are not in natural units
+     168           6 :   if( !pdb.read(reference,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength()) )
+     169           0 :     error("missing input file " + reference );
+     170             : 
+     171           6 :   rmsd=metricRegister().create<MultiDomainRMSD>(type,pdb);
+     172             :   // Do not align molecule if we are doing DRMSD for domains and NOPBC has been specified in input
+     173           6 :   if( pdb.hasFlag("NOPBC") ) nopbc=true;
+     174             : 
+     175             :   std::vector<AtomNumber> atoms;
+     176           3 :   rmsd->getAtomRequests( atoms );
+     177           3 :   requestAtoms( atoms );
+     178             : 
+     179           3 :   myvals.resize( 1, 3*atoms.size()+9 ); mypack.resize( 0, atoms.size() );
+     180          48 :   for(unsigned i=0; i<atoms.size(); ++i) mypack.setAtomIndex( i, i );
+     181             : 
+     182           3 :   log.printf("  reference from file %s\n",reference.c_str());
+     183           3 :   log.printf("  which contains %d atoms\n",getNumberOfAtoms());
+     184           3 :   log.printf("  with indices : ");
+     185          48 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     186          45 :     if(i%25==0) log<<"\n";
+     187          45 :     log.printf("%d ",atoms[i].serial());
+     188             :   }
+     189           3 :   log.printf("\n");
+     190           3 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     191           3 :   if(squared)log.printf("  chosen to use SQUARED option for MSD instead of RMSD\n");
+     192           6 : }
+     193             : 
+     194             : // calculator
+     195          15 : void MultiRMSD::calculate() {
+     196          15 :   if(!nopbc) makeWhole();
+     197          15 :   double r=rmsd->calculate( getPositions(), getPbc(), mypack, squared );
+     198             : 
+     199          15 :   setValue(r);
+     200         240 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) setAtomsDerivatives( i, mypack.getAtomDerivative(i) );
+     201             : 
+     202          15 :   if( !mypack.virialWasSet() ) setBoxDerivativesNoPbc();
+     203           5 :   else setBoxDerivatives( mypack.getBoxDerivatives() );
+     204          15 : }
+     205             : 
+     206             : }
+     207             : }
+     208             : 
+     209             : 
+     210             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ba43975af7 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:949598.9 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7PCARMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120PCARMSDRegisterMe1016createERKNS_13ActionOptionsE2
_ZN4PLMD6colvar7PCARMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD6colvar7PCARMSD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar7PCARMSD9calculateEv1092
_ZN4PLMD6colvar12_GLOBAL__N_120PCARMSDRegisterMe101C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120PCARMSDRegisterMe101D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/PCARMSD.cpp.func.html b/coverage/colvar/PCARMSD.cpp.func.html new file mode 100644 index 0000000000..be9c35f392 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:949598.9 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7PathMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe986createERKNS_13ActionOptionsE14
_ZN4PLMD6colvar7PathMSDC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar7PathMSD16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe98C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe98D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/PathMSD.cpp.func.html b/coverage/colvar/PathMSD.cpp.func.html new file mode 100644 index 0000000000..18887f02e0 --- /dev/null +++ b/coverage/colvar/PathMSD.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:2121100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe986createERKNS_13ActionOptionsE14
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe98C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe98D2Ev3473
_ZN4PLMD6colvar7PathMSD16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD6colvar7PathMSDC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar7PathMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/PathMSD.cpp.gcov.html b/coverage/colvar/PathMSD.cpp.gcov.html new file mode 100644 index 0000000000..3f1989cc6c --- /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:2121100.0 %
Date:2024-06-10 08:19:14Functions:5683.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 "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       10447 : PLUMED_REGISTER_ACTION(PathMSD,"PATHMSD")
+      99             : 
+     100          15 : void PathMSD::registerKeywords(Keywords& keys) {
+     101          15 :   PathMSDBase::registerKeywords(keys);
+     102          15 :   componentsAreNotOptional(keys);
+     103          30 :   keys.addOutputComponent("sss","default","the position on the path");
+     104          30 :   keys.addOutputComponent("zzz","default","the distance from the path");
+     105          15 : }
+     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          28 :   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.15
+
+ + + 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 0000000000..da0a5c1410 --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:17818297.8 %
Date:2024-06-10 08:19:14Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PathMSDBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar11PathMSDBaseD0Ev0
_ZN4PLMD6colvar11PathMSDBaseD1Ev0
_ZN4PLMD6colvar11PathMSDBaseC2ERKNS_13ActionOptionsE25
_ZN4PLMD6colvar11PathMSDBaseD2Ev25
_ZN4PLMD6colvar11PathMSDBase16registerKeywordsERNS_8KeywordsE27
_ZN4PLMD6colvar11PathMSDBase9calculateEv11179
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/PathMSDBase.cpp.func.html b/coverage/colvar/PathMSDBase.cpp.func.html new file mode 100644 index 0000000000..c60108ac30 --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:17818297.8 %
Date:2024-06-10 08:19:14Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PathMSDBase16registerKeywordsERNS_8KeywordsE27
_ZN4PLMD6colvar11PathMSDBase9calculateEv11179
_ZN4PLMD6colvar11PathMSDBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar11PathMSDBaseC2ERKNS_13ActionOptionsE25
_ZN4PLMD6colvar11PathMSDBaseD0Ev0
_ZN4PLMD6colvar11PathMSDBaseD1Ev0
_ZN4PLMD6colvar11PathMSDBaseD2Ev25
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/PathMSDBase.cpp.gcov.html b/coverage/colvar/PathMSDBase.cpp.gcov.html new file mode 100644 index 0000000000..502e9bab26 --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.gcov.html @@ -0,0 +1,409 @@ + + + + + + + + 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:17818297.8 %
Date:2024-06-10 08:19:14Functions:4757.1 %
+
+ + + + + + + + +

+
          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 "ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Atoms.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          27 : void PathMSDBase::registerKeywords(Keywords& keys) {
+      35          27 :   Colvar::registerKeywords(keys);
+      36          54 :   keys.add("compulsory","LAMBDA","the lambda parameter is needed for smoothing, is in the units of plumed");
+      37          54 :   keys.add("compulsory","REFERENCE","the pdb is needed to provide the various milestones");
+      38          54 :   keys.add("optional","NEIGH_SIZE","size of the neighbor list");
+      39          54 :   keys.add("optional","NEIGH_STRIDE","how often the neighbor list needs to be calculated in time units");
+      40          54 :   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          54 :   keys.add("optional", "LOG_CLOSE", "(default=0) value 1 enables logging regarding the close structure");
+      42          54 :   keys.add("optional", "DEBUG_CLOSE", "(default=0) value 1 enables extensive debugging info regarding the close structure, the simulation will run much slower");
+      43          27 : }
+      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 :   FILE* fp=fopen(reference.c_str(),"r");
+      67             :   std::vector<AtomNumber> aaa;
+      68          25 :   if (fp!=NULL)
+      69             :   {
+      70          25 :     log<<"Opening reference file "<<reference.c_str()<<"\n";
+      71             :     bool do_read=true;
+      72             :     unsigned nat=0;
+      73        1107 :     while (do_read) {
+      74        1107 :       PDB mypdb;
+      75        1107 :       RMSD mymsd;
+      76        2214 :       do_read=mypdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
+      77        1107 :       if(do_read) {
+      78        1082 :         nframes++;
+      79        1082 :         if(mypdb.getAtomNumbers().size()==0) error("number of atoms in a frame should be more than zero");
+      80        1082 :         if(nat==0) nat=mypdb.getAtomNumbers().size();
+      81        1082 :         if(nat!=mypdb.getAtomNumbers().size()) error("frames should have the same number of atoms");
+      82        1082 :         if(aaa.empty()) {
+      83          25 :           aaa=mypdb.getAtomNumbers();
+      84          25 :           log.printf("  found %zu atoms in input \n",aaa.size());
+      85          25 :           log.printf("  with indices : ");
+      86         346 :           for(unsigned i=0; i<aaa.size(); ++i) {
+      87         321 :             if(i%25==0) log<<"\n";
+      88         321 :             log.printf("%d ",aaa[i].serial());
+      89             :           }
+      90          25 :           log.printf("\n");
+      91             :         }
+      92        2164 :         if(aaa!=mypdb.getAtomNumbers()) error("frames should contain same atoms in same order");
+      93        1082 :         log<<"Found PDB: "<<nframes<<" containing  "<<mypdb.getAtomNumbers().size()<<" atoms\n";
+      94        1082 :         pdbv.push_back(mypdb);
+      95        1082 :         derivs_s.resize(mypdb.getAtomNumbers().size());
+      96        1082 :         derivs_z.resize(mypdb.getAtomNumbers().size());
+      97        1082 :         mymsd.set(mypdb,"OPTIMAL");
+      98        1082 :         msdv.push_back(mymsd); // the vector that stores the frames
+      99             :       } else {break ;}
+     100        1107 :     }
+     101          25 :     fclose (fp);
+     102          25 :     log<<"Found TOTAL "<<nframes<< " PDB in the file "<<reference.c_str()<<" \n";
+     103          25 :     if(nframes==0) error("at least one frame expected");
+     104             :     //set up rmsdRefClose, initialize it to the first structure loaded from reference file
+     105          25 :     rmsdPosClose.set(pdbv[0], "OPTIMAL");
+     106          25 :     firstPosClose = true;
+     107             :   }
+     108          25 :   if(neigh_stride>0 || neigh_size>0) {
+     109          14 :     if(neigh_size>int(nframes)) {
+     110           0 :       log.printf(" List size required ( %d ) is too large: resizing to the maximum number of frames required: %u  \n",neigh_size,nframes);
+     111           0 :       neigh_size=nframes;
+     112             :     }
+     113          14 :     log.printf("  Neighbor list enabled: \n");
+     114          14 :     log.printf("                size   :  %d elements\n",neigh_size);
+     115          14 :     log.printf("                stride :  %d timesteps \n",neigh_stride);
+     116             :   } else {
+     117          11 :     log.printf("  Neighbor list NOT enabled \n");
+     118             :   }
+     119          25 :   if (epsilonClose > 0) {
+     120           2 :     log.printf(" Computing with the close structure, epsilon = %lf\n", epsilonClose);
+     121           6 :     log << "  Bibliography " << plumed.cite("Pazurikova J, Krenek A, Spiwok V, Simkova M J. Chem. Phys. 146, 115101 (2017)") << "\n";
+     122             :   }
+     123             :   else {
+     124          23 :     debugClose = 0;
+     125          23 :     logClose = 0;
+     126             :   }
+     127          25 :   if (debugClose)
+     128           2 :     log.printf(" Extensive debug info regarding close structure turned on\n");
+     129             : 
+     130          25 :   rotationRefClose.resize(nframes);
+     131          25 :   savedIndices = std::vector<unsigned>(nframes);
+     132             : 
+     133          25 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     134          24 :   else      log.printf("  using periodic boundary conditions\n");
+     135             : 
+     136          25 : }
+     137             : 
+     138          25 : PathMSDBase::~PathMSDBase() {
+     139          75 : }
+     140             : 
+     141       11179 : void PathMSDBase::calculate() {
+     142             : 
+     143       11179 :   if(neigh_size>0 && getExchangeStep()) error("Neighbor lists for this collective variable are not compatible with replica exchange, sorry for that!");
+     144             : 
+     145             :   //log.printf("NOW CALCULATE! \n");
+     146             : 
+     147       11179 :   if(!nopbc) makeWhole();
+     148             : 
+     149             : 
+     150             :   // resize the list to full
+     151       11179 :   if(imgVec.empty()) { // this is the signal that means: recalculate all
+     152        7164 :     imgVec.resize(nframes);
+     153             :     #pragma omp simd
+     154        7164 :     for(unsigned i=0; i<nframes; i++) {
+     155      300920 :       imgVec[i].property=indexvec[i];
+     156      300920 :       imgVec[i].index=i;
+     157             :     }
+     158             :   }
+     159             : 
+     160             : // THIS IS THE HEAVY PART (RMSD STUFF)
+     161       11179 :   unsigned stride=comm.Get_size();
+     162       11179 :   unsigned rank=comm.Get_rank();
+     163       11179 :   size_t nat=pdbv[0].size();
+     164       11179 :   plumed_assert(nat>0);
+     165       11179 :   plumed_assert(nframes>0);
+     166       11179 :   plumed_assert(imgVec.size()>0);
+     167             : 
+     168       11179 :   std::vector<Tensor> tmp_rotationRefClose(nframes);
+     169             : 
+     170       11179 :   if (epsilonClose > 0) {
+     171             :     //compute rmsd between positions and close structure, save rotation matrix, drotation_drr01
+     172        1092 :     double posclose = rmsdPosClose.calc_Rot_DRotDRr01(getPositions(), rotationPosClose, drotationPosCloseDrr01, true);
+     173             :     //if we compute for the first time or the existing close structure is too far from current structure
+     174        1092 :     if (firstPosClose || (posclose > epsilonClose)) {
+     175             :       //set the current structure as close one for a few next steps
+     176          16 :       if (logClose)
+     177          16 :         log << "PLUMED_CLOSE: new close structure, rmsd pos close " << posclose << "\n";
+     178          16 :       rmsdPosClose.clear();
+     179          16 :       rmsdPosClose.setReference(getPositions());
+     180             :       //as this is a new close structure, we need to save the rotation matrices fitted to the reference structures
+     181             :       // and we need to accurately recalculate for all reference structures
+     182          16 :       computeRefClose = true;
+     183          16 :       imgVec.resize(nframes);
+     184         688 :       for(unsigned i=0; i<nframes; i++) {
+     185         672 :         imgVec[i].property=indexvec[i];
+     186         672 :         imgVec[i].index=i;
+     187             :       }
+     188          16 :       firstPosClose = false;
+     189          16 :     }
+     190             :     else {
+     191             :       //the current structure is pretty close to the close structure, so we use saved rotation matrices to decrease the complexity of rmsd comuptation
+     192        1076 :       if (debugClose)
+     193        1076 :         log << "PLUMED-CLOSE: old close structure, rmsd pos close " << posclose << "\n";
+     194        1076 :       computeRefClose = false;
+     195             :     }
+     196             :   }
+     197             : 
+     198       11179 :   std::vector<double> tmp_distances(imgVec.size(),0.0);
+     199             :   std::vector<Vector> tmp_derivs;
+     200             : // this array is a merge of all tmp_derivs, so as to allow a single comm.Sum below
+     201       11179 :   std::vector<Vector> tmp_derivs2(imgVec.size()*nat);
+     202             : 
+     203             : // if imgVec.size() is less than nframes, it means that only some msd will be calculated
+     204       11179 :   if (epsilonClose > 0) {
+     205        1092 :     if (computeRefClose) {
+     206             :       //recompute rotation matrices accurately
+     207         688 :       for(unsigned i=rank; i<imgVec.size(); i+=stride) {
+     208         672 :         tmp_distances[i] = msdv[imgVec[i].index].calc_Rot(getPositions(), tmp_derivs, tmp_rotationRefClose[imgVec[i].index], true);
+     209         672 :         plumed_assert(tmp_derivs.size()==nat);
+     210             :         #pragma omp simd
+     211        8736 :         for(unsigned j=0; j<nat; j++) tmp_derivs2[i*nat+j]=tmp_derivs[j];
+     212             :       }
+     213             :     }
+     214             :     else {
+     215             :       //approximate distance with saved rotation matrices
+     216       46268 :       for(unsigned i=rank; i<imgVec.size(); i+=stride) {
+     217       45192 :         tmp_distances[i] = msdv[imgVec[i].index].calculateWithCloseStructure(getPositions(), tmp_derivs, rotationPosClose, rotationRefClose[imgVec[i].index], drotationPosCloseDrr01, true);
+     218       45192 :         plumed_assert(tmp_derivs.size()==nat);
+     219             :         #pragma omp simd
+     220      587496 :         for(unsigned j=0; j<nat; j++) tmp_derivs2[i*nat+j]=tmp_derivs[j];
+     221       45192 :         if (debugClose) {
+     222       45192 :           double withclose = tmp_distances[i];
+     223       45192 :           RMSD opt;
+     224       45192 :           opt.setType("OPTIMAL");
+     225       90384 :           opt.setReference(msdv[imgVec[i].index].getReference());
+     226             :           std::vector<Vector> ders;
+     227       45192 :           double withoutclose = opt.calculate(getPositions(), ders, true);
+     228       45192 :           float difference = std::abs(withoutclose-withclose);
+     229       45192 :           log<<"PLUMED-CLOSE: difference original "<<withoutclose;
+     230       45192 :           log<<" - with close "<<withclose<<" = "<<difference<<", step "<<getStep()<<", i "<<i<<" imgVec[i].index "<<imgVec[i].index<<"\n";
+     231       45192 :         }
+     232             :       }
+     233             :     }
+     234             :   }
+     235             :   else {
+     236             :     // store temporary local results
+     237      297781 :     for(unsigned i=rank; i<imgVec.size(); i+=stride) {
+     238      287694 :       tmp_distances[i]=msdv[imgVec[i].index].calculate(getPositions(),tmp_derivs,true);
+     239      287694 :       plumed_assert(tmp_derivs.size()==nat);
+     240             :       #pragma omp simd
+     241     3729822 :       for(unsigned j=0; j<nat; j++) tmp_derivs2[i*nat+j]=tmp_derivs[j];
+     242             :     }
+     243             :   }
+     244             : 
+     245             : // reduce over all processors
+     246       11179 :   comm.Sum(tmp_distances);
+     247       11179 :   comm.Sum(tmp_derivs2);
+     248       11179 :   if (epsilonClose > 0 && computeRefClose) {
+     249          16 :     comm.Sum(tmp_rotationRefClose);
+     250         688 :     for (unsigned i=0; i<nframes; i++) {
+     251         672 :       rotationRefClose[i] = tmp_rotationRefClose[i];
+     252             :     }
+     253             :   }
+     254             : // assign imgVec[i].distance and imgVec[i].distder
+     255      482329 :   for(size_t i=0; i<imgVec.size(); i++) {
+     256      471150 :     imgVec[i].distance=tmp_distances[i];
+     257      471150 :     imgVec[i].distder.assign(&tmp_derivs2[i*nat],nat+&tmp_derivs2[i*nat]);
+     258             :   }
+     259             : 
+     260             : // END OF THE HEAVY PART
+     261             : 
+     262             :   std::vector<Value*> val_s_path;
+     263       11179 :   if(labels.size()>0) {
+     264       18018 :     for(unsigned i=0; i<labels.size(); i++) { val_s_path.push_back(getPntrToComponent(labels[i].c_str()));}
+     265             :   } else {
+     266        5173 :     val_s_path.push_back(getPntrToComponent("sss"));
+     267             :   }
+     268       22358 :   Value* val_z_path=getPntrToComponent("zzz");
+     269             : 
+     270       28364 :   std::vector<double> s_path(val_s_path.size()); for(unsigned i=0; i<s_path.size(); i++)s_path[i]=0.;
+     271             :   double partition=0.;
+     272             :   double tmp;
+     273             : 
+     274             :   // clean vector
+     275      156302 :   for(unsigned i=0; i< derivs_z.size(); i++) {derivs_z[i].zero();}
+     276             : 
+     277      482329 :   for(auto & it : imgVec) {
+     278      471150 :     it.similarity=std::exp(-lambda*(it.distance));
+     279     1194552 :     for(unsigned i=0; i<s_path.size(); i++) {
+     280      723402 :       s_path[i]+=(it.property[i])*it.similarity;
+     281             :     }
+     282      471150 :     partition+=it.similarity;
+     283             :   }
+     284       28364 :   for(unsigned i=0; i<s_path.size(); i++) { s_path[i]/=partition;  val_s_path[i]->set(s_path[i]) ;}
+     285       11179 :   val_z_path->set(-(1./lambda)*std::log(partition));
+     286       28364 :   for(unsigned j=0; j<s_path.size(); j++) {
+     287             :     // clean up
+     288             :     #pragma omp simd
+     289      240386 :     for(unsigned i=0; i< derivs_s.size(); i++) {derivs_s[i].zero();}
+     290             :     // do the derivative
+     291      740587 :     for(const auto & it : imgVec) {
+     292      723402 :       double expval=it.similarity;
+     293      723402 :       tmp=lambda*expval*(s_path[j]-it.property[j])/partition;
+     294             :       #pragma omp simd
+     295    10117428 :       for(unsigned i=0; i< derivs_s.size(); i++) { derivs_s[i]+=tmp*it.distder[i] ;}
+     296      723402 :       if(j==0) {
+     297             :         #pragma omp simd
+     298     6585900 :         for(unsigned i=0; i< derivs_z.size(); i++) { derivs_z[i]+=it.distder[i]*expval/partition;}
+     299             :       }
+     300             :     }
+     301      240386 :     for(unsigned i=0; i< derivs_s.size(); i++) {
+     302      223201 :       setAtomsDerivatives (val_s_path[j],i,derivs_s[i]);
+     303      223201 :       if(j==0) {setAtomsDerivatives (val_z_path,i,derivs_z[i]);}
+     304             :     }
+     305             :   }
+     306       28364 :   for(unsigned i=0; i<val_s_path.size(); ++i) setBoxDerivativesNoPbc(val_s_path[i]);
+     307       11179 :   setBoxDerivativesNoPbc(val_z_path);
+     308             :   //
+     309             :   //  here set next round neighbors
+     310             :   //
+     311       11179 :   if (neigh_size>0) {
+     312             :     //if( int(getStep())%int(neigh_stride/getTimeStep())==0 ){
+     313             :     // enforce consistency: the stride is in time steps
+     314        7153 :     if( int(getStep())%int(neigh_stride)==0 ) {
+     315             : 
+     316             :       // next round do it all:empty the vector
+     317        7153 :       imgVec.clear();
+     318             :     }
+     319             :     // time to analyze the results:
+     320        7153 :     if(imgVec.size()==nframes) {
+     321             :       //sort by msd
+     322           0 :       sort(imgVec.begin(), imgVec.end(), imgOrderByDist());
+     323             :       //resize
+     324           0 :       imgVec.resize(neigh_size);
+     325             :     }
+     326             :   }
+     327             :   //log.printf("CALCULATION DONE! \n");
+     328       11179 : }
+     329             : 
+     330             : }
+     331             : 
+     332             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..1bee8fb62b --- /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:010.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/PathMSDBase.h.func.html b/coverage/colvar/PathMSDBase.h.func.html new file mode 100644 index 0000000000..e661c1090f --- /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:010.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/PathMSDBase.h.gcov.html b/coverage/colvar/PathMSDBase.h.gcov.html new file mode 100644 index 0000000000..ba02d2e0ca --- /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:010.0 %
Date:2024-06-10 08:19:14Functions: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 "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             :   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.15
+
+ + + 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 0000000000..b51c735223 --- /dev/null +++ b/coverage/colvar/Position.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:6666100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8PositionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe846createERKNS_13ActionOptionsE87
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE87
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE88
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe84C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe84D2Ev3473
_ZN4PLMD6colvar8Position9calculateEv8037
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Position.cpp.func.html b/coverage/colvar/Position.cpp.func.html new file mode 100644 index 0000000000..e8eddf5450 --- /dev/null +++ b/coverage/colvar/Position.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:6666100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe846createERKNS_13ActionOptionsE87
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe84C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe84D2Ev3473
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE88
_ZN4PLMD6colvar8Position9calculateEv8037
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE87
_ZN4PLMD6colvar8PositionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Position.cpp.gcov.html b/coverage/colvar/Position.cpp.gcov.html new file mode 100644 index 0000000000..a1617deef0 --- /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:6666100.0 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "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       10592 : PLUMED_REGISTER_ACTION(Position,"POSITION")
+      85             : 
+      86          88 : void Position::registerKeywords( Keywords& keys ) {
+      87          88 :   Colvar::registerKeywords( keys );
+      88          88 :   componentsAreNotOptional(keys);
+      89         176 :   keys.add("atoms","ATOM","the atom number");
+      90         176 :   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         176 :   keys.addOutputComponent("x","default","the x-component of the atom position");
+      92         176 :   keys.addOutputComponent("y","default","the y-component of the atom position");
+      93         176 :   keys.addOutputComponent("z","default","the z-component of the atom position");
+      94         264 :   keys.addOutputComponent("a","SCALED_COMPONENTS","the normalized projection on the first lattice vector of the atom position");
+      95         264 :   keys.addOutputComponent("b","SCALED_COMPONENTS","the normalized projection on the second lattice vector of the atom position");
+      96         264 :   keys.addOutputComponent("c","SCALED_COMPONENTS","the normalized projection on the third lattice vector of the atom position");
+      97          88 : }
+      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         164 :     addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+     124         164 :     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        7992 :     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.15
+
+ + + 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 0000000000..cf69702067 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:606395.2 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16ProjectionOnAxisC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe796createERKNS_13ActionOptionsE1
_ZN4PLMD6colvar16ProjectionOnAxisC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar16ProjectionOnAxis16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6colvar16ProjectionOnAxis9calculateEv25
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe79C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe79D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/ProjectionOnAxis.cpp.func.html b/coverage/colvar/ProjectionOnAxis.cpp.func.html new file mode 100644 index 0000000000..3e59f9e804 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:606395.2 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe796createERKNS_13ActionOptionsE1
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe79C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe79D2Ev3473
_ZN4PLMD6colvar16ProjectionOnAxis16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6colvar16ProjectionOnAxis9calculateEv25
_ZN4PLMD6colvar16ProjectionOnAxisC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar16ProjectionOnAxisC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/ProjectionOnAxis.cpp.gcov.html b/coverage/colvar/ProjectionOnAxis.cpp.gcov.html new file mode 100644 index 0000000000..51ce1c7053 --- /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:606395.2 %
Date:2024-06-10 08:19:14Functions: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             : #include "Colvar.h"
+      23             : #include "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       10421 : PLUMED_REGISTER_ACTION(ProjectionOnAxis,"PROJECTION_ON_AXIS")
+      80             : 
+      81           2 : void ProjectionOnAxis::registerKeywords( Keywords& keys ) {
+      82           2 :   Colvar::registerKeywords(keys);
+      83           4 :   keys.add("atoms","AXIS_ATOMS","The atoms that define the direction of the axis of interest");
+      84           4 :   keys.add("atoms","ATOM","The atom whose position we want to project on the axis of interest");
+      85           4 :   keys.addOutputComponent("proj","COMPONENTS","The value of the projection along the axis");
+      86           4 :   keys.addOutputComponent("ext","COMPONENTS","The value of the extension from the axis");
+      87           2 : }
+      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           2 :   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.15
+
+ + + 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 0000000000..fee682a7a6 --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:252792.6 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar11PropertyMapC1ERKNS_13ActionOptionsE11
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe976createERKNS_13ActionOptionsE11
_ZN4PLMD6colvar11PropertyMap16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe97C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe97D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/PropertyMap.cpp.func.html b/coverage/colvar/PropertyMap.cpp.func.html new file mode 100644 index 0000000000..13eed04e3c --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:252792.6 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PropertyMap16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD6colvar11PropertyMapC1ERKNS_13ActionOptionsE11
_ZN4PLMD6colvar11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe976createERKNS_13ActionOptionsE11
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe97C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe97D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/PropertyMap.cpp.gcov.html b/coverage/colvar/PropertyMap.cpp.gcov.html new file mode 100644 index 0000000000..27e250e7ec --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + 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:252792.6 %
Date:2024-06-10 08:19:14Functions:5683.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 "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       10441 : PLUMED_REGISTER_ACTION(PropertyMap,"PROPERTYMAP")
+      98             : 
+      99          12 : void PropertyMap::registerKeywords(Keywords& keys) {
+     100          12 :   PathMSDBase::registerKeywords(keys);
+     101          24 :   keys.add("compulsory","PROPERTY","the property to be used in the indexing: this goes in the REMARK field of the reference");
+     102          12 :   ActionWithValue::useCustomisableComponents(keys);
+     103          24 :   keys.addOutputComponent("zzz","default","the minimum distance from the reference points");
+     104          12 : }
+     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          33 :      <<plumed.cite("Spiwok V, Kralova B  J. Chem. Phys. 135,  224504 (2011)")
+     115          22 :      <<"\n";
+     116          11 :   if(labels.size()==0) {
+     117             :     char buf[500];
+     118             :     std::sprintf(buf,"Need to specify PROPERTY with this action\n");
+     119           0 :     plumed_merror(buf);
+     120             :   } else {
+     121          33 :     for(unsigned i=0; i<labels.size(); i++) {
+     122          22 :       log<<" found custom propety to be found in the REMARK line: "<<labels[i].c_str()<<"\n";
+     123          22 :       addComponentWithDerivatives(labels[i]); componentIsNotPeriodic(labels[i]);
+     124             :     }
+     125             :     // add distance anyhow
+     126          22 :     addComponentWithDerivatives("zzz"); componentIsNotPeriodic("zzz");
+     127             :     //reparse the REMARK field and pick the index
+     128         473 :     for(unsigned i=0; i<pdbv.size(); i++) {
+     129             :       // now look for X=1.34555 Y=5.6677
+     130             :       std::vector<double> labelvals;
+     131        1386 :       for(unsigned j=0; j<labels.size(); j++) {
+     132             :         double val;
+     133         924 :         if( pdbv[i].getArgumentValue(labels[j],val) ) {labelvals.push_back(val);}
+     134             :         else {
+     135             :           char buf[500];
+     136             :           std::sprintf(buf,"PROPERTY LABEL \" %s \" NOT FOUND IN REMARK FOR FRAME %u \n",labels[j].c_str(),i);
+     137           0 :           plumed_merror(buf);
+     138             :         };
+     139             :       }
+     140         462 :       indexvec.push_back(labelvals);
+     141             :     }
+     142             :   }
+     143          11 :   requestAtoms(pdbv[0].getAtomNumbers());
+     144             : 
+     145          11 : }
+     146             : 
+     147             : }
+     148             : }
+     149             : 
+     150             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..043e7d983a --- /dev/null +++ b/coverage/colvar/Puckering.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:22923099.6 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9PuckeringC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe816createERKNS_13ActionOptionsE54
_ZN4PLMD6colvar9PuckeringC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar9Puckering16registerKeywordsERNS_8KeywordsE55
_ZN4PLMD6colvar9Puckering11calculate6mEv103
_ZN4PLMD6colvar9Puckering11calculate5mEv294
_ZN4PLMD6colvar9Puckering9calculateEv397
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe81C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe81D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Puckering.cpp.func.html b/coverage/colvar/Puckering.cpp.func.html new file mode 100644 index 0000000000..c1ec924b22 --- /dev/null +++ b/coverage/colvar/Puckering.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:22923099.6 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe816createERKNS_13ActionOptionsE54
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe81C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe81D2Ev3473
_ZN4PLMD6colvar9Puckering11calculate5mEv294
_ZN4PLMD6colvar9Puckering11calculate6mEv103
_ZN4PLMD6colvar9Puckering16registerKeywordsERNS_8KeywordsE55
_ZN4PLMD6colvar9Puckering9calculateEv397
_ZN4PLMD6colvar9PuckeringC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar9PuckeringC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Puckering.cpp.gcov.html b/coverage/colvar/Puckering.cpp.gcov.html new file mode 100644 index 0000000000..3b419dafa6 --- /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:22923099.6 %
Date:2024-06-10 08:19:14Functions:8988.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 "Colvar.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "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       10526 : PLUMED_REGISTER_ACTION(Puckering,"PUCKERING")
+      82             : 
+      83          55 : void Puckering::registerKeywords(Keywords& keys) {
+      84          55 :   Colvar::registerKeywords( keys );
+      85          55 :   keys.remove("NOPBC");
+      86         110 :   keys.add("atoms","ATOMS","the five or six atoms of the sugar ring in the proper order");
+      87         110 :   keys.addOutputComponent("phs","default","Pseudorotation phase (5 membered rings)");
+      88         110 :   keys.addOutputComponent("amp","default","Pseudorotation amplitude (5 membered rings)");
+      89         110 :   keys.addOutputComponent("Zx","default","Pseudorotation x Cartesian component (5 membered rings)");
+      90         110 :   keys.addOutputComponent("Zy","default","Pseudorotation y Cartesian component (5 membered rings)");
+      91         110 :   keys.addOutputComponent("phi","default","Pseudorotation phase (6 membered rings)");
+      92         110 :   keys.addOutputComponent("theta","default","Theta angle (6 membered rings)");
+      93         110 :   keys.addOutputComponent("amplitude","default","Pseudorotation amplitude (6 membered rings)");
+      94         110 :   keys.addOutputComponent("qx","default","Cartesian component x (6 membered rings)");
+      95         110 :   keys.addOutputComponent("qy","default","Cartesian component y (6 membered rings)");
+      96         110 :   keys.addOutputComponent("qz","default","Cartesian component z (6 membered rings)");
+      97          55 : }
+      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         104 :     addComponentWithDerivatives("amp"); componentIsNotPeriodic("amp");
+     116         104 :     addComponentWithDerivatives("Zx"); componentIsNotPeriodic("Zx");
+     117         156 :     addComponentWithDerivatives("Zy"); componentIsNotPeriodic("Zy");
+     118           1 :   } else if(atoms.size()==6) {
+     119           2 :     addComponentWithDerivatives("qx"); componentIsNotPeriodic("qx");
+     120           2 :     addComponentWithDerivatives("qy"); componentIsNotPeriodic("qy");
+     121           2 :     addComponentWithDerivatives("qz"); componentIsNotPeriodic("qz");
+     122           3 :     addComponentWithDerivatives("phi"); componentIsPeriodic("phi","0","2pi");
+     123           2 :     addComponentWithDerivatives("theta"); componentIsNotPeriodic("theta");
+     124           3 :     addComponentWithDerivatives("amplitude"); componentIsNotPeriodic("amplitude");
+     125             :   }
+     126             : 
+     127          53 :   log<<"  Bibliography ";
+     128         157 :   if(atoms.size()==5) log<<plumed.cite("Huang, Giese, Lee, York, J. Chem. Theory Comput. 10, 1538 (2014)");
+     129          56 :   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.15
+
+ + + 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 0000000000..c9ea8fcce6 --- /dev/null +++ b/coverage/colvar/RMSD.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4747100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4RMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_117RMSDRegisterMe1626createERKNS_13ActionOptionsE72
_ZN4PLMD6colvar4RMSDC1ERKNS_13ActionOptionsE72
_ZN4PLMD6colvar4RMSD16registerKeywordsERNS_8KeywordsE73
_ZN4PLMD6colvar12_GLOBAL__N_117RMSDRegisterMe162C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_117RMSDRegisterMe162D2Ev3473
_ZN4PLMD6colvar4RMSD9calculateEv40484
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/RMSD.cpp.func.html b/coverage/colvar/RMSD.cpp.func.html new file mode 100644 index 0000000000..507bef5c93 --- /dev/null +++ b/coverage/colvar/RMSD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4747100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe596createERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8Template9calculateEv0
_ZN4PLMD6colvar8TemplateC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8TemplateC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8Template16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe59C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe59D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Template.cpp.func.html b/coverage/colvar/Template.cpp.func.html new file mode 100644 index 0000000000..022d55c04a --- /dev/null +++ b/coverage/colvar/Template.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:83522.9 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe596createERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe59C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe59D2Ev3473
_ZN4PLMD6colvar8Template16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD6colvar8Template9calculateEv0
_ZN4PLMD6colvar8TemplateC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8TemplateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Template.cpp.gcov.html b/coverage/colvar/Template.cpp.gcov.html new file mode 100644 index 0000000000..d909fc8508 --- /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:83522.9 %
Date:2024-06-10 08:19:14Functions:3742.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 "Colvar.h"
+      23             : #include "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       10419 : PLUMED_REGISTER_ACTION(Template,"TEMPLATE")
+      60             : 
+      61           1 : void Template::registerKeywords(Keywords& keys) {
+      62           1 :   Colvar::registerKeywords(keys);
+      63           2 :   keys.addFlag("TEMPLATE_DEFAULT_OFF_FLAG",false,"flags that are by default not performed should be specified like this");
+      64           3 :   keys.add("compulsory","TEMPLATE_COMPULSORY","all compulsory keywords should be added like this with a description here");
+      65           3 :   keys.add("optional","TEMPLATE_OPTIONAL","all optional keywords that have input should be added like a description here");
+      66           2 :   keys.add("atoms","ATOMS","the keyword with which you specify what atoms to use should be added like this");
+      67           1 : }
+      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.15
+
+ + + 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 0000000000..7d804e9859 --- /dev/null +++ b/coverage/colvar/Torsion.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:667291.7 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7TorsionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120TorsionRegisterMe1006createERKNS_13ActionOptionsE652
_ZN4PLMD6colvar7TorsionC1ERKNS_13ActionOptionsE652
_ZN4PLMD6colvar7Torsion16registerKeywordsERNS_8KeywordsE653
_ZN4PLMD6colvar12_GLOBAL__N_120TorsionRegisterMe100C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120TorsionRegisterMe100D2Ev3473
_ZN4PLMD6colvar7Torsion9calculateEv34536
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Torsion.cpp.func.html b/coverage/colvar/Torsion.cpp.func.html new file mode 100644 index 0000000000..0a17b51d1d --- /dev/null +++ b/coverage/colvar/Torsion.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:667291.7 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120TorsionRegisterMe1006createERKNS_13ActionOptionsE652
_ZN4PLMD6colvar12_GLOBAL__N_120TorsionRegisterMe100C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_120TorsionRegisterMe100D2Ev3473
_ZN4PLMD6colvar7Torsion16registerKeywordsERNS_8KeywordsE653
_ZN4PLMD6colvar7Torsion9calculateEv34536
_ZN4PLMD6colvar7TorsionC1ERKNS_13ActionOptionsE652
_ZN4PLMD6colvar7TorsionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Torsion.cpp.gcov.html b/coverage/colvar/Torsion.cpp.gcov.html new file mode 100644 index 0000000000..44ea228bb6 --- /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:667291.7 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "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       11721 : PLUMED_REGISTER_ACTION(Torsion,"TORSION")
+     101             : 
+     102         653 : void Torsion::registerKeywords(Keywords& keys) {
+     103         653 :   Colvar::registerKeywords( keys );
+     104        1306 :   keys.add("atoms-1","ATOMS","the four atoms involved in the torsional angle");
+     105        1306 :   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        1306 :   keys.add("atoms-2","VECTOR1","two atoms that define a vector.  You can use this in combination with VECTOR2 and AXIS");
+     107        1306 :   keys.add("atoms-2","VECTOR2","two atoms that define a vector.  You can use this in combination with VECTOR1 and AXIS");
+     108        1306 :   keys.addFlag("COSINE",false,"calculate cosine instead of dihedral");
+     109         653 : }
+     110             : 
+     111         652 : Torsion::Torsion(const ActionOptions&ao):
+     112             :   PLUMED_COLVAR_INIT(ao),
+     113         652 :   pbc(true),
+     114         652 :   do_cosine(false)
+     115             : {
+     116             :   std::vector<AtomNumber> atoms,v1,v2,axis;
+     117         652 :   parseAtomList("ATOMS",atoms);
+     118         652 :   parseAtomList("VECTOR1",v1);
+     119         652 :   parseAtomList("VECTOR2",v2);
+     120         652 :   parseAtomList("AXIS",axis);
+     121             : 
+     122         652 :   parseFlag("COSINE",do_cosine);
+     123             : 
+     124         652 :   bool nopbc=!pbc;
+     125         652 :   parseFlag("NOPBC",nopbc);
+     126         652 :   pbc=!nopbc;
+     127         652 :   checkRead();
+     128             : 
+     129         652 :   if(atoms.size()==4) {
+     130         647 :     if(!(v1.empty() && v2.empty() && axis.empty()))
+     131           1 :       error("ATOMS keyword is not compatible with VECTOR1, VECTOR2 and AXIS keywords");
+     132         646 :     log.printf("  between atoms %d %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
+     133         646 :     atoms.resize(6);
+     134         646 :     atoms[5]=atoms[3];
+     135         646 :     atoms[4]=atoms[2];
+     136         646 :     atoms[3]=atoms[2];
+     137         646 :     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         650 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     153         112 :   else    log.printf("  without periodic boundary conditions\n");
+     154             : 
+     155         650 :   if(do_cosine) log.printf("  calculating cosine instead of torsion\n");
+     156             : 
+     157         650 :   addValueWithDerivatives();
+     158        1302 :   if(!do_cosine) setPeriodic("-pi","pi");
+     159           0 :   else setNotPeriodic();
+     160         650 :   requestAtoms(atoms);
+     161         654 : }
+     162             : 
+     163             : // calculator
+     164       34536 : void Torsion::calculate() {
+     165             : 
+     166       34536 :   Vector d0,d1,d2;
+     167       34536 :   if(pbc) makeWhole();
+     168       34536 :   d0=delta(getPosition(1),getPosition(0));
+     169       34536 :   d1=delta(getPosition(3),getPosition(2));
+     170       34536 :   d2=delta(getPosition(5),getPosition(4));
+     171       34536 :   Vector dd0,dd1,dd2;
+     172             :   PLMD::Torsion t;
+     173       34536 :   double torsion=t.compute(d0,d1,d2,dd0,dd1,dd2);
+     174       34536 :   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       34536 :   setAtomsDerivatives(0,dd0);
+     181       34536 :   setAtomsDerivatives(1,-dd0);
+     182       34536 :   setAtomsDerivatives(2,dd1);
+     183       34536 :   setAtomsDerivatives(3,-dd1);
+     184       34536 :   setAtomsDerivatives(4,dd2);
+     185       34536 :   setAtomsDerivatives(5,-dd2);
+     186             : 
+     187       34536 :   setValue           (torsion);
+     188       34536 :   setBoxDerivativesNoPbc();
+     189       34536 : }
+     190             : 
+     191             : }
+     192             : }
+     193             : 
+     194             : 
+     195             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b13191ace2 --- /dev/null +++ b/coverage/colvar/Volume.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1717100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6VolumeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe546createERKNS_13ActionOptionsE9
_ZN4PLMD6colvar6VolumeC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6colvar6Volume9calculateEv148
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe54C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe54D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Volume.cpp.func.html b/coverage/colvar/Volume.cpp.func.html new file mode 100644 index 0000000000..58c3e6065c --- /dev/null +++ b/coverage/colvar/Volume.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1717100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe546createERKNS_13ActionOptionsE9
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe54C2Ev3473
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe54D2Ev3473
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6colvar6Volume9calculateEv148
_ZN4PLMD6colvar6VolumeC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar6VolumeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/Volume.cpp.gcov.html b/coverage/colvar/Volume.cpp.gcov.html new file mode 100644 index 0000000000..69ea85cddd --- /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:1717100.0 %
Date:2024-06-10 08:19:14Functions: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 "Colvar.h"
+      23             : #include "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       10437 : 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           9 :   addValueWithDerivatives(); setNotPeriodic();
+      63           9 :   requestAtoms(atoms);
+      64           9 : }
+      65             : 
+      66          10 : void Volume::registerKeywords( Keywords& keys ) {
+      67          10 :   Action::registerKeywords( keys );
+      68          10 :   ActionWithValue::registerKeywords( keys );
+      69          10 :   ActionAtomistic::registerKeywords( keys );
+      70          10 : }
+      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.15
+
+ + + diff --git a/coverage/colvar/index-sort-f.html b/coverage/colvar/index-sort-f.html new file mode 100644 index 0000000000..7fe1f0c912 --- /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:1980211493.7 %
Date:2024-06-10 08:19:14Functions:18222182.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Template.cpp +
22.9%22.9%
+
22.9 %8 / 3542.9 %3 / 7
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %178 / 18257.1 %4 / 7
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
Fake.cpp +
81.6%81.6%
+
81.6 %31 / 3871.4 %5 / 7
ContactMap.cpp +
91.7%91.7%
+
91.7 %121 / 13275.0 %6 / 8
PathMSD.cpp +
100.0%
+
100.0 %21 / 2183.3 %5 / 6
PropertyMap.cpp +
92.6%92.6%
+
92.6 %25 / 2783.3 %5 / 6
ERMSD.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
Angle.cpp +
97.4%97.4%
+
97.4 %38 / 3985.7 %6 / 7
Position.cpp +
100.0%
+
100.0 %66 / 6685.7 %6 / 7
Distance.cpp +
100.0%
+
100.0 %82 / 8285.7 %6 / 7
DHEnergy.cpp +
94.1%94.1%
+
94.1 %32 / 3485.7 %6 / 7
DRMSD.cpp +
100.0%
+
100.0 %44 / 4485.7 %6 / 7
Coordination.cpp +
100.0%
+
100.0 %30 / 3085.7 %6 / 7
Gyration.cpp +
77.4%77.4%
+
77.4 %144 / 18685.7 %6 / 7
Volume.cpp +
100.0%
+
100.0 %17 / 1785.7 %6 / 7
MultiRMSD.cpp +
97.7%97.7%
+
97.7 %42 / 4385.7 %6 / 7
Constant.cpp +
95.6%95.6%
+
95.6 %43 / 4585.7 %6 / 7
GHBFIX.cpp +
100.0%
+
100.0 %77 / 7785.7 %6 / 7
Torsion.cpp +
91.7%91.7%
+
91.7 %66 / 7285.7 %6 / 7
RMSD.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
Cell.cpp +
100.0%
+
100.0 %36 / 3685.7 %6 / 7
Dipole.cpp +
100.0%
+
100.0 %61 / 6185.7 %6 / 7
PCARMSD.cpp +
98.9%98.9%
+
98.9 %94 / 9585.7 %6 / 7
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %60 / 6385.7 %6 / 7
Dimer.cpp +
92.2%92.2%
+
92.2 %83 / 9087.5 %7 / 8
Puckering.cpp +
99.6%99.6%
+
99.6 %229 / 23088.9 %8 / 9
ExtraCV.cpp +
100.0%
+
100.0 %25 / 2588.9 %8 / 9
Energy.cpp +
100.0%
+
100.0 %26 / 2688.9 %8 / 9
EEFSolv.cpp +
89.1%89.1%
+
89.1 %114 / 12890.9 %10 / 11
PathMSDBase.h +
0.0%
+
0.0 %0 / 1-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/index-sort-l.html b/coverage/colvar/index-sort-l.html new file mode 100644 index 0000000000..0c30b1bb67 --- /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:1980211493.7 %
Date:2024-06-10 08:19:14Functions:18222182.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PathMSDBase.h +
0.0%
+
0.0 %0 / 1-0 / 0
Template.cpp +
22.9%22.9%
+
22.9 %8 / 3542.9 %3 / 7
Gyration.cpp +
77.4%77.4%
+
77.4 %144 / 18685.7 %6 / 7
Fake.cpp +
81.6%81.6%
+
81.6 %31 / 3871.4 %5 / 7
EEFSolv.cpp +
89.1%89.1%
+
89.1 %114 / 12890.9 %10 / 11
Torsion.cpp +
91.7%91.7%
+
91.7 %66 / 7285.7 %6 / 7
ContactMap.cpp +
91.7%91.7%
+
91.7 %121 / 13275.0 %6 / 8
Dimer.cpp +
92.2%92.2%
+
92.2 %83 / 9087.5 %7 / 8
PropertyMap.cpp +
92.6%92.6%
+
92.6 %25 / 2783.3 %5 / 6
DHEnergy.cpp +
94.1%94.1%
+
94.1 %32 / 3485.7 %6 / 7
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %60 / 6385.7 %6 / 7
Constant.cpp +
95.6%95.6%
+
95.6 %43 / 4585.7 %6 / 7
Angle.cpp +
97.4%97.4%
+
97.4 %38 / 3985.7 %6 / 7
MultiRMSD.cpp +
97.7%97.7%
+
97.7 %42 / 4385.7 %6 / 7
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %178 / 18257.1 %4 / 7
ERMSD.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
PCARMSD.cpp +
98.9%98.9%
+
98.9 %94 / 9585.7 %6 / 7
Puckering.cpp +
99.6%99.6%
+
99.6 %229 / 23088.9 %8 / 9
Volume.cpp +
100.0%
+
100.0 %17 / 1785.7 %6 / 7
PathMSD.cpp +
100.0%
+
100.0 %21 / 2183.3 %5 / 6
ExtraCV.cpp +
100.0%
+
100.0 %25 / 2588.9 %8 / 9
Energy.cpp +
100.0%
+
100.0 %26 / 2688.9 %8 / 9
Coordination.cpp +
100.0%
+
100.0 %30 / 3085.7 %6 / 7
Cell.cpp +
100.0%
+
100.0 %36 / 3685.7 %6 / 7
DRMSD.cpp +
100.0%
+
100.0 %44 / 4485.7 %6 / 7
RMSD.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
Dipole.cpp +
100.0%
+
100.0 %61 / 6185.7 %6 / 7
Position.cpp +
100.0%
+
100.0 %66 / 6685.7 %6 / 7
GHBFIX.cpp +
100.0%
+
100.0 %77 / 7785.7 %6 / 7
Distance.cpp +
100.0%
+
100.0 %82 / 8285.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/colvar/index.html b/coverage/colvar/index.html new file mode 100644 index 0000000000..e6b5b7a904 --- /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:1980211493.7 %
Date:2024-06-10 08:19:14Functions:18222182.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Angle.cpp +
97.4%97.4%
+
97.4 %38 / 3985.7 %6 / 7
Cell.cpp +
100.0%
+
100.0 %36 / 3685.7 %6 / 7
Constant.cpp +
95.6%95.6%
+
95.6 %43 / 4585.7 %6 / 7
ContactMap.cpp +
91.7%91.7%
+
91.7 %121 / 13275.0 %6 / 8
Coordination.cpp +
100.0%
+
100.0 %30 / 3085.7 %6 / 7
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
DHEnergy.cpp +
94.1%94.1%
+
94.1 %32 / 3485.7 %6 / 7
DRMSD.cpp +
100.0%
+
100.0 %44 / 4485.7 %6 / 7
Dimer.cpp +
92.2%92.2%
+
92.2 %83 / 9087.5 %7 / 8
Dipole.cpp +
100.0%
+
100.0 %61 / 6185.7 %6 / 7
Distance.cpp +
100.0%
+
100.0 %82 / 8285.7 %6 / 7
EEFSolv.cpp +
89.1%89.1%
+
89.1 %114 / 12890.9 %10 / 11
ERMSD.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
Energy.cpp +
100.0%
+
100.0 %26 / 2688.9 %8 / 9
ExtraCV.cpp +
100.0%
+
100.0 %25 / 2588.9 %8 / 9
Fake.cpp +
81.6%81.6%
+
81.6 %31 / 3871.4 %5 / 7
GHBFIX.cpp +
100.0%
+
100.0 %77 / 7785.7 %6 / 7
Gyration.cpp +
77.4%77.4%
+
77.4 %144 / 18685.7 %6 / 7
MultiRMSD.cpp +
97.7%97.7%
+
97.7 %42 / 4385.7 %6 / 7
PCARMSD.cpp +
98.9%98.9%
+
98.9 %94 / 9585.7 %6 / 7
PathMSD.cpp +
100.0%
+
100.0 %21 / 2183.3 %5 / 6
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %178 / 18257.1 %4 / 7
PathMSDBase.h +
0.0%
+
0.0 %0 / 1-0 / 0
Position.cpp +
100.0%
+
100.0 %66 / 6685.7 %6 / 7
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %60 / 6385.7 %6 / 7
PropertyMap.cpp +
92.6%92.6%
+
92.6 %25 / 2783.3 %5 / 6
Puckering.cpp +
99.6%99.6%
+
99.6 %229 / 23088.9 %8 / 9
RMSD.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
Template.cpp +
22.9%22.9%
+
22.9 %8 / 3542.9 %3 / 7
Torsion.cpp +
91.7%91.7%
+
91.7 %66 / 7285.7 %6 / 7
Volume.cpp +
100.0%
+
100.0 %17 / 1785.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7d66781dfc --- /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:346949.3 %
Date:2024-06-10 08:19:14Functions:122548.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config12plumed_soextEv0
_ZN4PLMD6config14plumed_htmldirEv0
_ZN4PLMD6config17plumed_includedirEv0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19plumed_program_nameEv0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
_ZN4PLMD6config13getEnvCommandB5cxx11Ev1
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev1
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev1
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev1
_ZN4PLMD6config11isInstalledEv3
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZN4PLMD6config13getVersionGitB5cxx11Ev5
_ZN4PLMD6config18getCompilationDateB5cxx11Ev5
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev5
_ZN4PLMD6config14getVersionLongB5cxx11Ev6
_ZN4PLMD6config11plumed_rootEv301
_ZN4PLMD6config13getPlumedRootB5cxx11Ev301
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/config/Config.inc.func.html b/coverage/config/Config.inc.func.html new file mode 100644 index 0000000000..d924b3aaec --- /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:346949.3 %
Date:2024-06-10 08:19:14Functions:122548.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv3
_ZN4PLMD6config11plumed_rootEv301
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5
_ZN4PLMD6config12plumed_soextEv0
_ZN4PLMD6config13getEnvCommandB5cxx11Ev1
_ZN4PLMD6config13getPlumedRootB5cxx11Ev301
_ZN4PLMD6config13getVersionGitB5cxx11Ev5
_ZN4PLMD6config14getVersionLongB5cxx11Ev6
_ZN4PLMD6config14plumed_htmldirEv0
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev1
_ZN4PLMD6config17plumed_includedirEv0
_ZN4PLMD6config18getCompilationDateB5cxx11Ev5
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev5
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev1
_ZN4PLMD6config19plumed_program_nameEv0
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev1
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/config/Config.inc.gcov.html b/coverage/config/Config.inc.gcov.html new file mode 100644 index 0000000000..4c9a0a4c5f --- /dev/null +++ b/coverage/config/Config.inc.gcov.html @@ -0,0 +1,277 @@ + + + + + + + + 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:346949.3 %
Date:2024-06-10 08:19:14Functions:122548.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             : 
+      28             : namespace PLMD {
+      29             : namespace config {
+      30             : 
+      31             : namespace {
+      32             :   /// local tool that, given a string, returns a new string which is:
+      33             :   /// - enclosed in single quotes (')
+      34             :   /// - with all single quotes escaped
+      35           5 :   std::string escapeForSingleQuote(const std::string& input) {
+      36             :     std::string escaped;
+      37         130 :     for (char c : input) {
+      38         125 :         if (c == '\'') {
+      39             :             escaped += "'\\''";
+      40             :         } else {
+      41         125 :             escaped += c;
+      42             :         }
+      43             :     }
+      44          13 :     return "'" + escaped + "'";
+      45             :   }
+      46             : }
+      47             : 
+      48             : // This is a fix to allow conda to correctly replace paths in binary files.
+      49             : // These functions should not be static or they will be optimized away!
+      50         301 : const char* plumed_root() {return "/home/runner/work/plumed2/plumed2/";}
+      51           0 : const char* plumed_soext() {return "so";}
+      52           0 : const char* plumed_htmldir() {return "xxxxNAxxxx";}
+      53           0 : const char* plumed_includedir() {return "xxxxNAxxxx";}
+      54           0 : const char* plumed_program_name() {return "xxxxNAxxxx";}
+      55             : 
+      56           0 : std::string getSoExt() {
+      57           0 :   return plumed_soext();
+      58             : }
+      59             : 
+      60           3 : bool isInstalled() {
+      61           3 :   return false;
+      62             : }
+      63             : 
+      64         301 : std::string getPlumedRoot() {
+      65         301 :   char *env = std::getenv("PLUMED_ROOT");
+      66             :   std::string ss;
+      67         301 :   if( env == NULL) {
+      68         301 :     ss=plumed_root();
+      69             :   } else {
+      70           0 :     ss=std::string( env );
+      71             :   }
+      72         301 :   return ss;
+      73             : }
+      74             : 
+      75           1 : std::string getPlumedHtmldir() {
+      76           1 :   if(!isInstalled()) return getPlumedRoot();
+      77           0 :   char *env = std::getenv("PLUMED_HTMLDIR");
+      78             :   std::string ss;
+      79           0 :   if( env == NULL) {
+      80           0 :     ss=plumed_htmldir();
+      81             :   } else {
+      82           0 :     ss=std::string( env );
+      83             :   }
+      84             :   return ss;
+      85             : }
+      86             : 
+      87           1 : std::string getPlumedIncludedir() {
+      88           2 :   if(!isInstalled()) return getPlumedRoot()+"/src/include";
+      89           0 :   char *env = std::getenv("PLUMED_INCLUDEDIR");
+      90             :   std::string ss;
+      91           0 :   if( env == NULL) {
+      92           0 :     ss=plumed_includedir();
+      93             :   } else {
+      94           0 :     ss=std::string( env );
+      95             :   }
+      96             :   return ss;
+      97             : }
+      98             : 
+      99           1 : std::string getPlumedProgramName() {
+     100           1 :   if(!isInstalled()) return "plumed";
+     101           0 :   char *env = std::getenv("PLUMED_PROGRAM_NAME");
+     102             :   std::string ss;
+     103           0 :   if( env == NULL) {
+     104           0 :     ss=plumed_program_name();
+     105             :   } else {
+     106           0 :     ss=std::string( env );
+     107             :   }
+     108             :   return ss;
+     109             : }
+     110             : 
+     111           1 : std::string getEnvCommand() {
+     112           3 :   return "env PLUMED_ROOT="+escapeForSingleQuote(getPlumedRoot())+
+     113           4 :          " PLUMED_VERSION="+escapeForSingleQuote(getVersionLong())+
+     114           5 :          " PLUMED_HTMLDIR="+escapeForSingleQuote(getPlumedHtmldir())+
+     115           5 :          " PLUMED_INCLUDEDIR="+escapeForSingleQuote(getPlumedIncludedir())+
+     116           4 :          " PLUMED_PROGRAM_NAME="+escapeForSingleQuote(getPlumedProgramName())+
+     117           3 :          " PLUMED_IS_INSTALLED='"+(false?"yes":"no")+"'";
+     118             : }
+     119             : 
+     120           0 : std::string getVersion() {
+     121           0 :   return PLUMED_VERSION_SHORT;
+     122             : }
+     123             : 
+     124           6 : std::string getVersionLong() {
+     125           6 :   return PLUMED_VERSION_LONG;
+     126             : }
+     127             : 
+     128           5 : std::string getVersionGit() {
+     129           5 :   return PLUMED_VERSION_GIT;
+     130             : }
+     131             : 
+     132           0 : std::string getMakefile() {
+     133             :   static const unsigned char confu [] = {
+     134             : #include "Makefile.conf.xxd"
+     135             :     , 0x00
+     136             :   };
+     137             :   auto conf=(char*)confu;
+     138           0 :   return std::string(conf,conf+std::strlen(conf));
+     139             : }
+     140             : 
+     141           0 : bool hasMatheval() {
+     142             : #ifdef __PLUMED_HAS_MATHEVAL
+     143             :   return true;
+     144             : #else
+     145           0 :   return false;
+     146             : #endif
+     147             : }
+     148             : 
+     149           0 : bool hasDlopen() {
+     150             : #ifdef __PLUMED_HAS_DLOPEN
+     151           0 :   return true;
+     152             : #else
+     153             :   return false;
+     154             : #endif
+     155             : }
+     156             : 
+     157           0 : bool hasCregex() {
+     158             : #ifdef __PLUMED_HAS_CREGEX
+     159           0 :   return true;
+     160             : #else
+     161             :   return false;
+     162             : #endif
+     163             : }
+     164             : 
+     165           0 : bool hasMolfile() {
+     166             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     167           0 :   return true;
+     168             : #else
+     169             :   return false;
+     170             : #endif
+     171             : }
+     172             : 
+     173           0 : bool hasExternalMolfile() {
+     174             : #ifdef __PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS
+     175             :   return true;
+     176             : #else
+     177           0 :   return false;
+     178             : #endif
+     179             : }
+     180             : 
+     181           0 : bool hasZlib() {
+     182             : #ifdef __PLUMED_HAS_ZLIB
+     183           0 :   return true;
+     184             : #else
+     185             :   return false;
+     186             : #endif
+     187             : }
+     188             : 
+     189           5 : std::string getCompilationDate() {
+     190           5 :   return __DATE__;
+     191             : }
+     192             : 
+     193           5 : std::string getCompilationTime() {
+     194           5 :   return __TIME__;
+     195             : }
+     196             : 
+     197             : 
+     198             : }
+     199             : }
+     200             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bb405e6794 --- /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:526975.4 %
Date:2024-06-10 08:19:14Functions:182572.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev27
_ZN4PLMD6config12plumed_soextEv593
_ZN4PLMD6config8getSoExtB5cxx11Ev593
_ZN4PLMD6config17plumed_includedirEv649
_ZN4PLMD6config13getEnvCommandB5cxx11Ev650
_ZN4PLMD6config14plumed_htmldirEv650
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev650
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev650
_ZN4PLMD6config19plumed_program_nameEv650
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev650
_ZN4PLMD6config13getVersionGitB5cxx11Ev909
_ZN4PLMD6config18getCompilationDateB5cxx11Ev909
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev909
_ZN4PLMD6config14getVersionLongB5cxx11Ev1559
_ZN4PLMD6config11isInstalledEv2569
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3250
_ZN4PLMD6config11plumed_rootEv6222
_ZN4PLMD6config13getPlumedRootB5cxx11Ev6222
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.func.html b/coverage/config/ConfigInstall.inc.func.html new file mode 100644 index 0000000000..e936c37e91 --- /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:526975.4 %
Date:2024-06-10 08:19:14Functions:182572.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev27
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv2569
_ZN4PLMD6config11plumed_rootEv6222
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3250
_ZN4PLMD6config12plumed_soextEv593
_ZN4PLMD6config13getEnvCommandB5cxx11Ev650
_ZN4PLMD6config13getPlumedRootB5cxx11Ev6222
_ZN4PLMD6config13getVersionGitB5cxx11Ev909
_ZN4PLMD6config14getVersionLongB5cxx11Ev1559
_ZN4PLMD6config14plumed_htmldirEv650
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev650
_ZN4PLMD6config17plumed_includedirEv649
_ZN4PLMD6config18getCompilationDateB5cxx11Ev909
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev909
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev650
_ZN4PLMD6config19plumed_program_nameEv650
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev650
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev593
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.gcov.html b/coverage/config/ConfigInstall.inc.gcov.html new file mode 100644 index 0000000000..c4293e8cbd --- /dev/null +++ b/coverage/config/ConfigInstall.inc.gcov.html @@ -0,0 +1,277 @@ + + + + + + + + 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:526975.4 %
Date:2024-06-10 08:19:14Functions: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             : 
+      28             : namespace PLMD {
+      29             : namespace config {
+      30             : 
+      31             : namespace {
+      32             :   /// local tool that, given a string, returns a new string which is:
+      33             :   /// - enclosed in single quotes (')
+      34             :   /// - with all single quotes escaped
+      35        3250 :   std::string escapeForSingleQuote(const std::string& input) {
+      36             :     std::string escaped;
+      37       65005 :     for (char c : input) {
+      38       61755 :         if (c == '\'') {
+      39             :             escaped += "'\\''";
+      40             :         } else {
+      41       61755 :             escaped += c;
+      42             :         }
+      43             :     }
+      44        8450 :     return "'" + escaped + "'";
+      45             :   }
+      46             : }
+      47             : 
+      48             : // This is a fix to allow conda to correctly replace paths in binary files.
+      49             : // These functions should not be static or they will be optimized away!
+      50        6222 : const char* plumed_root() {return "/home/runner/opt/lib/plumed";}
+      51         593 : const char* plumed_soext() {return "so";}
+      52         650 : const char* plumed_htmldir() {return "/home/runner/opt/share/doc/plumed";}
+      53         649 : const char* plumed_includedir() {return "/home/runner/opt/include";}
+      54         650 : const char* plumed_program_name() {return "plumed";}
+      55             : 
+      56         593 : std::string getSoExt() {
+      57         593 :   return plumed_soext();
+      58             : }
+      59             : 
+      60        2569 : bool isInstalled() {
+      61        2569 :   return true;
+      62             : }
+      63             : 
+      64        6222 : std::string getPlumedRoot() {
+      65        6222 :   char *env = std::getenv("PLUMED_ROOT");
+      66             :   std::string ss;
+      67        6222 :   if( env == NULL) {
+      68        6222 :     ss=plumed_root();
+      69             :   } else {
+      70           0 :     ss=std::string( env );
+      71             :   }
+      72        6222 :   return ss;
+      73             : }
+      74             : 
+      75         650 : std::string getPlumedHtmldir() {
+      76         650 :   if(!isInstalled()) return getPlumedRoot();
+      77         650 :   char *env = std::getenv("PLUMED_HTMLDIR");
+      78             :   std::string ss;
+      79         650 :   if( env == NULL) {
+      80         650 :     ss=plumed_htmldir();
+      81             :   } else {
+      82           0 :     ss=std::string( env );
+      83             :   }
+      84             :   return ss;
+      85             : }
+      86             : 
+      87         650 : std::string getPlumedIncludedir() {
+      88         650 :   if(!isInstalled()) return getPlumedRoot()+"/src/include";
+      89         650 :   char *env = std::getenv("PLUMED_INCLUDEDIR");
+      90             :   std::string ss;
+      91         650 :   if( env == NULL) {
+      92         649 :     ss=plumed_includedir();
+      93             :   } else {
+      94           2 :     ss=std::string( env );
+      95             :   }
+      96             :   return ss;
+      97             : }
+      98             : 
+      99         650 : std::string getPlumedProgramName() {
+     100         650 :   if(!isInstalled()) return "plumed";
+     101         650 :   char *env = std::getenv("PLUMED_PROGRAM_NAME");
+     102             :   std::string ss;
+     103         650 :   if( env == NULL) {
+     104         650 :     ss=plumed_program_name();
+     105             :   } else {
+     106           0 :     ss=std::string( env );
+     107             :   }
+     108             :   return ss;
+     109             : }
+     110             : 
+     111         650 : std::string getEnvCommand() {
+     112        1950 :   return "env PLUMED_ROOT="+escapeForSingleQuote(getPlumedRoot())+
+     113        2600 :          " PLUMED_VERSION="+escapeForSingleQuote(getVersionLong())+
+     114        3250 :          " PLUMED_HTMLDIR="+escapeForSingleQuote(getPlumedHtmldir())+
+     115        3250 :          " PLUMED_INCLUDEDIR="+escapeForSingleQuote(getPlumedIncludedir())+
+     116        2600 :          " PLUMED_PROGRAM_NAME="+escapeForSingleQuote(getPlumedProgramName())+
+     117        1950 :          " PLUMED_IS_INSTALLED='"+(true?"yes":"no")+"'";
+     118             : }
+     119             : 
+     120           0 : std::string getVersion() {
+     121           0 :   return PLUMED_VERSION_SHORT;
+     122             : }
+     123             : 
+     124        1559 : std::string getVersionLong() {
+     125        1559 :   return PLUMED_VERSION_LONG;
+     126             : }
+     127             : 
+     128         909 : std::string getVersionGit() {
+     129         909 :   return PLUMED_VERSION_GIT;
+     130             : }
+     131             : 
+     132          27 : std::string getMakefile() {
+     133             :   static const unsigned char confu [] = {
+     134             : #include "Makefile.conf.xxd"
+     135             :     , 0x00
+     136             :   };
+     137             :   auto conf=(char*)confu;
+     138          27 :   return std::string(conf,conf+std::strlen(conf));
+     139             : }
+     140             : 
+     141           0 : bool hasMatheval() {
+     142             : #ifdef __PLUMED_HAS_MATHEVAL
+     143             :   return true;
+     144             : #else
+     145           0 :   return false;
+     146             : #endif
+     147             : }
+     148             : 
+     149           0 : bool hasDlopen() {
+     150             : #ifdef __PLUMED_HAS_DLOPEN
+     151           0 :   return true;
+     152             : #else
+     153             :   return false;
+     154             : #endif
+     155             : }
+     156             : 
+     157           0 : bool hasCregex() {
+     158             : #ifdef __PLUMED_HAS_CREGEX
+     159           0 :   return true;
+     160             : #else
+     161             :   return false;
+     162             : #endif
+     163             : }
+     164             : 
+     165           0 : bool hasMolfile() {
+     166             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     167           0 :   return true;
+     168             : #else
+     169             :   return false;
+     170             : #endif
+     171             : }
+     172             : 
+     173           0 : bool hasExternalMolfile() {
+     174             : #ifdef __PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS
+     175             :   return true;
+     176             : #else
+     177           0 :   return false;
+     178             : #endif
+     179             : }
+     180             : 
+     181           0 : bool hasZlib() {
+     182             : #ifdef __PLUMED_HAS_ZLIB
+     183           0 :   return true;
+     184             : #else
+     185             :   return false;
+     186             : #endif
+     187             : }
+     188             : 
+     189         909 : std::string getCompilationDate() {
+     190         909 :   return __DATE__;
+     191             : }
+     192             : 
+     193         909 : std::string getCompilationTime() {
+     194         909 :   return __TIME__;
+     195             : }
+     196             : 
+     197             : 
+     198             : }
+     199             : }
+     200             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/config/index-sort-f.html b/coverage/config/index-sort-f.html new file mode 100644 index 0000000000..39746641c6 --- /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:8613862.3 %
Date:2024-06-10 08:19:14Functions:305060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
49.3%49.3%
+
49.3 %34 / 6948.0 %12 / 25
ConfigInstall.inc +
75.4%75.4%
+
75.4 %52 / 6972.0 %18 / 25
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/config/index-sort-l.html b/coverage/config/index-sort-l.html new file mode 100644 index 0000000000..5dd78154cb --- /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:8613862.3 %
Date:2024-06-10 08:19:14Functions:305060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
49.3%49.3%
+
49.3 %34 / 6948.0 %12 / 25
ConfigInstall.inc +
75.4%75.4%
+
75.4 %52 / 6972.0 %18 / 25
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/config/index.html b/coverage/config/index.html new file mode 100644 index 0000000000..e1791f0f0a --- /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:8613862.3 %
Date:2024-06-10 08:19:14Functions:305060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
49.3%49.3%
+
49.3 %34 / 6948.0 %12 / 25
ConfigInstall.inc +
75.4%75.4%
+
75.4 %52 / 6972.0 %18 / 25
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..1474c7574b --- /dev/null +++ b/coverage/core/Action.cpp.func-sort-c.html @@ -0,0 +1,197 @@ + + + + + + + + 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:12115578.1 %
Date:2024-06-10 08:19:14Functions:253180.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6ActionD0Ev0
_ZNK4PLMD6Action16getDocumentationB5cxx11Ev0
_ZNK4PLMD6Action5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30
_ZN4PLMD6Action10getKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33
_ZN4PLMD6Action4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZN4PLMD6Action5fopenEPKcS2_73
_ZN4PLMD6Action6fcloseEP8_IO_FILE91
_ZN4PLMD6Action7warningERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE129
_ZN4PLMD6Action9setOptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE267
_ZNK4PLMD6Action6getCPTEv1091
_ZN4PLMD6ActionD2Ev14104
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE14105
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE14105
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE14107
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE14388
_ZNK4PLMD6Action11getTimeStepEv16248
_ZN4PLMD6Action6fflushEv17862
_ZN4PLMD6Action9checkReadEv27486
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb40532
_ZN4PLMD6Action17clearDependenciesEv188987
_ZN4PLMD6Action7prepareEv316711
_ZN4PLMD6Action13addDependencyEPS0_1083801
_ZNK4PLMD6Action11checkUpdateEv1634506
_ZNK4PLMD6Action7getTimeEv2939688
_ZN4PLMD6Action8activateEv3205166
_ZNK4PLMD6Action7getStepEv4498338
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Action.cpp.func.html b/coverage/core/Action.cpp.func.html new file mode 100644 index 0000000000..25303b2c80 --- /dev/null +++ b/coverage/core/Action.cpp.func.html @@ -0,0 +1,197 @@ + + + + + + + + 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:12115578.1 %
Date:2024-06-10 08:19:14Functions:253180.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE14105
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE14107
_ZN4PLMD6Action10getKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action13addDependencyEPS0_1083801
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE14388
_ZN4PLMD6Action17clearDependenciesEv188987
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6Action5fopenEPKcS2_73
_ZN4PLMD6Action6fcloseEP8_IO_FILE91
_ZN4PLMD6Action6fflushEv17862
_ZN4PLMD6Action7prepareEv316711
_ZN4PLMD6Action7warningERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE129
_ZN4PLMD6Action8activateEv3205166
_ZN4PLMD6Action9checkReadEv27486
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb40532
_ZN4PLMD6Action9setOptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE267
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE14105
_ZN4PLMD6ActionD0Ev0
_ZN4PLMD6ActionD2Ev14104
_ZNK4PLMD6Action11checkUpdateEv1634506
_ZNK4PLMD6Action11getTimeStepEv16248
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZNK4PLMD6Action16getDocumentationB5cxx11Ev0
_ZNK4PLMD6Action5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30
_ZNK4PLMD6Action6getCPTEv1091
_ZNK4PLMD6Action7getStepEv4498338
_ZNK4PLMD6Action7getTimeEv2939688
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Action.cpp.gcov.html b/coverage/core/Action.cpp.gcov.html new file mode 100644 index 0000000000..889b9d55d0 --- /dev/null +++ b/coverage/core/Action.cpp.gcov.html @@ -0,0 +1,359 @@ + + + + + + + + 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:12115578.1 %
Date:2024-06-10 08:19:14Functions:253180.6 %
+
+ + + + + + + + +

+
          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 "ActionWithValue.h"
+      24             : #include "PlumedMain.h"
+      25             : #include "tools/Log.h"
+      26             : #include "tools/Exception.h"
+      27             : #include "Atoms.h"
+      28             : #include "ActionSet.h"
+      29             : #include <iostream>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : Keywords ActionOptions::emptyKeys;
+      34             : 
+      35       14107 : ActionOptions::ActionOptions(PlumedMain&p,const std::vector<std::string>&l):
+      36       14107 :   plumed(p),
+      37       14107 :   line(l),
+      38       14107 :   keys(emptyKeys)
+      39             : {
+      40       14107 : }
+      41             : 
+      42       14105 : ActionOptions::ActionOptions(const ActionOptions&ao,const Keywords&keys):
+      43       14105 :   plumed(ao.plumed),
+      44       14105 :   line(ao.line),
+      45       14105 :   keys(keys)
+      46             : {
+      47       14105 : }
+      48             : 
+      49       14388 : void Action::registerKeywords( Keywords& keys ) {
+      50       14388 :   plumed_assert( keys.size()==0 );
+      51       28776 :   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" );
+      52       28776 :   keys.reserve("optional","UPDATE_FROM","Only update this action from this time");
+      53       28776 :   keys.reserve("optional","UPDATE_UNTIL","Only update this action until this time");
+      54       28776 :   keys.reserve("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
+      55       14388 : }
+      56             : 
+      57       14105 : Action::Action(const ActionOptions&ao):
+      58       14105 :   name(ao.line[0]),
+      59       14105 :   line(ao.line),
+      60       14105 :   update_from(std::numeric_limits<double>::max()),
+      61       14105 :   update_until(std::numeric_limits<double>::max()),
+      62       14105 :   active(false),
+      63       14105 :   restart(ao.plumed.getRestart()),
+      64       14105 :   doCheckPoint(ao.plumed.getCPT()),
+      65       14105 :   plumed(ao.plumed),
+      66       14105 :   log(plumed.getLog()),
+      67       14105 :   comm(plumed.comm),
+      68       14105 :   multi_sim_comm(plumed.multi_sim_comm),
+      69       28210 :   keywords(ao.keys)
+      70             : {
+      71             :   line.erase(line.begin());
+      72       14105 :   log.printf("Action %s\n",name.c_str());
+      73             : 
+      74       14105 :   if(comm.Get_rank()==0) {
+      75        7691 :     replica_index=multi_sim_comm.Get_rank();
+      76             :   }
+      77       14105 :   comm.Bcast(replica_index,0);
+      78             : 
+      79       42128 :   if ( keywords.exists("LABEL") ) { parse("LABEL",label); }
+      80             : 
+      81       14105 :   if(label.length()==0) {
+      82        2289 :     std::string s; Tools::convert(plumed.getActionSet().size(),s);
+      83        4578 :     label="@"+s;
+      84             :   }
+      85       14105 :   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
+      86       14105 :   log.printf("  with label %s\n",label.c_str());
+      87       29847 :   if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
+      88       14105 :   if(update_from!=std::numeric_limits<double>::max()) log.printf("  only update from time %f\n",update_from);
+      89       29847 :   if ( keywords.exists("UPDATE_UNTIL") ) parse("UPDATE_UNTIL",update_until);
+      90       14105 :   if(update_until!=std::numeric_limits<double>::max()) log.printf("  only update until time %f\n",update_until);
+      91       28210 :   if ( keywords.exists("RESTART") ) {
+      92        1683 :     std::string srestart="AUTO";
+      93        3364 :     parse("RESTART",srestart);
+      94        1682 :     if(srestart=="YES") restart=true;
+      95        1601 :     else if(srestart=="NO")  restart=false;
+      96        1579 :     else if(srestart=="AUTO") {
+      97             :       // do nothing, this is the default
+      98           2 :     } else error("RESTART should be either YES, NO, or AUTO");
+      99             :   }
+     100       14105 : }
+     101             : 
+     102       14104 : Action::~Action() {
+     103       14104 :   if(files.size()!=0) {
+     104           0 :     std::cerr<<"WARNING: some files open in action "+getLabel()+" where not properly closed. This could lead to data loss!!\n";
+     105             :   }
+     106       14104 : }
+     107             : 
+     108          73 : FILE* Action::fopen(const char *path, const char *mode) {
+     109             :   bool write(false);
+     110         146 :   for(const char*p=mode; *p; p++) if(*p=='w' || *p=='a' || *p=='+') write=true;
+     111             :   FILE* fp;
+     112          73 :   if(write && comm.Get_rank()!=0) fp=plumed.fopen("/dev/null",mode);
+     113          73 :   else      fp=plumed.fopen(path,mode);
+     114          73 :   files.insert(fp);
+     115          73 :   return fp;
+     116             : }
+     117             : 
+     118          91 : int Action::fclose(FILE*fp) {
+     119             :   files.erase(fp);
+     120          91 :   return plumed.fclose(fp);
+     121             : }
+     122             : 
+     123       17862 : void Action::fflush() {
+     124       17862 :   for(const auto & p : files) {
+     125           0 :     std::fflush(p);
+     126             :   }
+     127       17862 : }
+     128             : 
+     129          33 : std::string Action::getKeyword(const std::string& key) {
+     130             :   // Check keyword has been registered
+     131          33 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     132             : 
+     133             :   std::string outkey;
+     134          33 :   if( Tools::getKey(line,key,outkey ) ) return key + outkey;
+     135             : 
+     136           0 :   if( keywords.style(key,"compulsory") ) {
+     137           0 :     if( keywords.getDefaultValue(key,outkey) ) {
+     138           0 :       if( outkey.length()==0 ) error("keyword " + key + " has weird default value");
+     139           0 :       return key + "=" +  outkey;
+     140             :     } else {
+     141           0 :       error("keyword " + key + " is compulsory for this action");
+     142             :     }
+     143             :   }
+     144           0 :   return "";
+     145             : }
+     146             : 
+     147       40532 : void Action::parseFlag(const std::string&key,bool & t) {
+     148             :   // Check keyword has been registered
+     149       40532 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     150             :   // Check keyword is a flag
+     151       81064 :   if(!keywords.style(key,"nohtml")) {
+     152       78530 :     plumed_massert( keywords.style(key,"vessel") || keywords.style(key,"flag") || keywords.style(key,"hidden"), "keyword " + key + " is not a flag");
+     153             :   }
+     154             : 
+     155             :   // Read in the flag otherwise get the default value from the keywords object
+     156       40532 :   if(!Tools::parseFlag(line,key,t)) {
+     157       80858 :     if( keywords.style(key,"nohtml") || keywords.style(key,"vessel") ) {
+     158        2634 :       t=false;
+     159       72956 :     } else if ( !keywords.getLogicalDefault(key,t) ) {
+     160           0 :       log.printf("ERROR in action %s with label %s : flag %s has no default",name.c_str(),label.c_str(),key.c_str() );
+     161           0 :       plumed_error();
+     162             :     }
+     163             :   }
+     164       40532 : }
+     165             : 
+     166     1083801 : void Action::addDependency(Action*action) {
+     167     1083801 :   after.push_back(action);
+     168     1083801 : }
+     169             : 
+     170     3205166 : void Action::activate() {
+     171             : // preparation step is called only the first time an Action is activated.
+     172             : // since it could change its dependences (e.g. in an ActionAtomistic which is
+     173             : // accessing to a virtual atom), this is done just before dependencies are
+     174             : // activated
+     175     3205166 :   if(!active) {
+     176     1642451 :     this->unlockRequests();
+     177     1642451 :     prepare();
+     178     1642451 :     this->lockRequests();
+     179             :   } else return;
+     180     3577516 :   for(const auto & p : after) p->activate();
+     181     1642451 :   active=true;
+     182             : }
+     183             : 
+     184         267 : void Action::setOption(const std::string &s) {
+     185             : // This overloads the action and activate some options
+     186         267 :   options.insert(s);
+     187         448 :   for(const auto & p : after) p->setOption(s);
+     188         267 : }
+     189             : 
+     190           0 : void Action::clearOptions() {
+     191             : // This overloads the action and activate some options
+     192             :   options.clear();
+     193           0 : }
+     194             : 
+     195             : 
+     196      188987 : void Action::clearDependencies() {
+     197             :   after.clear();
+     198      188987 : }
+     199             : 
+     200           0 : std::string Action::getDocumentation()const {
+     201           0 :   return std::string("UNDOCUMENTED ACTION");
+     202             : }
+     203             : 
+     204       27486 : void Action::checkRead() {
+     205       27486 :   if(!line.empty()) {
+     206           0 :     std::string msg="cannot understand the following words from the input line : ";
+     207           0 :     for(unsigned i=0; i<line.size(); i++) {
+     208           0 :       if(i>0) msg = msg + ", ";
+     209           0 :       msg = msg + line[i];
+     210             :     }
+     211           0 :     error(msg);
+     212             :   }
+     213       27486 : }
+     214             : 
+     215     4498338 : long int Action::getStep()const {
+     216     4498338 :   return plumed.getStep();
+     217             : }
+     218             : 
+     219     2939688 : double Action::getTime()const {
+     220     2939688 :   return plumed.getAtoms().getTimeStep()*getStep();
+     221             : }
+     222             : 
+     223       16248 : double Action::getTimeStep()const {
+     224       16248 :   return plumed.getAtoms().getTimeStep();
+     225             : }
+     226             : 
+     227             : 
+     228             : 
+     229           0 : void Action::exit(int c) {
+     230           0 :   plumed.exit(c);
+     231           0 : }
+     232             : 
+     233           0 : void Action::calculateNumericalDerivatives( ActionWithValue* a ) {
+     234           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");
+     235             : }
+     236             : 
+     237      316711 : void Action::prepare() {
+     238      316711 :   return;
+     239             : }
+     240             : 
+     241          30 : [[noreturn]] void Action::error( const std::string & msg ) const {
+     242          30 :   log.printf("ERROR in input to action %s with label %s : %s \n \n", name.c_str(), label.c_str(), msg.c_str() );
+     243          90 :   plumed_merror("ERROR in input to action " + name + " with label " + label + " : " + msg );
+     244             : }
+     245             : 
+     246         129 : void Action::warning( const std::string & msg ) {
+     247         129 :   log.printf("WARNING for action %s with label %s : %s \n", name.c_str(), label.c_str(), msg.c_str() );
+     248         129 : }
+     249             : 
+     250           0 : void Action::calculateFromPDB( const PDB& pdb ) {
+     251           0 :   activate();
+     252           0 :   for(const auto & p : after) {
+     253           0 :     ActionWithValue*av=dynamic_cast<ActionWithValue*>(p);
+     254           0 :     if(av) { av->clearInputForces(); av->clearDerivatives(); }
+     255           0 :     p->readAtomsFromPDB( pdb );
+     256           0 :     p->calculate();
+     257             :   }
+     258           0 :   readAtomsFromPDB( pdb );
+     259           0 :   calculate();
+     260           0 : }
+     261             : 
+     262       28109 : bool Action::getExchangeStep()const {
+     263       28109 :   return plumed.getExchangeStep();
+     264             : }
+     265             : 
+     266          40 : std::string Action::cite(const std::string&s) {
+     267          40 :   return plumed.cite(s);
+     268             : }
+     269             : 
+     270             : /// Check if action should be updated.
+     271     1634506 : bool Action::checkUpdate()const {
+     272     1634506 :   double t=getTime();
+     273     1634506 :   if(t<update_until && (update_from==std::numeric_limits<double>::max() || t>=update_from)) return true;
+     274         510 :   else return false;
+     275             : }
+     276             : 
+     277        1091 : bool Action::getCPT()const {
+     278        1091 :   return plumed.getCPT();
+     279             : }
+     280             : 
+     281             : }
+     282             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..3dd8cde53c --- /dev/null +++ b/coverage/core/Action.h.func-sort-c.html @@ -0,0 +1,177 @@ + + + + + + + + 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:666995.7 %
Date:2024-06-10 08:19:14Functions:252696.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD6Action19parseNumberedVectorIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE14
_ZN4PLMD6Action5parseImEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_16
_ZN4PLMD6Action11parseVectorIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE31
_ZN4PLMD6Action19parseNumberedVectorIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE32
_ZN4PLMD6Action5parseIlEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_109
_ZN4PLMD6Action11parseVectorIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE515
_ZN4PLMD6Action13parseNumberedIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_1010
_ZN4PLMD6Action19parseNumberedVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE1313
_ZN4PLMD6Action19parseNumberedVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRSt6vectorIT_SaISB_EE2088
_ZN4PLMD6Action5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3532
_ZN4PLMD6Action13parseNumberedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRT_3613
_ZN4PLMD6Action5parseIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5084
_ZN4PLMD6Action5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_7778
_ZN4PLMD6Action11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE11056
_ZN4PLMD6Action12runFinalJobsEv13316
_ZN4PLMD6Action11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RSt6vectorIT_SaISB_EE18348
_ZN4PLMD6Action5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RT_28771
_ZNK4PLMD6Action25checkNumericalDerivativesEv251765
_ZN4PLMD6Action6updateEv412153
_ZN4PLMD6Action12lockRequestsEv945438
_ZN4PLMD6Action14unlockRequestsEv945438
_ZNK4PLMD6Action10isOptionOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1404234
_ZNK4PLMD6Action19checkNeedsGradientsEv1633696
_ZN4PLMD6Action12beforeUpdateEv1806737
_ZN4PLMD6Action10deactivateEv1823622
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Action.h.func.html b/coverage/core/Action.h.func.html new file mode 100644 index 0000000000..6587f2229c --- /dev/null +++ b/coverage/core/Action.h.func.html @@ -0,0 +1,177 @@ + + + + + + + + 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:666995.7 %
Date:2024-06-10 08:19:14Functions:252696.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action10deactivateEv1823622
_ZN4PLMD6Action11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RSt6vectorIT_SaISB_EE18348
_ZN4PLMD6Action11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE11056
_ZN4PLMD6Action11parseVectorIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE31
_ZN4PLMD6Action11parseVectorIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE515
_ZN4PLMD6Action12beforeUpdateEv1806737
_ZN4PLMD6Action12lockRequestsEv945438
_ZN4PLMD6Action12runFinalJobsEv13316
_ZN4PLMD6Action13parseNumberedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRT_3613
_ZN4PLMD6Action13parseNumberedIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_1010
_ZN4PLMD6Action14unlockRequestsEv945438
_ZN4PLMD6Action16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD6Action19parseNumberedVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRSt6vectorIT_SaISB_EE2088
_ZN4PLMD6Action19parseNumberedVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE1313
_ZN4PLMD6Action19parseNumberedVectorIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE32
_ZN4PLMD6Action19parseNumberedVectorIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE14
_ZN4PLMD6Action5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RT_28771
_ZN4PLMD6Action5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_7778
_ZN4PLMD6Action5parseIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5084
_ZN4PLMD6Action5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3532
_ZN4PLMD6Action5parseIlEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_109
_ZN4PLMD6Action5parseImEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_16
_ZN4PLMD6Action6updateEv412153
_ZNK4PLMD6Action10isOptionOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1404234
_ZNK4PLMD6Action19checkNeedsGradientsEv1633696
_ZNK4PLMD6Action25checkNumericalDerivativesEv251765
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Action.h.gcov.html b/coverage/core/Action.h.gcov.html new file mode 100644 index 0000000000..4b8ff90ce1 --- /dev/null +++ b/coverage/core/Action.h.gcov.html @@ -0,0 +1,507 @@ + + + + + + + + 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:666995.7 %
Date:2024-06-10 08:19:14Functions:252696.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_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/Log.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : class PDB;
+      34             : class PlumedMain;
+      35             : class Communicator;
+      36             : class ActionWithValue;
+      37             : 
+      38             : /// This class is used to bring the relevant information to the Action constructor.
+      39             : /// Only Action and ActionRegister class can access to its content, which is
+      40             : /// kept private to other classes, and may change in the future.
+      41       28212 : class ActionOptions {
+      42             :   friend class Action;
+      43             :   friend class ActionRegister;
+      44             : /// Reference to main PlumedMain object
+      45             :   PlumedMain& plumed;
+      46             : /// Input line which sets up the action
+      47             :   std::vector<std::string> line;
+      48             : /// The documentation for this action
+      49             :   const Keywords& keys;
+      50             :   static Keywords emptyKeys;
+      51             : public:
+      52             : /// Constructor
+      53             :   ActionOptions(PlumedMain&p,const std::vector<std::string>&);
+      54             :   ActionOptions(const ActionOptions&,const Keywords& keys);
+      55             : };
+      56             : 
+      57             : /// Base class for all the input Actions.
+      58             : /// The input Actions are more or less corresponding to the directives
+      59             : /// in the plumed.dat file and are applied in order at each time-step.
+      60             : class Action {
+      61             :   friend class ActionShortcut;
+      62             : 
+      63             : /// Name of the directive in the plumed.dat file.
+      64             :   const std::string name;
+      65             : 
+      66             : /// Label of the Action, as set with LABEL= in the plumed.dat file.
+      67             :   std::string label;
+      68             : 
+      69             : /// Directive line.
+      70             : /// This line is progressively erased during Action construction
+      71             : /// so as to check if all the present keywords are correct.
+      72             :   std::vector<std::string> line;
+      73             : 
+      74             : /// Update only after this time.
+      75             :   double update_from;
+      76             : 
+      77             : /// Update only until this time.
+      78             :   double update_until;
+      79             : 
+      80             : public:
+      81             : 
+      82             : /// Check if action should be updated.
+      83             :   bool checkUpdate()const;
+      84             : 
+      85             : public:
+      86             :   typedef std::vector<Action*> Dependencies;
+      87             : 
+      88             : private:
+      89             : /// Actions on which this Action depends.
+      90             :   Dependencies after;
+      91             : 
+      92             : /// Switch to activate Action on this step.
+      93             :   bool active;
+      94             : 
+      95             : /// Option that you might have enabled
+      96             :   std::set<std::string> options;
+      97             : 
+      98             :   bool restart;
+      99             : 
+     100             :   bool doCheckPoint;
+     101             : 
+     102             : public:
+     103             : 
+     104             : /// Reference to main plumed object
+     105             :   PlumedMain& plumed;
+     106             : 
+     107             : /// Reference to the log stream
+     108             :   Log& log;
+     109             : 
+     110             : /// Specify that this Action depends on another one
+     111             :   void addDependency(Action*);
+     112             : 
+     113             : /// Clear the dependence list for this Action
+     114             :   void clearDependencies();
+     115             : 
+     116             : /// Return the present timestep
+     117             :   long int getStep()const;
+     118             : 
+     119             : /// Return the present time
+     120             :   double getTime()const;
+     121             : 
+     122             : /// Return the timestep
+     123             :   double getTimeStep()const;
+     124             : 
+     125             : /// Return true if we are doing a restart
+     126             :   bool getRestart()const;
+     127             : 
+     128             : /// Return true if we are doing at a checkpoint step
+     129             :   bool getCPT()const;
+     130             : 
+     131             : /// Just read one of the keywords and return the whole thing as a string
+     132             :   std::string getKeyword(const std::string& key);
+     133             : 
+     134             : /// Parse one keyword as generic type
+     135             :   template<class T>
+     136             :   void parse(const std::string&key,T&t);
+     137             : 
+     138             : /// Parse one numbered keyword as generic type
+     139             :   template<class T>
+     140             :   bool parseNumbered(const std::string&key, const int no, T&t);
+     141             : 
+     142             : /// Parse one keyword as std::vector
+     143             :   template<class T>
+     144             :   void parseVector(const std::string&key,std::vector<T>&t);
+     145             : 
+     146             : /// Parse a vector with a number
+     147             :   template<class T>
+     148             :   bool parseNumberedVector(const std::string& key, const int no, std::vector<T>&t);
+     149             : 
+     150             : /// Parse one keyword as boolean flag
+     151             :   void parseFlag(const std::string&key,bool&t);
+     152             : 
+     153             : /// Crash calculation and print documentation
+     154             :   [[noreturn]] void error( const std::string & msg ) const;
+     155             : 
+     156             : /// Issue a warning
+     157             :   void warning( const std::string & msg );
+     158             : 
+     159             : /// Exit with error code c
+     160             :   void exit(int c=0);
+     161             : 
+     162             : ///
+     163             :   std::set<FILE*> files;
+     164             : 
+     165             : public:
+     166             : /// Standard constructor from ActionOptions
+     167             :   explicit Action(const ActionOptions&);
+     168             : /// Destructor
+     169             :   virtual ~Action();
+     170             : private:
+     171             : /// Copy constructor is deleted
+     172             :   Action(const Action&a) = delete;
+     173             : /// Assignment operator is deleted
+     174             :   Action& operator=(const Action&a) = delete;
+     175             :   int replica_index;
+     176             : public:
+     177             : /// Check if Action was properly read.
+     178             : /// This checks if Action::line is empty. It must be called after
+     179             : /// a final Action has been initialized
+     180             :   void checkRead();
+     181             : 
+     182             :   Communicator& comm;
+     183             :   Communicator& multi_sim_comm;
+     184             : 
+     185             :   const Keywords& keywords;
+     186             : /// Prepare an Action for calculation
+     187             : /// This can be used by Action if they need some special preparation
+     188             : /// before calculation. Typical case is for collective variables
+     189             : /// which would like to change their list of requested atoms.
+     190             : /// By default (if not overridden) does nothing.
+     191             :   virtual void prepare();
+     192             : 
+     193             : /// Register all the relevant keywords for the action
+     194             :   static void registerKeywords( Keywords& keys );
+     195             : 
+     196      945438 :   virtual void lockRequests() {}
+     197      945438 :   virtual void unlockRequests() {}
+     198             : 
+     199             : /// Calculate an Action.
+     200             : /// This method is called one or more times per step.
+     201             : /// The set of all Actions is calculated in forward order.
+     202             :   virtual void calculate()=0;
+     203             : 
+     204             : /// Apply an Action.
+     205             : /// This method is called one time per step.
+     206             : /// The set of all Actions is applied in backward order.
+     207             :   virtual void apply()=0;
+     208             : 
+     209             : /// Before Update.
+     210             : /// This is a special method that is called just
+     211             : /// before the update() method. It can be used by
+     212             : /// actions that want to do something irrespectively
+     213             : /// of the fact that update() is active or not.
+     214             : /// In other words, this is *always* called, even when action
+     215             : /// is not active.
+     216     1806737 :   virtual void beforeUpdate() {}
+     217             : 
+     218             : /// Update.
+     219             : /// This method is called one time per step.
+     220             : /// The set of all Actions is updated in forward order.
+     221      412153 :   virtual void update() {}
+     222             : 
+     223             : /// RunFinalJobs
+     224             : /// This method is called once at the very end of the calculation.
+     225             : /// The set of all Actions in run for the final time in forward order.
+     226       13316 :   virtual void runFinalJobs() {}
+     227             : 
+     228             : /// Tell to the Action to flush open files
+     229             :   void fflush();
+     230             : 
+     231             :   virtual std::string getDocumentation()const;
+     232             : 
+     233             : /// Returns the label
+     234             :   const std::string & getLabel()const;
+     235             : 
+     236             : /// Returns the name
+     237             :   const std::string & getName()const;
+     238             : 
+     239             : /// Set action to active
+     240             :   virtual void activate();
+     241             : 
+     242             : ///
+     243             :   virtual void setOption(const std::string &s);
+     244             : 
+     245             :   virtual void clearOptions();
+     246             : 
+     247             : /// Set action to inactive
+     248             :   virtual void deactivate();
+     249             : 
+     250             : /// Check if action is active
+     251             :   bool isActive()const;
+     252             : 
+     253             : /// Check if an option is on
+     254             :   bool isOptionOn(const std::string &s)const;
+     255             : 
+     256             : /// Return dependencies
+     257             :   const Dependencies & getDependencies()const {return after;}
+     258             : 
+     259             : /// Check if numerical derivatives should be performed
+     260      251765 :   virtual bool checkNumericalDerivatives()const {return false;}
+     261             : 
+     262             : /// Check if the action needs gradient
+     263     1633696 :   virtual bool checkNeedsGradients()const {return false;}
+     264             : 
+     265             : /// Perform calculation using numerical derivatives
+     266             : /// N.B. only pass an ActionWithValue to this routine if you know exactly what you
+     267             : /// are doing.
+     268             :   virtual void calculateNumericalDerivatives( ActionWithValue* a=NULL );
+     269             : 
+     270             : /// Opens a file.
+     271             : /// This is similar to plain fopen, but with some extra functionality.
+     272             : /// * When opened for writing, processors other than the one with rank 0 just open /dev/null
+     273             : /// * PlumedMain::fopen is used, so that other tricks may appear (see \ref PlumedMain::fopen)
+     274             :   FILE *fopen(const char *path, const char *mode);
+     275             : /// Closes a file opened with Action::fclose().
+     276             :   int   fclose(FILE*fp);
+     277             : 
+     278             : /// Calculate the action given a pdb file as input.  This is used to initialize
+     279             : /// things like distance from a point in CV map space given a pdb as an input file
+     280             :   void calculateFromPDB( const PDB&  );
+     281             : /// This is overwritten in ActionAtomistic so that we can read
+     282             : /// the atoms from the pdb input file rather than taking them from the
+     283             : /// MD code
+     284           0 :   virtual void readAtomsFromPDB( const PDB&  ) {}
+     285             : /// Check if we are on an exchange step
+     286             :   bool getExchangeStep()const;
+     287             : 
+     288             : /// Cite a paper see PlumedMain::cite
+     289             :   std::string cite(const std::string&s);
+     290             : };
+     291             : 
+     292             : /////////////////////
+     293             : // FAST INLINE METHODS
+     294             : 
+     295             : inline
+     296             : const std::string & Action::getLabel()const {
+     297    60592886 :   return label;
+     298             : }
+     299             : 
+     300             : inline
+     301             : const std::string & Action::getName()const {
+     302        7713 :   return name;
+     303             : }
+     304             : 
+     305             : template<class T>
+     306       45290 : void Action::parse(const std::string&key,T&t) {
+     307             : //  if(!Tools::parse(line,key,t)){
+     308             : //    log.printf("ERROR parsing keyword %s\n",key.c_str());
+     309             : //    log.printf("%s\n",getDocumentation().c_str());
+     310             : //    this->exit(1);
+     311             : //  }
+     312             :   // Check keyword has been registered
+     313       45290 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     314             : 
+     315             :   // Now try to read the keyword
+     316             :   std::string def;
+     317       45290 :   bool present=Tools::findKeyword(line,key);
+     318       45290 :   bool found=Tools::parse(line,key,t,replica_index);
+     319       45293 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     320             : 
+     321             :   // If it isn't read and it is compulsory see if a default value was specified
+     322       93364 :   if ( !found && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+     323       15194 :     if( keywords.getDefaultValue(key,def) ) {
+     324        2479 :       if( def.length()==0 || !Tools::convertNoexcept(def,t) ) {
+     325           0 :         plumed_error() <<"ERROR in action "<<name<<" with label "<<label<<" : keyword "<<key<<" has weird default value";
+     326             :       }
+     327       10236 :     } else if( keywords.style(key,"compulsory") ) {
+     328           3 :       error("keyword " + key + " is compulsory for this action");
+     329             :     }
+     330             :   }
+     331       45287 : }
+     332             : 
+     333             : template<class T>
+     334        4623 : bool Action::parseNumbered(const std::string&key, const int no, T&t) {
+     335             :   // Check keyword has been registered
+     336        4623 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     337        4623 :   if( !keywords.numbered(key) ) error("numbered keywords are not allowed for " + key );
+     338             : 
+     339             :   // Now try to read the keyword
+     340        4623 :   std::string num; Tools::convert(no,num);
+     341        9246 :   return Tools::parse(line,key+num,t,replica_index);
+     342             : }
+     343             : 
+     344             : template<class T>
+     345       29950 : void Action::parseVector(const std::string&key,std::vector<T>&t) {
+     346             : //  if(!Tools::parseVector(line,key,t)){
+     347             : //    log.printf("ERROR parsing keyword %s\n",key.c_str());
+     348             : //    log.printf("%s\n",getDocumentation().c_str());
+     349             : //    this->exit(1);
+     350             : //  }
+     351             : 
+     352             :   // Check keyword has been registered
+     353       29950 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     354       29950 :   unsigned size=t.size(); bool skipcheck=false;
+     355       29950 :   if(size==0) skipcheck=true;
+     356             : 
+     357             :   // Now try to read the keyword
+     358             :   std::string def; T val;
+     359       29950 :   bool present=Tools::findKeyword(line,key);
+     360       29950 :   bool found=Tools::parseVector(line,key,t,replica_index);
+     361       29951 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     362             : 
+     363             :   // Check vectors size is correct (not if this is atoms or ARG)
+     364       59898 :   if( !keywords.style(key,"atoms") && found ) {
+     365             : //     bool skipcheck=false;
+     366             : //     if( keywords.style(key,"compulsory") ){ keywords.getDefaultValue(key,def); skipcheck=(def=="nosize"); }
+     367       13485 :     if( !skipcheck && t.size()!=size ) error("vector read in for keyword " + key + " has the wrong size");
+     368             :   }
+     369             : 
+     370             :   // If it isn't read and it is compulsory see if a default value was specified
+     371       42958 :   if ( !found && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+     372        1876 :     if( keywords.getDefaultValue(key,def) ) {
+     373         836 :       if( def.length()==0 || !Tools::convertNoexcept(def,val) ) {
+     374           0 :         plumed_error() <<"ERROR in action "<<name<<" with label "<<label<<" : keyword "<<key<<" has weird default value";
+     375             :       } else {
+     376        2422 :         if(t.size()>0) for(unsigned i=0; i<t.size(); ++i) t[i]=val;
+     377         236 :         else t.push_back(val);
+     378             :       }
+     379         204 :     } else if( keywords.style(key,"compulsory") ) {
+     380           4 :       error("keyword " + key + " is compulsory for this action");
+     381             :     }
+     382       29008 :   } else if ( !found ) {
+     383        5935 :     t.resize(0);
+     384             :   }
+     385       29946 : }
+     386             : 
+     387             : template<class T>
+     388        3447 : bool Action::parseNumberedVector(const std::string&key, const int no, std::vector<T>&t) {
+     389        3447 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     390        3447 :   if( !keywords.numbered(key) ) error("numbered keywords are not allowed for " + key );
+     391             : 
+     392        3447 :   unsigned size=t.size(); bool skipcheck=false;
+     393        3447 :   if(size==0) skipcheck=true;
+     394        3447 :   std::string num; Tools::convert(no,num);
+     395        3447 :   bool present=Tools::findKeyword(line,key);
+     396        3447 :   bool found=Tools::parseVector(line,key+num,t,replica_index);
+     397        3447 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     398             : 
+     399        6894 :   if(  keywords.style(key,"compulsory") ) {
+     400          90 :     if (!skipcheck && found && t.size()!=size ) error("vector read in for keyword " + key + num + " has the wrong size");
+     401        3357 :   } else if ( !found ) {
+     402         992 :     t.resize(0);
+     403             :   }
+     404        3447 :   return found;
+     405             : }
+     406             : 
+     407             : inline
+     408     1823622 : void Action::deactivate() {
+     409             :   options.clear();
+     410     1823622 :   active=false;
+     411     1823622 : }
+     412             : 
+     413             : inline
+     414             : bool Action::isActive()const {
+     415     7612264 :   return active;
+     416             : }
+     417             : 
+     418             : inline
+     419     1404234 : bool Action::isOptionOn(const std::string &s)const {
+     420     1404234 :   return options.count(s);
+     421             : }
+     422             : 
+     423             : inline
+     424             : bool Action::getRestart()const {
+     425        3486 :   return restart;
+     426             : }
+     427             : 
+     428             : }
+     429             : #endif
+     430             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..6a3be291f6 --- /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-06-10 08:19:14Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE102
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.func.html b/coverage/core/ActionAnyorder.cpp.func.html new file mode 100644 index 0000000000..72c18cbcbc --- /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-06-10 08:19:14Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE102
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.gcov.html b/coverage/core/ActionAnyorder.cpp.gcov.html new file mode 100644 index 0000000000..c2cc0f53b7 --- /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-06-10 08:19:14Functions: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         102 : ActionAnyorder::ActionAnyorder(const ActionOptions&ao):
+      30         102 :   Action(ao)
+      31             : {
+      32         102 : }
+      33             : 
+      34           0 : void ActionAnyorder::registerKeywords( Keywords& keys ) {
+      35           0 :   Action::registerKeywords(keys);
+      36           0 : }
+      37             : 
+      38             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ffc28710d2 --- /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-06-10 08:19:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder5applyEv0
_ZN4PLMD14ActionAnyorder9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.func.html b/coverage/core/ActionAnyorder.h.func.html new file mode 100644 index 0000000000..7c975fdedb --- /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-06-10 08:19:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder5applyEv0
_ZN4PLMD14ActionAnyorder9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.gcov.html b/coverage/core/ActionAnyorder.h.gcov.html new file mode 100644 index 0000000000..ae3b5daf23 --- /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-06-10 08:19:14Functions: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          84 : 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.15
+
+ + + 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 0000000000..e5c081f854 --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func-sort-c.html @@ -0,0 +1,161 @@ + + + + + + + + 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:16818391.8 %
Date:2024-06-10 08:19:14Functions:172277.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD15ActionAtomistic9changeBoxERKNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD15ActionAtomisticC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionAtomisticD0Ev0
_ZN4PLMD15ActionAtomisticD1Ev0
_ZN4PLMD15ActionAtomistic29calculateNumericalDerivativesEPNS_15ActionWithValueE195
_ZN4PLMD15ActionAtomistic35calculateAtomicNumericalDerivativesEPNS_15ActionWithValueERKj492
_ZN4PLMD15ActionAtomistic16setForcesOnAtomsERKSt6vectorIdSaIdEEj624
_ZN4PLMD15ActionAtomisticC2ERKNS_13ActionOptionsE10109
_ZN4PLMD15ActionAtomisticD2Ev10109
_ZN4PLMD15ActionAtomistic12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EEb10145
_ZN4PLMD15ActionAtomistic16registerKeywordsERNS_8KeywordsE10199
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_INS_10AtomNumberESaISB_EE11274
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE11601
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_10AtomNumberESaISA_EE13577
_ZN4PLMD15ActionAtomistic17updateUniqueLocalEv19794
_ZN4PLMD15ActionAtomistic9makeWholeEv106195
_ZN4PLMD15ActionAtomistic11applyForcesEv157858
_ZN4PLMD15ActionAtomistic13retrieveAtomsEv158317
_ZN4PLMD15ActionAtomistic17clearOutputForcesEv158317
_ZNK4PLMD15ActionAtomistic8pbcApplyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj220567
_ZNK4PLMD15ActionAtomistic11pbcDistanceERKNS_13VectorGenericILj3EEES4_180302983
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.func.html b/coverage/core/ActionAtomistic.cpp.func.html new file mode 100644 index 0000000000..fd2acf7855 --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func.html @@ -0,0 +1,161 @@ + + + + + + + + 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:16818391.8 %
Date:2024-06-10 08:19:14Functions:172277.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic11applyForcesEv157858
_ZN4PLMD15ActionAtomistic12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EEb10145
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE11601
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_10AtomNumberESaISA_EE13577
_ZN4PLMD15ActionAtomistic13retrieveAtomsEv158317
_ZN4PLMD15ActionAtomistic16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD15ActionAtomistic16registerKeywordsERNS_8KeywordsE10199
_ZN4PLMD15ActionAtomistic16setForcesOnAtomsERKSt6vectorIdSaIdEEj624
_ZN4PLMD15ActionAtomistic17clearOutputForcesEv158317
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_INS_10AtomNumberESaISB_EE11274
_ZN4PLMD15ActionAtomistic17updateUniqueLocalEv19794
_ZN4PLMD15ActionAtomistic29calculateNumericalDerivativesEPNS_15ActionWithValueE195
_ZN4PLMD15ActionAtomistic35calculateAtomicNumericalDerivativesEPNS_15ActionWithValueERKj492
_ZN4PLMD15ActionAtomistic9changeBoxERKNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD15ActionAtomistic9makeWholeEv106195
_ZN4PLMD15ActionAtomisticC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionAtomisticC2ERKNS_13ActionOptionsE10109
_ZN4PLMD15ActionAtomisticD0Ev0
_ZN4PLMD15ActionAtomisticD1Ev0
_ZN4PLMD15ActionAtomisticD2Ev10109
_ZNK4PLMD15ActionAtomistic11pbcDistanceERKNS_13VectorGenericILj3EEES4_180302983
_ZNK4PLMD15ActionAtomistic8pbcApplyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj220567
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.gcov.html b/coverage/core/ActionAtomistic.cpp.gcov.html new file mode 100644 index 0000000000..8e92f07968 --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.gcov.html @@ -0,0 +1,383 @@ + + + + + + + + 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:16818391.8 %
Date:2024-06-10 08:19:14Functions:172277.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 "ActionAtomistic.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionSet.h"
+      25             : #include "GenericMolInfo.h"
+      26             : #include <vector>
+      27             : #include <string>
+      28             : #include "ActionWithValue.h"
+      29             : #include "Colvar.h"
+      30             : #include "ActionWithVirtualAtom.h"
+      31             : #include "tools/Exception.h"
+      32             : #include "Atoms.h"
+      33             : #include "tools/Pbc.h"
+      34             : #include "tools/PDB.h"
+      35             : 
+      36             : namespace PLMD {
+      37             : 
+      38       10109 : ActionAtomistic::~ActionAtomistic() {
+      39             : // forget the pending request
+      40       10109 :   atoms.remove(this);
+      41       10109 : }
+      42             : 
+      43       10109 : ActionAtomistic::ActionAtomistic(const ActionOptions&ao):
+      44             :   Action(ao),
+      45       10109 :   lockRequestAtoms(false),
+      46       10109 :   donotretrieve(false),
+      47       10109 :   donotforce(false),
+      48       10109 :   atoms(plumed.getAtoms())
+      49             : {
+      50       10109 :   atoms.add(this);
+      51             : //  if(atoms.getNatoms()==0) error("Cannot perform calculations involving atoms without atoms");
+      52       10109 : }
+      53             : 
+      54       10199 : void ActionAtomistic::registerKeywords( Keywords& keys ) {
+      55             :   (void) keys; // avoid warning
+      56       10199 : }
+      57             : 
+      58             : 
+      59       10145 : void ActionAtomistic::requestAtoms(const std::vector<AtomNumber> & a, const bool clearDep) {
+      60       10145 :   plumed_massert(!lockRequestAtoms,"requested atom list can only be changed in the prepare() method");
+      61       10145 :   int nat=a.size();
+      62       10145 :   indexes=a;
+      63       10145 :   positions.resize(nat);
+      64       10145 :   forces.resize(nat);
+      65       10145 :   masses.resize(nat);
+      66       10145 :   charges.resize(nat);
+      67       10145 :   int n=atoms.positions.size();
+      68       10145 :   if(clearDep) clearDependencies();
+      69             :   unique.clear();
+      70     1180256 :   for(unsigned i=0; i<indexes.size(); i++) {
+      71     1170114 :     if(indexes[i].index()>=n) { std::string num; Tools::convert( indexes[i].serial(),num ); error("atom " + num + " out of range"); }
+      72     1170111 :     if(atoms.isVirtualAtom(indexes[i])) addDependency(atoms.getVirtualAtomsAction(indexes[i]));
+      73             : // only real atoms are requested to lower level Atoms class
+      74     1162890 :     else unique.insert(indexes[i]);
+      75             :   }
+      76       10144 :   updateUniqueLocal();
+      77       10144 :   atoms.unique.clear();
+      78       10144 : }
+      79             : 
+      80   180302983 : Vector ActionAtomistic::pbcDistance(const Vector &v1,const Vector &v2)const {
+      81   180302983 :   return pbc.distance(v1,v2);
+      82             : }
+      83             : 
+      84      220567 : void ActionAtomistic::pbcApply(std::vector<Vector>& dlist, unsigned max_index)const {
+      85      220567 :   pbc.apply(dlist, max_index);
+      86      220567 : }
+      87             : 
+      88         195 : void ActionAtomistic::calculateNumericalDerivatives( ActionWithValue* a ) {
+      89         195 :   calculateAtomicNumericalDerivatives( a, 0 );
+      90         195 : }
+      91             : 
+      92           0 : void ActionAtomistic::changeBox( const Tensor& newbox ) {
+      93           0 :   pbc.setBox( newbox );
+      94           0 : }
+      95             : 
+      96         492 : void ActionAtomistic::calculateAtomicNumericalDerivatives( ActionWithValue* a, const unsigned& startnum ) {
+      97         492 :   if(!a) {
+      98         279 :     a=dynamic_cast<ActionWithValue*>(this);
+      99         279 :     plumed_massert(a,"only Actions with a value can be differentiated");
+     100             :   }
+     101             : 
+     102         492 :   const size_t nval=a->getNumberOfComponents();
+     103         492 :   const size_t natoms=getNumberOfAtoms();
+     104         492 :   std::vector<Vector> value(nval*natoms);
+     105         492 :   std::vector<Tensor> valuebox(nval);
+     106         492 :   std::vector<Vector> savedPositions(natoms);
+     107             :   const double delta=std::sqrt(epsilon);
+     108             : 
+     109       91856 :   for(int i=0; i<natoms; i++) for(int k=0; k<3; k++) {
+     110       68523 :       savedPositions[i][k]=positions[i][k];
+     111       68523 :       positions[i][k]=positions[i][k]+delta;
+     112       68523 :       a->calculate();
+     113       68523 :       positions[i][k]=savedPositions[i][k];
+     114      202917 :       for(int j=0; j<nval; j++) {
+     115      134394 :         value[j*natoms+i][k]=a->getOutputQuantity(j);
+     116             :       }
+     117             :     }
+     118         492 :   Tensor box(pbc.getBox());
+     119        6396 :   for(int i=0; i<3; i++) for(int k=0; k<3; k++) {
+     120        4428 :       double arg0=box(i,k);
+     121      209997 :       for(int j=0; j<natoms; j++) positions[j]=pbc.realToScaled(positions[j]);
+     122        4428 :       box(i,k)=box(i,k)+delta;
+     123        4428 :       pbc.setBox(box);
+     124      209997 :       for(int j=0; j<natoms; j++) positions[j]=pbc.scaledToReal(positions[j]);
+     125        4428 :       a->calculate();
+     126        4428 :       box(i,k)=arg0;
+     127        4428 :       pbc.setBox(box);
+     128      209997 :       for(int j=0; j<natoms; j++) positions[j]=savedPositions[j];
+     129       19512 :       for(int j=0; j<nval; j++) valuebox[j](i,k)=a->getOutputQuantity(j);
+     130             :     }
+     131             : 
+     132         492 :   a->calculate();
+     133         492 :   a->clearDerivatives();
+     134        2168 :   for(int j=0; j<nval; j++) {
+     135        1676 :     Value* v=a->copyOutput(j);
+     136             :     double ref=v->get();
+     137        1676 :     if(v->hasDerivatives()) {
+     138      100117 :       for(int i=0; i<natoms; i++) for(int k=0; k<3; k++) {
+     139       74532 :           double d=(value[j*natoms+i][k]-ref)/delta;
+     140       74532 :           v->addDerivative(startnum+3*i+k,d);
+     141             :         }
+     142         741 :       Tensor virial;
+     143        9633 :       for(int i=0; i<3; i++) for(int k=0; k<3; k++)virial(i,k)= (valuebox[j](i,k)-ref)/delta;
+     144             : // BE CAREFUL WITH NON ORTHOROMBIC CELL
+     145         741 :       virial=-matmul(box.transpose(),virial);
+     146        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));
+     147             :     }
+     148             :   }
+     149         492 : }
+     150             : 
+     151       11601 : void ActionAtomistic::parseAtomList(const std::string&key, std::vector<AtomNumber> &t) {
+     152       11601 :   parseAtomList(key,-1,t);
+     153       11600 : }
+     154             : 
+     155       13577 : void ActionAtomistic::parseAtomList(const std::string&key,const int num, std::vector<AtomNumber> &t) {
+     156       13577 :   plumed_massert( keywords.style(key,"atoms") || keywords.style(key,"hidden"), "keyword " + key + " should be registered as atoms");
+     157             :   std::vector<std::string> strings;
+     158       13577 :   if( num<0 ) {
+     159       11601 :     parseVector(key,strings);
+     160       11600 :     if(strings.empty()) return;
+     161             :   } else {
+     162        1976 :     if ( !parseNumberedVector(key,num,strings) ) return;
+     163             :   }
+     164       11075 :   interpretAtomList( strings, t );
+     165       13577 : }
+     166             : 
+     167       11274 : void ActionAtomistic::interpretAtomList(std::vector<std::string>& strings, std::vector<AtomNumber> &t) {
+     168       11274 :   Tools::interpretRanges(strings); t.resize(0);
+     169      250699 :   for(unsigned i=0; i<strings.size(); ++i) {
+     170             :     AtomNumber atom;
+     171      239425 :     bool ok=Tools::convertNoexcept(strings[i],atom); // this is converting strings to AtomNumbers
+     172      239425 :     if(ok) t.push_back(atom);
+     173             : // here we check if this is a special symbol for MOLINFO
+     174      239425 :     if( !ok && strings[i].compare(0,1,"@")==0 ) {
+     175         631 :       std::string symbol=strings[i].substr(1);
+     176         631 :       if(symbol=="allatoms") {
+     177          10 :         const auto n=plumed.getAtoms().getNatoms() + plumed.getAtoms().getNVirtualAtoms();
+     178          10 :         t.reserve(t.size()+n);
+     179         365 :         for(unsigned i=0; i<n; i++) t.push_back(AtomNumber::index(i));
+     180             :         ok=true;
+     181         621 :       } else if(symbol=="mdatoms") {
+     182           4 :         const auto n=plumed.getAtoms().getNatoms();
+     183           4 :         t.reserve(t.size()+n);
+     184         228 :         for(unsigned i=0; i<n; i++) t.push_back(AtomNumber::index(i));
+     185             :         ok=true;
+     186             :       } else {
+     187         617 :         auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     188         617 :         if( moldat ) {
+     189         617 :           std::vector<AtomNumber> atom_list; moldat->interpretSymbol( symbol, atom_list );
+     190         617 :           if( atom_list.size()>0 ) { ok=true; t.insert(t.end(),atom_list.begin(),atom_list.end()); }
+     191           0 :           else { error(strings[i] + " is not a label plumed knows"); }
+     192             :         } else {
+     193           0 :           error("atoms specified using @ symbol but no MOLINFO was available");
+     194             :         }
+     195             :       }
+     196             :     }
+     197             : // here we check if the atom name is the name of a group
+     198      238794 :     if(!ok) {
+     199        7596 :       if(atoms.groups.count(strings[i])) {
+     200             :         const auto m=atoms.groups.find(strings[i]);
+     201         381 :         t.insert(t.end(),m->second.begin(),m->second.end());
+     202             :         ok=true;
+     203             :       }
+     204             :     }
+     205             : // here we check if the atom name is the name of an added virtual atom
+     206      239044 :     if(!ok) {
+     207        7215 :       const ActionSet&actionSet(plumed.getActionSet());
+     208     6088154 :       for(const auto & a : actionSet) {
+     209     6088154 :         ActionWithVirtualAtom* c=dynamic_cast<ActionWithVirtualAtom*>(a.get());
+     210     6088154 :         if(c) if(c->getLabel()==strings[i]) {
+     211             :             ok=true;
+     212        7215 :             t.push_back(c->getIndex());
+     213             :             break;
+     214             :           }
+     215             :       }
+     216             :     }
+     217      232210 :     if(!ok) error("it was not possible to interpret atom name " + strings[i]);
+     218             :     // plumed_massert(ok,"it was not possible to interpret atom name " + strings[i]);
+     219             :   }
+     220       11274 : }
+     221             : 
+     222      158317 : void ActionAtomistic::retrieveAtoms() {
+     223      158317 :   pbc=atoms.pbc;
+     224      158317 :   Colvar*cc=dynamic_cast<Colvar*>(this);
+     225      158317 :   if(cc && cc->checkIsEnergy()) energy=atoms.getEnergy();
+     226      158317 :   if(donotretrieve) return;
+     227      154425 :   chargesWereSet=atoms.chargesWereSet();
+     228             :   const std::vector<Vector> & p(atoms.positions);
+     229             :   const std::vector<double> & c(atoms.charges);
+     230             :   const std::vector<double> & m(atoms.masses);
+     231     3688318 :   for(unsigned j=0; j<indexes.size(); j++) positions[j]=p[indexes[j].index()];
+     232     3688318 :   for(unsigned j=0; j<indexes.size(); j++) charges[j]=c[indexes[j].index()];
+     233     3688318 :   for(unsigned j=0; j<indexes.size(); j++) masses[j]=m[indexes[j].index()];
+     234             : }
+     235             : 
+     236         624 : void ActionAtomistic::setForcesOnAtoms(const std::vector<double>& forcesToApply, unsigned ind) {
+     237         624 :   if(donotforce) return;
+     238      213170 :   for(unsigned i=0; i<indexes.size(); ++i) {
+     239      212546 :     forces[i][0]=forcesToApply[ind]; ind++;
+     240      212546 :     forces[i][1]=forcesToApply[ind]; ind++;
+     241      212546 :     forces[i][2]=forcesToApply[ind]; ind++;
+     242             :   }
+     243         624 :   virial(0,0)=forcesToApply[ind]; ind++;
+     244         624 :   virial(0,1)=forcesToApply[ind]; ind++;
+     245         624 :   virial(0,2)=forcesToApply[ind]; ind++;
+     246         624 :   virial(1,0)=forcesToApply[ind]; ind++;
+     247         624 :   virial(1,1)=forcesToApply[ind]; ind++;
+     248         624 :   virial(1,2)=forcesToApply[ind]; ind++;
+     249         624 :   virial(2,0)=forcesToApply[ind]; ind++;
+     250         624 :   virial(2,1)=forcesToApply[ind]; ind++;
+     251         624 :   virial(2,2)=forcesToApply[ind];
+     252             :   plumed_dbg_assert( ind+1==forcesToApply.size());
+     253             : }
+     254             : 
+     255      157858 : void ActionAtomistic::applyForces() {
+     256      157858 :   if(donotforce) return;
+     257      153966 :   std::vector<Vector>& f(atoms.forces);
+     258      153966 :   Tensor& v(atoms.virial);
+     259     3668372 :   for(unsigned j=0; j<indexes.size(); j++) f[indexes[j].index()]+=forces[j];
+     260      153966 :   v+=virial;
+     261      153966 :   atoms.forceOnEnergy+=forceOnEnergy;
+     262      153966 :   if(extraCV.length()>0) atoms.updateExtraCVForce(extraCV,forceOnExtraCV);
+     263             : }
+     264             : 
+     265      158317 : void ActionAtomistic::clearOutputForces() {
+     266      158317 :   virial.zero();
+     267      158317 :   if(donotforce) return;
+     268     3688318 :   for(unsigned i=0; i<forces.size(); ++i) forces[i].zero();
+     269      154425 :   forceOnEnergy=0.0;
+     270      154425 :   forceOnExtraCV=0.0;
+     271             : }
+     272             : 
+     273             : 
+     274           0 : void ActionAtomistic::readAtomsFromPDB(const PDB& pdb) {
+     275           0 :   Colvar*cc=dynamic_cast<Colvar*>(this);
+     276           0 :   if(cc && cc->checkIsEnergy()) error("can't read energies from pdb files");
+     277             : 
+     278           0 :   for(unsigned j=0; j<indexes.size(); j++) {
+     279           0 :     if( indexes[j].index()>pdb.size() ) error("there are not enough atoms in the input pdb file");
+     280           0 :     if( pdb.getAtomNumbers()[j].index()!=indexes[j].index() ) error("there are atoms missing in the pdb file");
+     281           0 :     positions[j]=pdb.getPositions()[indexes[j].index()];
+     282             :   }
+     283           0 :   for(unsigned j=0; j<indexes.size(); j++) charges[j]=pdb.getBeta()[indexes[j].index()];
+     284           0 :   for(unsigned j=0; j<indexes.size(); j++) masses[j]=pdb.getOccupancy()[indexes[j].index()];
+     285           0 : }
+     286             : 
+     287      106195 : void ActionAtomistic::makeWhole() {
+     288     1150846 :   for(unsigned j=0; j<positions.size()-1; ++j) {
+     289             :     const Vector & first (positions[j]);
+     290     1044651 :     Vector & second (positions[j+1]);
+     291     1044651 :     second=first+pbcDistance(first,second);
+     292             :   }
+     293      106195 : }
+     294             : 
+     295       19794 : void ActionAtomistic::updateUniqueLocal() {
+     296             :   unique_local.clear();
+     297       19794 :   if(atoms.dd && atoms.shuffledAtoms>0) {
+     298       91318 :     for(auto pp=unique.begin(); pp!=unique.end(); ++pp) {
+     299       81612 :       if(atoms.g2l[pp->index()]>=0) unique_local.insert(*pp);
+     300             :     }
+     301             :   } else {
+     302       10088 :     unique_local.insert(unique.begin(),unique.end());
+     303             :   }
+     304       19794 : }
+     305             : 
+     306             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..a811eb7b25 --- /dev/null +++ b/coverage/core/ActionAtomistic.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + 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:3232100.0 %
Date:2024-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15ActionAtomistic18getAbsoluteIndexesEv160
_ZNK4PLMD15ActionAtomistic9getChargeEi63872
_ZN4PLMD15ActionAtomistic12lockRequestsEv144327
_ZN4PLMD15ActionAtomistic14unlockRequestsEv144327
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionAtomistic.h.func.html b/coverage/core/ActionAtomistic.h.func.html new file mode 100644 index 0000000000..8a9f19f1ab --- /dev/null +++ b/coverage/core/ActionAtomistic.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + 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:3232100.0 %
Date:2024-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic12lockRequestsEv144327
_ZN4PLMD15ActionAtomistic14unlockRequestsEv144327
_ZNK4PLMD15ActionAtomistic18getAbsoluteIndexesEv160
_ZNK4PLMD15ActionAtomistic9getChargeEi63872
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionAtomistic.h.gcov.html b/coverage/core/ActionAtomistic.h.gcov.html new file mode 100644 index 0000000000..6364f6379a --- /dev/null +++ b/coverage/core/ActionAtomistic.h.gcov.html @@ -0,0 +1,399 @@ + + + + + + + + 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:3232100.0 %
Date:2024-06-10 08:19:14Functions: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_ActionAtomistic_h
+      23             : #define __PLUMED_core_ActionAtomistic_h
+      24             : 
+      25             : #include "Action.h"
+      26             : #include "tools/Tensor.h"
+      27             : #include "Atoms.h"
+      28             : #include "tools/Pbc.h"
+      29             : #include "tools/ForwardDecl.h"
+      30             : #include <vector>
+      31             : #include <set>
+      32             : #include <map>
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : class Pbc;
+      37             : class PDB;
+      38             : 
+      39             : /// \ingroup MULTIINHERIT
+      40             : /// Action used to create objects that access the positions of the atoms from the MD code
+      41             : class ActionAtomistic :
+      42             :   virtual public Action
+      43             : {
+      44             : 
+      45             :   std::vector<AtomNumber> indexes;         // the set of needed atoms
+      46             : /// unique should be an ordered set since we later create a vector containing the corresponding indexes
+      47             :   std::set<AtomNumber>  unique;
+      48             : /// unique_local should be an ordered set since we later create a vector containing the corresponding indexes
+      49             :   std::set<AtomNumber>  unique_local;
+      50             :   std::vector<Vector>   positions;       // positions of the needed atoms
+      51             :   double                energy;
+      52             :   ForwardDecl<Pbc>      pbc_fwd;
+      53             :   Pbc&                  pbc=*pbc_fwd;
+      54             :   Tensor                virial;
+      55             :   std::vector<double>   masses;
+      56             :   bool                  chargesWereSet;
+      57             :   std::vector<double>   charges;
+      58             : 
+      59             :   std::vector<Vector>   forces;          // forces on the needed atoms
+      60             :   double                forceOnEnergy;
+      61             : 
+      62             :   double                forceOnExtraCV;
+      63             : 
+      64             :   std::string           extraCV;
+      65             : 
+      66             :   bool                  lockRequestAtoms; // forbid changes to request atoms
+      67             : 
+      68             :   bool                  donotretrieve;
+      69             :   bool                  donotforce;
+      70             : 
+      71             : protected:
+      72             :   Atoms&                atoms;
+      73             : 
+      74             :   void setExtraCV(const std::string &name);
+      75             : 
+      76             : public:
+      77             : /// Request an array of atoms.
+      78             : /// This method is used to ask for a list of atoms. Atoms
+      79             : /// should be asked for by number. If this routine is called
+      80             : /// during the simulation, atoms will be available at the next step
+      81             : /// MAYBE WE HAVE TO FIND SOMETHING MORE CLEAR FOR DYNAMIC
+      82             : /// LISTS OF ATOMS
+      83             :   void requestAtoms(const std::vector<AtomNumber> & a, const bool clearDep=true);
+      84             : /// Get position of i-th atom (access by relative index)
+      85             :   const Vector & getPosition(int)const;
+      86             : /// Get position of i-th atom (access by absolute AtomNumber).
+      87             : /// With direct access to the global atom array.
+      88             : /// \warning Should be only used by actions that need to read the shared position array.
+      89             : ///          This array is insensitive to local changes such as makeWhole(), numerical derivatives, etc.
+      90             :   const Vector & getGlobalPosition(AtomNumber)const;
+      91             : /// Get modifiable position of i-th atom (access by absolute AtomNumber).
+      92             : /// \warning Should be only used by actions that need to modify the shared position array.
+      93             : ///          This array is insensitive to local changes such as makeWhole(), numerical derivatives, etc.
+      94             :   Vector & modifyGlobalPosition(AtomNumber);
+      95             : /// Get total number of atoms, including virtual ones.
+      96             : /// Can be used to make a loop on modifyGlobalPosition or getGlobalPosition.
+      97             :   unsigned getTotAtoms()const;
+      98             : /// Get modifiable force of i-th atom (access by absolute AtomNumber).
+      99             : /// \warning  Should be used by action that need to modify the stored atomic forces.
+     100             : ///           This should be used with great care since the plumed core does
+     101             : ///           not usually keep all these forces up to date. In particular,
+     102             : ///           if an action require this, one should during constructor
+     103             : ///           call allowToAccessGlobalForces().
+     104             : ///           Notice that for efficiency reason plumed does not check if this is done!
+     105             :   Vector & modifyGlobalForce(AtomNumber);
+     106             : /// Get modifiable virial
+     107             : /// Should be used by action that need to modify the stored virial
+     108             :   Tensor & modifyGlobalVirial();
+     109             : /// Get modifiable PBC
+     110             : /// Should be used by action that need to modify the stored box
+     111             :   Pbc & modifyGlobalPbc();
+     112             : /// Get box shape
+     113             :   const Tensor & getBox()const;
+     114             : /// Get the array of all positions
+     115             :   const std::vector<Vector> & getPositions()const;
+     116             : /// Get energy
+     117             :   const double & getEnergy()const;
+     118             : /// Get mass of i-th atom
+     119             :   double getMass(int i)const;
+     120             : /// Get charge of i-th atom
+     121             :   double getCharge(int i)const;
+     122             : /// Get a reference to forces array
+     123             :   std::vector<Vector> & modifyForces();
+     124             : /// Get a reference to virial array
+     125             :   Tensor & modifyVirial();
+     126             : /// Get a reference to force on energy
+     127             :   double & modifyForceOnEnergy();
+     128             : /// Get a reference to force on extraCV
+     129             :   double & modifyForceOnExtraCV();
+     130             : /// Get number of available atoms
+     131  4193443802 :   unsigned getNumberOfAtoms()const {return indexes.size();}
+     132             : /// Compute the pbc distance between two positions
+     133             :   Vector pbcDistance(const Vector&,const Vector&)const;
+     134             : /// Applies  PBCs to a seriens of positions or distances
+     135             :   void pbcApply(std::vector<Vector>& dlist, unsigned max_index=0) const;
+     136             : /// Get the vector of absolute indexes
+     137             :   virtual const std::vector<AtomNumber> & getAbsoluteIndexes()const;
+     138             : /// Get the absolute index of an atom
+     139             :   AtomNumber getAbsoluteIndex(int i)const;
+     140             : /// Parse a list of atoms without a numbered keyword
+     141             :   void parseAtomList(const std::string&key,std::vector<AtomNumber> &t);
+     142             : /// Parse an list of atom with a numbred keyword
+     143             :   void parseAtomList(const std::string&key,const int num, std::vector<AtomNumber> &t);
+     144             : /// Convert a set of read in strings into an atom list (this is used in parseAtomList)
+     145             :   void interpretAtomList( std::vector<std::string>& strings, std::vector<AtomNumber> &t);
+     146             : /// Change the box shape
+     147             :   void changeBox( const Tensor& newbox );
+     148             : /// Get reference to Pbc
+     149             :   const Pbc & getPbc() const;
+     150             : /// Add the forces to the atoms
+     151             :   void setForcesOnAtoms( const std::vector<double>& forcesToApply, unsigned ind=0 );
+     152             : /// Skip atom retrieval - use with care.
+     153             : /// If this function is called during initialization, then atoms are
+     154             : /// not going to be retrieved. Can be used for optimization. Notice that
+     155             : /// calling getPosition(int) in an Action where DoNotRetrieve() was called might
+     156             : /// lead to undefined behavior.
+     157          38 :   void doNotRetrieve() {donotretrieve=true;}
+     158             : /// Skip atom forces - use with care.
+     159             : /// If this function is called during initialization, then forces are
+     160             : /// not going to be propagated. Can be used for optimization.
+     161          38 :   void doNotForce() {donotforce=true;}
+     162             : /// Make atoms whole, assuming they are in the proper order
+     163             :   void makeWhole();
+     164             : /// Allow calls to modifyGlobalForce()
+     165           9 :   void allowToAccessGlobalForces() {atoms.zeroallforces=true;}
+     166             : /// updates local unique atoms
+     167             :   void updateUniqueLocal();
+     168             : public:
+     169             : 
+     170             : // virtual functions:
+     171             : 
+     172             :   explicit ActionAtomistic(const ActionOptions&ao);
+     173             :   ~ActionAtomistic();
+     174             : 
+     175             :   static void registerKeywords( Keywords& keys );
+     176             : 
+     177             :   void clearOutputForces();
+     178             : 
+     179             : /// N.B. only pass an ActionWithValue to this routine if you know exactly what you
+     180             : /// are doing.  The default will be correct for the vast majority of cases
+     181             :   void   calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+     182             : /// Numerical derivative routine to use when using Actions that inherit from BOTH
+     183             : /// ActionWithArguments and ActionAtomistic
+     184             :   void calculateAtomicNumericalDerivatives( ActionWithValue* a, const unsigned& startnum );
+     185             : 
+     186             :   virtual void retrieveAtoms();
+     187             :   void applyForces();
+     188             :   void lockRequests() override;
+     189             :   void unlockRequests() override;
+     190             :   const std::set<AtomNumber> & getUnique()const;
+     191             :   const std::set<AtomNumber> & getUniqueLocal()const;
+     192             : /// Read in an input file containing atom positions and calculate the action for the atomic
+     193             : /// configuration therin
+     194             :   void readAtomsFromPDB( const PDB& pdb ) override;
+     195             : };
+     196             : 
+     197             : inline
+     198             : const Vector & ActionAtomistic::getPosition(int i)const {
+     199   521324313 :   return positions[i];
+     200             : }
+     201             : 
+     202             : inline
+     203             : const Vector & ActionAtomistic::getGlobalPosition(AtomNumber i)const {
+     204      290796 :   return atoms.positions[i.index()];
+     205             : }
+     206             : 
+     207             : inline
+     208             : Vector & ActionAtomistic::modifyGlobalPosition(AtomNumber i) {
+     209      351074 :   return atoms.positions[i.index()];
+     210             : }
+     211             : 
+     212             : inline
+     213             : Vector & ActionAtomistic::modifyGlobalForce(AtomNumber i) {
+     214       16318 :   return atoms.forces[i.index()];
+     215             : }
+     216             : 
+     217             : inline
+     218             : Tensor & ActionAtomistic::modifyGlobalVirial() {
+     219         125 :   return atoms.virial;
+     220             : }
+     221             : 
+     222             : inline
+     223             : double ActionAtomistic::getMass(int i)const {
+     224      499720 :   return masses[i];
+     225             : }
+     226             : 
+     227             : inline
+     228       63872 : double ActionAtomistic::getCharge(int i) const {
+     229       63872 :   if( !chargesWereSet ) error("charges were not passed to plumed");
+     230       63872 :   return charges[i];
+     231             : }
+     232             : 
+     233             : inline
+     234         160 : const std::vector<AtomNumber> & ActionAtomistic::getAbsoluteIndexes()const {
+     235         161 :   return indexes;
+     236             : }
+     237             : 
+     238             : inline
+     239             : AtomNumber ActionAtomistic::getAbsoluteIndex(int i)const {
+     240   126880183 :   return indexes[i];
+     241             : }
+     242             : 
+     243             : inline
+     244             : const std::vector<Vector> & ActionAtomistic::getPositions()const {
+     245      562784 :   return positions;
+     246             : }
+     247             : 
+     248             : inline
+     249             : const double & ActionAtomistic::getEnergy()const {
+     250        3989 :   return energy;
+     251             : }
+     252             : 
+     253             : inline
+     254             : const Tensor & ActionAtomistic::getBox()const {
+     255       25161 :   return pbc.getBox();
+     256             : }
+     257             : 
+     258             : inline
+     259             : std::vector<Vector> & ActionAtomistic::modifyForces() {
+     260      115500 :   return forces;
+     261             : }
+     262             : 
+     263             : inline
+     264             : Tensor & ActionAtomistic::modifyVirial() {
+     265      129955 :   return virial;
+     266             : }
+     267             : 
+     268             : inline
+     269             : double & ActionAtomistic::modifyForceOnEnergy() {
+     270             :   return forceOnEnergy;
+     271             : }
+     272             : 
+     273             : inline
+     274             : double & ActionAtomistic::modifyForceOnExtraCV() {
+     275             :   return forceOnExtraCV;
+     276             : }
+     277             : 
+     278             : inline
+     279             : const Pbc & ActionAtomistic::getPbc() const {
+     280      572918 :   return pbc;
+     281             : }
+     282             : 
+     283             : inline
+     284      144327 : void ActionAtomistic::lockRequests() {
+     285      158900 :   lockRequestAtoms=true;
+     286      144327 : }
+     287             : 
+     288             : inline
+     289      144327 : void ActionAtomistic::unlockRequests() {
+     290      158900 :   lockRequestAtoms=false;
+     291      144327 : }
+     292             : 
+     293             : inline
+     294             : const std::set<AtomNumber> & ActionAtomistic::getUnique()const {
+     295             :   return unique;
+     296             : }
+     297             : 
+     298             : inline
+     299             : const std::set<AtomNumber> & ActionAtomistic::getUniqueLocal()const {
+     300             :   return unique_local;
+     301             : }
+     302             : 
+     303             : inline
+     304             : unsigned ActionAtomistic::getTotAtoms()const {
+     305       32095 :   return atoms.positions.size();
+     306             : }
+     307             : 
+     308             : inline
+     309             : Pbc & ActionAtomistic::modifyGlobalPbc() {
+     310          77 :   return atoms.pbc;
+     311             : }
+     312             : 
+     313             : inline
+     314             : void ActionAtomistic::setExtraCV(const std::string &name) {
+     315           2 :   extraCV=name;
+     316           2 : }
+     317             : 
+     318             : 
+     319             : 
+     320             : }
+     321             : 
+     322             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bfcf835067 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilot9setStrideERKi17
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE2495
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE2507
_ZNK4PLMD11ActionPilot9getStrideEv81205
_ZNK4PLMD11ActionPilot6onStepEv1439721
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionPilot.cpp.func.html b/coverage/core/ActionPilot.cpp.func.html new file mode 100644 index 0000000000..4ca7c42386 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE2495
_ZN4PLMD11ActionPilot9setStrideERKi17
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE2507
_ZNK4PLMD11ActionPilot6onStepEv1439721
_ZNK4PLMD11ActionPilot9getStrideEv81205
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionPilot.cpp.gcov.html b/coverage/core/ActionPilot.cpp.gcov.html new file mode 100644 index 0000000000..0608892579 --- /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-06-10 08:19:14Functions: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        2495 : void ActionPilot::registerKeywords(Keywords& keys) {}
+      27             : 
+      28        2507 : ActionPilot::ActionPilot(const ActionOptions&ao):
+      29             :   Action(ao),
+      30        2507 :   stride(1)
+      31             : {
+      32        5014 :   if( keywords.exists("STRIDE") ) {
+      33        2449 :     parse("STRIDE",stride);
+      34        4898 :     if( !keywords.style("STRIDE","hidden") ) log.printf("  with stride %d\n",stride);
+      35             :   } else {
+      36          58 :     stride=0;
+      37             :   }
+      38        2507 : }
+      39             : 
+      40     1439721 : bool ActionPilot::onStep()const {
+      41     1439721 :   if( stride>0 ) return getStep()%stride==0;
+      42             :   return false;
+      43             : }
+      44             : 
+      45       81205 : int ActionPilot::getStride()const {
+      46       81205 :   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.15
+
+ + + 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 0000000000..7f289918a0 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionPilot.h.func.html b/coverage/core/ActionPilot.h.func.html new file mode 100644 index 0000000000..5573e46a88 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionPilot.h.gcov.html b/coverage/core/ActionPilot.h.gcov.html new file mode 100644 index 0000000000..c0e32977f6 --- /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-06-10 08:19:14Functions: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        1401 : 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.15
+
+ + + 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 0000000000..ef91b19511 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:426168.9 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE287
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_288
_ZN4PLMDlsERSoRKNS_14ActionRegisterE289
_ZN4PLMD14ActionRegisterD2Ev3473
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE14107
_ZN4PLMD14ActionRegister5checkENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14684
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE996752
_ZN4PLMD14ActionRegister6removeEPFSt10unique_ptrINS_6ActionESt14default_deleteIS2_EERKNS_13ActionOptionsEE996752
_ZN4PLMD14actionRegisterEv2008190
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.func.html b/coverage/core/ActionRegister.cpp.func.html new file mode 100644 index 0000000000..632da1bfc7 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:426168.9 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE287
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_288
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE996752
_ZN4PLMD14ActionRegister5checkENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14684
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE14107
_ZN4PLMD14ActionRegister6removeEPFSt10unique_ptrINS_6ActionESt14default_deleteIS2_EERKNS_13ActionOptionsEE996752
_ZN4PLMD14ActionRegisterD2Ev3473
_ZN4PLMD14actionRegisterEv2008190
_ZN4PLMDlsERSoRKNS_14ActionRegisterE289
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.gcov.html b/coverage/core/ActionRegister.cpp.gcov.html new file mode 100644 index 0000000000..61e6f03d2e --- /dev/null +++ b/coverage/core/ActionRegister.cpp.gcov.html @@ -0,0 +1,214 @@ + + + + + + + + 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:426168.9 %
Date:2024-06-10 08:19:14Functions:91090.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 "ActionRegister.h"
+      23             : #include "tools/Tools.h"
+      24             : #include "Action.h"
+      25             : #include <algorithm>
+      26             : #include <iostream>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30        3473 : ActionRegister::~ActionRegister() {
+      31        3473 :   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        3473 : }
+      37             : 
+      38     2008190 : ActionRegister& actionRegister() {
+      39     2008190 :   static ActionRegister ans;
+      40     2008190 :   return ans;
+      41             : }
+      42             : 
+      43      996752 : void ActionRegister::remove(creator_pointer f) {
+      44    83459721 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      45    83459721 :     if((*p).second==f) {
+      46      996752 :       m.erase(p); break;
+      47             :     }
+      48             :   }
+      49      996752 : }
+      50             : 
+      51      996752 : 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     5046273 :   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      996752 :     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      996752 :     mk.insert(std::pair<std::string,keywords_pointer>(key,k));
+      63             :   };
+      64      996752 : }
+      65             : 
+      66       14684 : bool ActionRegister::check(std::string key) {
+      67       14680 :   if(m.count(key)>0 && mk.count(key)>0) return true;
+      68             :   return false;
+      69             : }
+      70             : 
+      71       14107 : std::unique_ptr<Action> ActionRegister::create(const ActionOptions&ao) {
+      72       14107 :   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       14107 :   std::unique_ptr<Action> action;
+      80       28214 :   if( check(ao.line[0]) ) {
+      81       14105 :     Keywords keys; mk[ao.line[0]](keys);
+      82       14105 :     ActionOptions nao( ao,keys );
+      83       28173 :     action=m[ao.line[0]](nao);
+      84       14105 :   }
+      85             :   return action;
+      86       14107 : }
+      87             : 
+      88         287 : bool ActionRegister::getKeywords(const std::string& action, Keywords& keys) {
+      89         574 :   if ( check(action) ) {  mk[action](keys); return true; }
+      90             :   return false;
+      91             : }
+      92             : 
+      93         288 : bool ActionRegister::printManual(const std::string& action, const bool& vimout, const bool& spellout) {
+      94         576 :   if ( check(action) ) {
+      95         287 :     Keywords keys; getKeywords( action, keys );
+      96         287 :     if( vimout ) {
+      97         287 :       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         287 :   } 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         289 : std::ostream & operator<<(std::ostream &log,const ActionRegister&ar) {
+     120             :   std::vector<std::string> s;
+     121       83233 :   for(const auto & it : ar.m) s.push_back(it.first);
+     122         289 :   std::sort(s.begin(),s.end());
+     123       83233 :   for(unsigned i=0; i<s.size(); i++) log<<"  "<<s[i]<<"\n";
+     124         289 :   if(!ar.disabled.empty()) {
+     125           0 :     s.assign(ar.disabled.size(),"");
+     126           0 :     std::copy(ar.disabled.begin(),ar.disabled.end(),s.begin());
+     127           0 :     std::sort(s.begin(),s.end());
+     128           0 :     log<<"+++++++ WARNING +++++++\n";
+     129           0 :     log<<"The following keywords have been registered more than once and will be disabled:\n";
+     130           0 :     for(unsigned i=0; i<s.size(); i++) log<<"  - "<<s[i]<<"\n";
+     131           0 :     log<<"+++++++ END WARNING +++++++\n";
+     132             :   };
+     133         289 :   return log;
+     134         289 : }
+     135             : 
+     136             : 
+     137             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..5bcba11f5b --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv1
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE404395
_ZN4PLMD9ActionSetD2Ev404395
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionSet.cpp.func.html b/coverage/core/ActionSet.cpp.func.html new file mode 100644 index 0000000000..e2a2b30671 --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv1
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE404395
_ZN4PLMD9ActionSetD2Ev404395
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionSet.cpp.gcov.html b/coverage/core/ActionSet.cpp.gcov.html new file mode 100644 index 0000000000..a67e39e532 --- /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-06-10 08:19:14Functions: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      404395 : ActionSet::ActionSet(PlumedMain&p):
+      27      404395 :   plumed(p) {
+      28             :   (void) plumed; // to suppress warning about "unused plumed"
+      29      404395 : }
+      30             : 
+      31      404395 : ActionSet::~ActionSet()
+      32             : {
+      33             : // required in order to deallocate in reverse order:
+      34      418461 :   for(int i=size()-1; i>=0; i--) (*this)[i].reset();
+      35      404395 : }
+      36             : 
+      37           1 : void ActionSet::clearDelete() {
+      38           3 :   for(int i=size()-1; i>=0; i--) (*this)[i].reset();
+      39           1 :   clear();
+      40           1 : }
+      41             : 
+      42             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ffe95fb7e1 --- /dev/null +++ b/coverage/core/ActionSet.h.func-sort-c.html @@ -0,0 +1,169 @@ + + + + + + + + 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-06-10 08:19:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_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_3ves14BasisFunctionsEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE241
_ZNK4PLMD9ActionSet6selectIPNS_15ActionWithValueEEESt6vectorIT_SaIS5_EEv313
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_11multicolvar15MultiColvarBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE384
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE407
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE901
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6ActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14105
_ZNK4PLMD9ActionSet6selectIPNS_11ActionPilotEEESt6vectorIT_SaIS5_EEv14863
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1081372
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionSet.h.func.html b/coverage/core/ActionSet.h.func.html new file mode 100644 index 0000000000..c1a9ec54e4 --- /dev/null +++ b/coverage/core/ActionSet.h.func.html @@ -0,0 +1,169 @@ + + + + + + + + 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-06-10 08:19:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9ActionSet12getLabelListIPNS_15ActionWithValueEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEv1
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE901
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_10vesselbase16ActionWithVesselEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE118
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_11multicolvar15MultiColvarBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE384
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1081372
_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_6ActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14105
_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
_ZNK4PLMD9ActionSet6selectIPNS_11ActionPilotEEESt6vectorIT_SaIS5_EEv14863
_ZNK4PLMD9ActionSet6selectIPNS_11ActionSetupEEESt6vectorIT_SaIS5_EEv2
_ZNK4PLMD9ActionSet6selectIPNS_15ActionWithValueEEESt6vectorIT_SaIS5_EEv313
_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.15
+
+ + + diff --git a/coverage/core/ActionSet.h.gcov.html b/coverage/core/ActionSet.h.gcov.html new file mode 100644 index 0000000000..c26077e268 --- /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-06-10 08:19:14Functions: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             : #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       15294 : std::vector<T> ActionSet::select()const {
+      85             :   std::vector<T> ret;
+      86     6252061 :   for(const auto & p : (*this)) {
+      87     6236767 :     T t=dynamic_cast<T>(p.get());
+      88     6236767 :     if(t) ret.push_back(t);
+      89             :   };
+      90       15294 :   return ret;
+      91             : }
+      92             : 
+      93             : template <class T>
+      94     1096815 : T ActionSet::selectWithLabel(const std::string&s)const {
+      95     9459412 :   for(const auto & p : (*this)) {
+      96     3274544 :     T t=dynamic_cast<T>(p.get());
+      97     9445107 :     if(t && dynamic_cast<Action*>(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           5 :   for(const auto & p : (*this)) {
+     116           8 :     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         901 : T ActionSet::selectLatest(const Action*action) const {
+     133             :   T t=nullptr;
+     134       12862 :   for(const auto & p : (*this)) {
+     135       12001 :     if(p.get()==action) return t;
+     136       11961 :     T r=dynamic_cast<T>(p.get());
+     137       11961 :     if(r) t=r;
+     138             :   }
+     139             :   return t;
+     140             : }
+     141             : 
+     142             : 
+     143             : 
+     144             : }
+     145             : 
+     146             : #endif
+     147             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b4258e02b9 --- /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:1010100.0 %
Date:2024-06-10 08:19:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetupC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionSetupC2ERKNS_13ActionOptionsE77
_ZN4PLMD11ActionSetup16registerKeywordsERNS_8KeywordsE165
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.func.html b/coverage/core/ActionSetup.cpp.func.html new file mode 100644 index 0000000000..302af8b0f6 --- /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:1010100.0 %
Date:2024-06-10 08:19:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup16registerKeywordsERNS_8KeywordsE165
_ZN4PLMD11ActionSetupC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionSetupC2ERKNS_13ActionOptionsE77
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.gcov.html b/coverage/core/ActionSetup.cpp.gcov.html new file mode 100644 index 0000000000..6b791a0524 --- /dev/null +++ b/coverage/core/ActionSetup.cpp.gcov.html @@ -0,0 +1,122 @@ + + + + + + + + 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:1010100.0 %
Date:2024-06-10 08:19:14Functions: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 "PlumedMain.h"
+      24             : #include "ActionSet.h"
+      25             : #include "tools/Exception.h"
+      26             : #include "ActionAnyorder.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30          77 : ActionSetup::ActionSetup(const ActionOptions&ao):
+      31          77 :   Action(ao)
+      32             : {
+      33          77 :   const ActionSet& actionset(plumed.getActionSet());
+      34          80 :   for(const auto & p : actionset) {
+      35             : // check that all the preceding actions are ActionSetup
+      36           3 :     if( !dynamic_cast<ActionSetup*>(p.get()) && !dynamic_cast<ActionAnyorder*>(p.get()) ) 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.");
+      37             :   }
+      38          77 : }
+      39             : 
+      40         165 : void ActionSetup::registerKeywords( Keywords& keys ) {
+      41         165 :   Action::registerKeywords(keys);
+      42         165 :   keys.remove("LABEL");
+      43         165 : }
+      44             : 
+      45             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..60ff338b60 --- /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-06-10 08:19:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup5applyEv0
_ZN4PLMD11ActionSetup9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionSetup.h.func.html b/coverage/core/ActionSetup.h.func.html new file mode 100644 index 0000000000..e7d630a422 --- /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-06-10 08:19:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup5applyEv0
_ZN4PLMD11ActionSetup9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionSetup.h.gcov.html b/coverage/core/ActionSetup.h.gcov.html new file mode 100644 index 0000000000..bb204c6512 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..2e219ea1a2 --- /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:212777.8 %
Date:2024-06-10 08:19:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev0
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE12
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev54
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.func.html b/coverage/core/ActionShortcut.cpp.func.html new file mode 100644 index 0000000000..7c2c1e7b8b --- /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:212777.8 %
Date:2024-06-10 08:19:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE12
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev54
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.gcov.html b/coverage/core/ActionShortcut.cpp.gcov.html new file mode 100644 index 0000000000..88b0b322ac --- /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:212777.8 %
Date:2024-06-10 08:19:14Functions: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          15 : void ActionShortcut::registerKeywords( Keywords& keys ) {
+      29          15 :   Action::registerKeywords( keys );
+      30          30 :   keys.add("hidden","IS_SHORTCUT","hidden keyword to tell if actions are shortcuts so that example generator can provide expansions of shortcuts");
+      31          15 : }
+      32             : 
+      33          12 : ActionShortcut::ActionShortcut(const ActionOptions&ao):
+      34             :   Action(ao),
+      35          12 :   shortcutlabel(label)
+      36             : {
+      37          12 :   std::string s; Tools::convert(plumed.getActionSet().size(),s);
+      38          12 :   if( shortcutlabel==("@" + s) ) {
+      39           6 :     std::string t; Tools::convert(plumed.getActionSet().size()+1,t);
+      40          12 :     shortcutlabel="@" + t;
+      41          12 :   } else label = ("@" + s);
+      42          12 : }
+      43             : 
+      44          36 : void ActionShortcut::readInputLine( const std::string& input ) {
+      45          36 :   std::string f_input = input; savedInputLines.push_back( input );
+      46          36 :   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          36 :   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          72 :   if( keywords.exists("RESTART") ) {
+      53           0 :     if( restart ) f_input += " RESTART=YES";
+      54           0 :     if( !restart ) f_input += " RESTART=NO";
+      55             :   }
+      56          36 :   plumed.readInputLine( f_input );
+      57          36 : }
+      58             : 
+      59          54 : const std::string & ActionShortcut::getShortcutLabel() const {
+      60          54 :   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.15
+
+ + + 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 0000000000..fd63b030bc --- /dev/null +++ b/coverage/core/ActionShortcut.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + 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:020.0 %
Date:2024-06-10 08:19:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut5applyEv0
_ZN4PLMD14ActionShortcut9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionShortcut.h.func.html b/coverage/core/ActionShortcut.h.func.html new file mode 100644 index 0000000000..e326611db2 --- /dev/null +++ b/coverage/core/ActionShortcut.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + 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:020.0 %
Date:2024-06-10 08:19:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut5applyEv0
_ZN4PLMD14ActionShortcut9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionShortcut.h.gcov.html b/coverage/core/ActionShortcut.h.gcov.html new file mode 100644 index 0000000000..3a805fdec5 --- /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:020.0 %
Date:2024-06-10 08:19:14Functions:020.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             : protected:
+      39             :   const std::string & getShortcutLabel() const ;
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             : /// Constructor
+      43             :   explicit ActionShortcut(const ActionOptions&ao);
+      44             : /// Read a line of input and create appropriate actions
+      45             :   void readInputLine( const std::string& input );
+      46             : /// Do nothing.
+      47           0 :   void calculate() override {}
+      48             : /// Do nothing.
+      49           0 :   void apply() override {}
+      50             : /// Get the lines of the shortcut that were read in
+      51             :   std::vector<std::string> getSavedInputLines() const ;
+      52             : };
+      53             : 
+      54             : }
+      55             : 
+      56             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e5da42fe6e --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:14816291.4 %
Date:2024-06-10 08:19:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArgumentsC1ERKNS_13ActionOptionsE0
_ZN4PLMD19ActionWithArguments24requestExtraDependenciesERKSt6vectorIPNS_5ValueESaIS3_EE4
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIPNS_5ValueESaISB_EE6
_ZN4PLMD19ActionWithArguments29calculateNumericalDerivativesEPNS_15ActionWithValueE58
_ZNK4PLMD19ActionWithArguments13getProjectionEjj261
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKSt6vectorIdSaIdEE350
_ZN4PLMD19ActionWithArguments21expandArgKeywordInPDBERKNS_3PDBE416
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE2808
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EE2848
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE2906
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_IPNS_5ValueESaISD_EE2950
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE178924
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithArguments.cpp.func.html b/coverage/core/ActionWithArguments.cpp.func.html new file mode 100644 index 0000000000..03d3e21899 --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:14816291.4 %
Date:2024-06-10 08:19:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE2906
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE178924
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EE2848
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIPNS_5ValueESaISB_EE6
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKSt6vectorIdSaIdEE350
_ZN4PLMD19ActionWithArguments21expandArgKeywordInPDBERKNS_3PDBE416
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_IPNS_5ValueESaISD_EE2950
_ZN4PLMD19ActionWithArguments24requestExtraDependenciesERKSt6vectorIPNS_5ValueESaIS3_EE4
_ZN4PLMD19ActionWithArguments29calculateNumericalDerivativesEPNS_15ActionWithValueE58
_ZN4PLMD19ActionWithArgumentsC1ERKNS_13ActionOptionsE0
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE2808
_ZNK4PLMD19ActionWithArguments13getProjectionEjj261
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithArguments.cpp.gcov.html b/coverage/core/ActionWithArguments.cpp.gcov.html new file mode 100644 index 0000000000..5ee872e4a3 --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.gcov.html @@ -0,0 +1,387 @@ + + + + + + + + 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:14816291.4 %
Date:2024-06-10 08:19:14Functions:111291.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 "ActionWithArguments.h"
+      23             : #include "ActionWithValue.h"
+      24             : #include "tools/PDB.h"
+      25             : #include "PlumedMain.h"
+      26             : #include "ActionSet.h"
+      27             : #include <iostream>
+      28             : #ifdef __PLUMED_HAS_CREGEX
+      29             : #include <cstring>
+      30             : #include <regex.h>
+      31             : #endif
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35        2906 : void ActionWithArguments::registerKeywords(Keywords& keys) {
+      36        5812 :   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        2906 : }
+      47             : 
+      48        2848 : void ActionWithArguments::parseArgumentList(const std::string&key,std::vector<Value*>&arg) {
+      49        2848 :   std::string def; std::vector<std::string> c; arg.clear(); parseVector(key,c);
+      50        3306 :   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        2848 :   interpretArgumentList(c,arg);
+      55        2848 : }
+      56             : 
+      57           6 : bool ActionWithArguments::parseArgumentList(const std::string&key,int i,std::vector<Value*>&arg) {
+      58             :   std::vector<std::string> c;
+      59             :   arg.clear();
+      60           6 :   if(parseNumberedVector(key,i,c)) {
+      61           6 :     interpretArgumentList(c,arg);
+      62             :     return true;
+      63             :   } else return false;
+      64           6 : }
+      65             : 
+      66        2950 : void ActionWithArguments::interpretArgumentList(const std::vector<std::string>& c, std::vector<Value*>&arg) {
+      67        8361 :   for(unsigned i=0; i<c.size(); i++) {
+      68             :     // is a regex? then just interpret it. The signal is ()
+      69        5414 :     if(!c[i].compare(0,1,"(")) {
+      70         196 :       unsigned l=c[i].length();
+      71         196 :       if(!c[i].compare(l-1,1,")")) {
+      72             :         // start regex parsing
+      73             : #ifdef __PLUMED_HAS_CREGEX
+      74             :         // take the string enclosed in quotes and put in round brackets
+      75         195 :         std::string myregex=c[i];
+      76             :         //log<<"  Evaluating regexp for this action: "<<myregex<<"\n";
+      77             : 
+      78             :         regex_t reg; // regular expression
+      79             : 
+      80         195 :         int errcode=regcomp(&reg, myregex.c_str(),REG_EXTENDED|REG_NEWLINE); // compile the regular expression
+      81         195 :         if(errcode) {
+      82             :           // one can check the errors asking to regerror
+      83           1 :           size_t errbuf_size = regerror(errcode, &reg, NULL, 0);
+      84           2 :           std::vector<char> errbuf(errbuf_size);
+      85           1 :           regerror(errcode, &reg, errbuf.data(), errbuf_size);
+      86           3 :           plumed_error()<<"Error parsing regular expression: "<<errbuf.data();
+      87             :         }
+      88             : 
+      89             :         // call regfree when reg goes out of scope
+      90         194 :         auto deleter=[](regex_t* r) { regfree(r); };
+      91             :         std::unique_ptr<regex_t,decltype(deleter)> reg_deleter(&reg,deleter);
+      92             : 
+      93         194 :         plumed_massert(reg.re_nsub==1,"I can parse with only one subexpression");
+      94             :         regmatch_t match;
+      95             :         // select all the actions that have a value
+      96         194 :         std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+      97         194 :         if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+      98             :         bool found_something=false;
+      99        1495 :         for(unsigned j=0; j<all.size(); j++) {
+     100        1301 :           std::vector<std::string> ss=all[j]->getComponentsVector();
+     101      220214 :           for(unsigned  k=0; k<ss.size(); ++k) {
+     102      218913 :             unsigned ll=std::strlen(ss[k].c_str())+1;
+     103      218913 :             std::vector<char> str(ll);
+     104             :             std::strcpy(&str[0],ss[k].c_str());
+     105             :             const char *ppstr=&str[0];
+     106      218913 :             if(!regexec(&reg, ppstr, reg.re_nsub, &match, 0)) {
+     107             :               //log.printf("  Something matched with \"%s\" : ",ss[k].c_str());
+     108             :               do {
+     109       27814 :                 if (match.rm_so != -1) {        /* The regex is matching part of a string */
+     110       27814 :                   size_t matchlen = match.rm_eo - match.rm_so;
+     111       27814 :                   std::vector<char> submatch(matchlen+1);
+     112       27814 :                   std::strncpy(submatch.data(), ppstr+match.rm_so, matchlen+1);
+     113       27814 :                   submatch[matchlen]='\0';
+     114             :                   //log.printf("  subpattern %s\n", submatch.data());
+     115             :                   // this is the match: try to see if it is a valid action
+     116       27814 :                   std::string putativeVal(submatch.data());
+     117       27814 :                   if( all[j]->exists(putativeVal) ) {
+     118       21327 :                     arg.push_back(all[j]->copyOutput(putativeVal));
+     119             :                     found_something=true;
+     120             :                     //log.printf("  Action %s added! \n",putativeVal.c_str());
+     121             :                   }
+     122             :                 }
+     123       27814 :                 ppstr += match.rm_eo;   /* Restart from last match */
+     124       27814 :               } while(!regexec(&reg,ppstr,reg.re_nsub,&match,0));
+     125             :             }
+     126             :           }
+     127        1301 :         }
+     128         194 :         if(!found_something) plumed_error()<<"There isn't any action matching your regex " << myregex;
+     129             : #else
+     130             :         plumed_merror("Regexp support not compiled!");
+     131             : #endif
+     132             :       } else {
+     133           2 :         plumed_merror("did you want to use regexp to input arguments? enclose it between two round braces (...) with no spaces!");
+     134             :       }
+     135             :     } else {
+     136             :       std::size_t dot=c[i].find_first_of('.');
+     137        5218 :       std::string a=c[i].substr(0,dot);
+     138        5218 :       std::string name=c[i].substr(dot+1);
+     139        5218 :       if(c[i].find(".")!=std::string::npos) {   // if it contains a dot:
+     140        1853 :         if(a=="*" && name=="*") {
+     141             :           // Take all values from all actions
+     142           1 :           std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+     143           1 :           if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+     144           9 :           for(unsigned j=0; j<all.size(); j++) {
+     145          18 :             for(int k=0; k<all[j]->getNumberOfComponents(); ++k) arg.push_back(all[j]->copyOutput(k));
+     146             :           }
+     147        1843 :         } else if ( name=="*") {
+     148             :           // Take all the values from an action with a specific name
+     149         510 :           ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(a);
+     150         510 :           if(!action) {
+     151           0 :             std::string str=" (hint! the actions with value in this ActionSet are: ";
+     152           0 :             str+=plumed.getActionSet().getLabelList<ActionWithValue*>()+")";
+     153           0 :             error("cannot find action named " + a + str);
+     154             :           }
+     155         510 :           if( action->getNumberOfComponents()==0 ) error("found " + a +".* indicating use all components calculated by action with label " + a + " but this action has no components");
+     156        5434 :           for(int k=0; k<action->getNumberOfComponents(); ++k) arg.push_back(action->copyOutput(k));
+     157        1333 :         } else if ( a=="*" ) {
+     158             :           // Take components from all actions with a specific name
+     159           8 :           std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+     160           8 :           if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+     161             :           unsigned nval=0;
+     162          36 :           for(unsigned j=0; j<all.size(); j++) {
+     163          56 :             std::string flab; flab=all[j]->getLabel() + "." + name;
+     164          28 :             if( all[j]->exists(flab) ) { arg.push_back(all[j]->copyOutput(flab)); nval++; }
+     165             :           }
+     166           8 :           if(nval==0) error("found no actions with a component called " + name );
+     167             :         } else {
+     168             :           // Take values with a specific name
+     169        1325 :           ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(a);
+     170        1325 :           if(!action) {
+     171           0 :             std::string str=" (hint! the actions with value in this ActionSet are: ";
+     172           0 :             str+=plumed.getActionSet().getLabelList<ActionWithValue*>()+")";
+     173           0 :             error("cannot find action named " + a +str);
+     174             :           }
+     175        1325 :           if( !(action->exists(c[i])) ) {
+     176           0 :             std::string str=" (hint! the components in this actions are: ";
+     177           0 :             str+=action->getComponentsList()+")";
+     178           0 :             error("action " + a + " has no component named " + name + str);
+     179             :           } ;
+     180        1325 :           arg.push_back(action->copyOutput(c[i]));
+     181             :         }
+     182             :       } else {    // if it doesn't contain a dot
+     183        3374 :         if(c[i]=="*") {
+     184             :           // Take all values from all actions
+     185         101 :           std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+     186         101 :           if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+     187         685 :           for(unsigned j=0; j<all.size(); j++) {
+     188        1257 :             for(int k=0; k<all[j]->getNumberOfComponents(); ++k) arg.push_back(all[j]->copyOutput(k));
+     189             :           }
+     190             :         } else {
+     191        3273 :           ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(c[i]);
+     192        3273 :           if(!action) {
+     193           1 :             std::string str=" (hint! the actions with value in this ActionSet are: ";
+     194           2 :             str+=plumed.getActionSet().getLabelList<ActionWithValue*>()+")";
+     195           3 :             error("cannot find action named " + c[i] + str );
+     196             :           }
+     197        3272 :           if( !(action->exists(c[i])) ) {
+     198           0 :             std::string str=" (hint! the components in this actions are: ";
+     199           0 :             str+=action->getComponentsList()+")";
+     200           0 :             error("action " + c[i] + " has no component named " + c[i] +str);
+     201             :           };
+     202        3273 :           arg.push_back(action->copyOutput(c[i]));
+     203             :         }
+     204             :       }
+     205             :     }
+     206             :   }
+     207        2947 : }
+     208             : 
+     209         416 : void ActionWithArguments::expandArgKeywordInPDB( const PDB& pdb ) {
+     210         416 :   std::vector<std::string> arg_names = pdb.getArgumentNames();
+     211         416 :   if( arg_names.size()>0 ) {
+     212             :     std::vector<Value*> arg_vals;
+     213          80 :     interpretArgumentList( arg_names, arg_vals );
+     214             :   }
+     215         416 : }
+     216             : 
+     217      178924 : void ActionWithArguments::requestArguments(const std::vector<Value*> &arg) {
+     218      178924 :   plumed_massert(!lockRequestArguments,"requested argument list can only be changed in the prepare() method");
+     219      178924 :   arguments=arg;
+     220      178924 :   clearDependencies();
+     221             :   std::string fullname;
+     222             :   std::string name;
+     223     1255035 :   for(unsigned i=0; i<arguments.size(); i++) {
+     224     1076111 :     fullname=arguments[i]->getName();
+     225     1076111 :     if(fullname.find(".")!=std::string::npos) {
+     226             :       std::size_t dot=fullname.find_first_of('.');
+     227      738352 :       name=fullname.substr(0,dot);
+     228             :     } else {
+     229             :       name=fullname;
+     230             :     }
+     231     1076111 :     ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(name);
+     232     1076111 :     plumed_massert(action,"cannot find action named (in requestArguments - this is weird)" + name);
+     233     1076111 :     addDependency(action);
+     234             :   }
+     235      178924 : }
+     236             : 
+     237           4 : void ActionWithArguments::requestExtraDependencies(const std::vector<Value*> &extra) {
+     238           4 :   plumed_massert(!lockRequestArguments,"requested argument list can only be changed in the prepare() method");
+     239             :   std::string fullname;
+     240             :   std::string name;
+     241           9 :   for(unsigned i=0; i<extra.size(); i++) {
+     242           5 :     fullname=extra[i]->getName();
+     243           5 :     if(fullname.find(".")!=std::string::npos) {
+     244             :       std::size_t dot=fullname.find_first_of('.');
+     245           0 :       name=fullname.substr(0,dot);
+     246             :     } else {
+     247             :       name=fullname;
+     248             :     }
+     249           5 :     ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(name);
+     250           5 :     plumed_massert(action,"cannot find action named (in requestArguments - this is weird)" + name);
+     251           5 :     addDependency(action);
+     252             :   }
+     253           4 : }
+     254             : 
+     255        2808 : ActionWithArguments::ActionWithArguments(const ActionOptions&ao):
+     256             :   Action(ao),
+     257        2808 :   lockRequestArguments(false)
+     258             : {
+     259        5619 :   if( keywords.exists("ARG") ) {
+     260             :     std::vector<Value*> arg;
+     261        5430 :     parseArgumentList("ARG",arg);
+     262             : 
+     263        2712 :     if(!arg.empty()) {
+     264        2583 :       log.printf("  with arguments");
+     265       25674 :       for(unsigned i=0; i<arg.size(); i++) log.printf(" %s",arg[i]->getName().c_str());
+     266        2583 :       log.printf("\n");
+     267             :     }
+     268        2712 :     requestArguments(arg);
+     269             :   }
+     270        2805 : }
+     271             : 
+     272          58 : void ActionWithArguments::calculateNumericalDerivatives( ActionWithValue* a ) {
+     273          58 :   if(!a) {
+     274          58 :     a=dynamic_cast<ActionWithValue*>(this);
+     275          58 :     plumed_massert(a,"cannot compute numerical derivatives for an action without values");
+     276             :   }
+     277             : 
+     278          58 :   const size_t nval=a->getNumberOfComponents();
+     279             :   const size_t npar=arguments.size();
+     280          58 :   std::vector<double> value (nval*npar);
+     281         161 :   for(int i=0; i<npar; i++) {
+     282         103 :     double arg0=arguments[i]->get();
+     283         103 :     arguments[i]->set(arg0+std::sqrt(epsilon));
+     284         103 :     a->calculate();
+     285         103 :     arguments[i]->set(arg0);
+     286        1367 :     for(int j=0; j<nval; j++) {
+     287        1264 :       value[i*nval+j]=a->getOutputQuantity(j);
+     288             :     }
+     289             :   }
+     290          58 :   a->calculate();
+     291          58 :   a->clearDerivatives();
+     292        1192 :   for(int j=0; j<nval; j++) {
+     293        1134 :     Value* v=a->copyOutput(j);
+     294        1534 :     if( v->hasDerivatives() ) for(int i=0; i<npar; i++) v->addDerivative(i,(value[i*nval+j]-a->getOutputQuantity(j))/std::sqrt(epsilon));
+     295             :   }
+     296          58 : }
+     297             : 
+     298         261 : double ActionWithArguments::getProjection(unsigned i,unsigned j)const {
+     299         261 :   plumed_massert(i<arguments.size()," making projections with an index which  is too large");
+     300         261 :   plumed_massert(j<arguments.size()," making projections with an index which  is too large");
+     301         261 :   const Value* v1=arguments[i];
+     302         261 :   const Value* v2=arguments[j];
+     303         261 :   return Value::projection(*v1,*v2);
+     304             : }
+     305             : 
+     306         350 : void ActionWithArguments::addForcesOnArguments( const std::vector<double>& forces ) {
+     307         474 :   for(unsigned i=0; i<arguments.size(); ++i) arguments[i]->addForce( forces[i] );
+     308         350 : }
+     309             : 
+     310             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..6cb9b59929 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArgumentsD2Ev2805
_ZNK4PLMD19ActionWithArguments12getArgumentsEv458199
_ZN4PLMD19ActionWithArguments12lockRequestsEv538111
_ZN4PLMD19ActionWithArguments14unlockRequestsEv538111
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv4120418708
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.func.html b/coverage/core/ActionWithArguments.h.func.html new file mode 100644 index 0000000000..879c58a7f0 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func.html @@ -0,0 +1,93 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments12lockRequestsEv538111
_ZN4PLMD19ActionWithArguments14unlockRequestsEv538111
_ZN4PLMD19ActionWithArgumentsD2Ev2805
_ZNK4PLMD19ActionWithArguments12getArgumentsEv458199
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv4120418708
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.gcov.html b/coverage/core/ActionWithArguments.h.gcov.html new file mode 100644 index 0000000000..a887b908be --- /dev/null +++ b/coverage/core/ActionWithArguments.h.gcov.html @@ -0,0 +1,209 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions: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             : #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 std::vector<double>& forces );
+      74             : public:
+      75             :   explicit ActionWithArguments(const ActionOptions&);
+      76        2805 :   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             : };
+      88             : 
+      89             : 
+      90             : inline
+      91             : Value* ActionWithArguments::getPntrToArgument( const unsigned n ) {
+      92     4174924 :   return arguments[n];
+      93             : }
+      94             : 
+      95             : inline
+      96             : double ActionWithArguments::getArgument(const unsigned n) const {
+      97      823666 :   return arguments[n]->get();
+      98             : }
+      99             : 
+     100             : inline
+     101  4120418708 : unsigned ActionWithArguments::getNumberOfArguments()const {
+     102  4120436327 :   return arguments.size();
+     103             : }
+     104             : 
+     105             : inline
+     106             : double ActionWithArguments::difference(int i,double d1,double d2)const {
+     107     4859200 :   return arguments[i]->difference(d1,d2);
+     108             : }
+     109             : 
+     110             : inline
+     111             : double ActionWithArguments::bringBackInPbc(int i,double d1)const {
+     112        1427 :   return arguments[i]->bringBackInPbc(d1);
+     113             : }
+     114             : 
+     115             : inline
+     116      538111 : void ActionWithArguments::lockRequests() {
+     117      552684 :   lockRequestArguments=true;
+     118      538111 : }
+     119             : 
+     120             : inline
+     121      538111 : void ActionWithArguments::unlockRequests() {
+     122      552684 :   lockRequestArguments=false;
+     123      538111 : }
+     124             : 
+     125             : inline
+     126      458199 : const std::vector<Value*> & ActionWithArguments::getArguments() const {
+     127      462012 :   return arguments;
+     128             : }
+     129             : 
+     130             : }
+     131             : 
+     132             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..986300f1c7 --- /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:11112489.5 %
Date:2024-06-10 08:19:14Functions:253083.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue23noAnalyticalDerivativesERNS_8KeywordsE0
_ZN4PLMD15ActionWithValueC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionWithValueD0Ev0
_ZN4PLMD15ActionWithValueD1Ev0
_ZNK4PLMD15ActionWithValue17getComponentsListB5cxx11Ev0
_ZN4PLMD15ActionWithValue8addValueEv56
_ZN4PLMD15ActionWithValue19componentIsPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_92
_ZN4PLMD15ActionWithValue25useCustomisableComponentsERNS_8KeywordsE241
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_676
_ZN4PLMD15ActionWithValue24componentsAreNotOptionalERNS_8KeywordsE1194
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev1354
_ZN4PLMD15ActionWithValue14setNotPeriodicEv1697
_ZN4PLMD15ActionWithValue23addValueWithDerivativesEv2317
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE4131
_ZN4PLMD15ActionWithValueD2Ev4131
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE4328
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10710
_ZNK4PLMD15ActionWithValue10copyOutputERKj10763
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22633
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE26102
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30152
_ZN4PLMD15ActionWithValue16clearInputForcesEv1389822
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1389822
_ZN4PLMD15ActionWithValue16clearDerivativesEv1392602
_ZN4PLMD15ActionWithValue18getPntrToComponentEi2139071
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv3493078
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10598053
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10628297
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10661051
_ZN4PLMD15ActionWithValue14getPntrToValueEv16301774
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.func.html b/coverage/core/ActionWithValue.cpp.func.html new file mode 100644 index 0000000000..398c051500 --- /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:11112489.5 %
Date:2024-06-10 08:19:14Functions:253083.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_676
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22633
_ZN4PLMD15ActionWithValue14getPntrToValueEv16301774
_ZN4PLMD15ActionWithValue14setNotPeriodicEv1697
_ZN4PLMD15ActionWithValue16clearDerivativesEv1392602
_ZN4PLMD15ActionWithValue16clearInputForcesEv1389822
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE4328
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv3493078
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10598053
_ZN4PLMD15ActionWithValue18getPntrToComponentEi2139071
_ZN4PLMD15ActionWithValue19componentIsPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_92
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1389822
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30152
_ZN4PLMD15ActionWithValue23addValueWithDerivativesEv2317
_ZN4PLMD15ActionWithValue23noAnalyticalDerivativesERNS_8KeywordsE0
_ZN4PLMD15ActionWithValue24componentsAreNotOptionalERNS_8KeywordsE1194
_ZN4PLMD15ActionWithValue25useCustomisableComponentsERNS_8KeywordsE241
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10710
_ZN4PLMD15ActionWithValue8addValueEv56
_ZN4PLMD15ActionWithValueC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE4131
_ZN4PLMD15ActionWithValueD0Ev0
_ZN4PLMD15ActionWithValueD1Ev0
_ZN4PLMD15ActionWithValueD2Ev4131
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE26102
_ZNK4PLMD15ActionWithValue10copyOutputERKj10763
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10628297
_ZNK4PLMD15ActionWithValue17getComponentsListB5cxx11Ev0
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev1354
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10661051
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.gcov.html b/coverage/core/ActionWithValue.cpp.gcov.html new file mode 100644 index 0000000000..1ccd32148b --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.gcov.html @@ -0,0 +1,309 @@ + + + + + + + + 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:11112489.5 %
Date:2024-06-10 08:19:14Functions: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 "tools/Exception.h"
+      24             : #include "tools/OpenMP.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28        4328 : void ActionWithValue::registerKeywords(Keywords& keys) {
+      29        4328 :   keys.setComponentsIntroduction("By default the value of the calculated quantity can be referenced elsewhere in the "
+      30             :                                  "input file by using the label of the action.  Alternatively this Action can be used "
+      31             :                                  "to calculate the following quantities by employing the keywords listed "
+      32             :                                  "below.  These quantities can be referenced elsewhere in the input by using this Action's "
+      33             :                                  "label followed by a dot and the name of the quantity required from the list below.");
+      34        8656 :   keys.addFlag("NUMERICAL_DERIVATIVES", false, "calculate the derivatives for these quantities numerically");
+      35        4328 : }
+      36             : 
+      37           0 : void ActionWithValue::noAnalyticalDerivatives(Keywords& keys) {
+      38           0 :   keys.remove("NUMERICAL_DERIVATIVES");
+      39           0 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"analytical derivatives are not implemented for this keyword so numerical derivatives are always used");
+      40           0 : }
+      41             : 
+      42        1194 : void ActionWithValue::componentsAreNotOptional(Keywords& keys) {
+      43        1194 :   keys.setComponentsIntroduction("By default this Action calculates the following quantities. These quantities can "
+      44             :                                  "be referenced elsewhere in the input by using this Action's label followed by a "
+      45             :                                  "dot and the name of the quantity required from the list below.");
+      46        1194 : }
+      47             : 
+      48         241 : void ActionWithValue::useCustomisableComponents(Keywords& keys) {
+      49         241 :   keys.setComponentsIntroduction("The names of the components in this action can be customized by the user in the "
+      50             :                                  "actions input file.  However, in addition to the components that can be customized the "
+      51             :                                  "following quantities will always be output");
+      52         241 : }
+      53             : 
+      54        4131 : ActionWithValue::ActionWithValue(const ActionOptions&ao):
+      55             :   Action(ao),
+      56        4131 :   noderiv(true),
+      57        4131 :   numericalDerivatives(false)
+      58             : {
+      59       11924 :   if( keywords.exists("NUMERICAL_DERIVATIVES") ) parseFlag("NUMERICAL_DERIVATIVES",numericalDerivatives);
+      60        4131 :   if(numericalDerivatives) log.printf("  using numerical derivatives\n");
+      61        4131 : }
+      62             : 
+      63        4131 : ActionWithValue::~ActionWithValue() {
+      64             : // empty destructor to delete unique_ptr
+      65        4131 : }
+      66             : 
+      67     1389822 : void ActionWithValue::clearInputForces() {
+      68     3470875 :   for(unsigned i=0; i<values.size(); i++) values[i]->clearInputForce();
+      69     1389822 : }
+      70             : 
+      71     1392602 : void ActionWithValue::clearDerivatives() {
+      72     1392602 :   unsigned nt = OpenMP::getNumThreads();
+      73     1392602 :   #pragma omp parallel num_threads(nt)
+      74             :   {
+      75             :     #pragma omp for
+      76             :     for(unsigned i=0; i<values.size(); i++) values[i]->clearDerivatives();
+      77             :   }
+      78     1392602 : }
+      79             : 
+      80             : // -- These are the routine for copying the value pointers to other classes -- //
+      81             : 
+      82    10661051 : bool ActionWithValue::exists( const std::string& name ) const {
+      83   116533068 :   for(unsigned i=0; i<values.size(); ++i) {
+      84   105897960 :     if (values[i]->name==name) return true;
+      85             :   }
+      86             :   return false;
+      87             : }
+      88             : 
+      89       26102 : Value* ActionWithValue::copyOutput( const std::string& name ) const {
+      90    11307760 :   for(unsigned i=0; i<values.size(); ++i) {
+      91    11307760 :     if (values[i]->name==name) return values[i].get();
+      92             :   }
+      93           0 :   plumed_merror("there is no pointer with name " + name);
+      94             : }
+      95             : 
+      96       10763 : Value* ActionWithValue::copyOutput( const unsigned& n ) const {
+      97       10763 :   plumed_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+      98       10763 :   return values[n].get();
+      99             : }
+     100             : 
+     101             : // -- HERE WE HAVE THE STUFF FOR THE DEFAULT VALUE -- //
+     102             : 
+     103          56 : void ActionWithValue::addValue() {
+     104          56 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     105          56 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), false ) );
+     106          56 : }
+     107             : 
+     108        2317 : void ActionWithValue::addValueWithDerivatives() {
+     109        2317 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     110        2317 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), true ) );
+     111        2317 : }
+     112             : 
+     113        1697 : void ActionWithValue::setNotPeriodic() {
+     114        1697 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     115        1697 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     116        1697 :   values[0]->min=0; values[0]->max=0;
+     117        1697 :   values[0]->setupPeriodicity();
+     118        1697 : }
+     119             : 
+     120         676 : void ActionWithValue::setPeriodic( const std::string& min, const std::string& max ) {
+     121         676 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     122         676 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     123         676 :   values[0]->setDomain( min, max );
+     124         676 : }
+     125             : 
+     126    16301774 : Value* ActionWithValue::getPntrToValue() {
+     127             :   plumed_dbg_massert(values.size()==1,"The number of components is not equal to one");
+     128             :   plumed_dbg_massert(values[0]->name==getLabel(), "The value you are trying to retrieve is not the default");
+     129    16301774 :   return values[0].get();
+     130             : }
+     131             : 
+     132             : // -- HERE WE HAVE THE STUFF FOR NAMED VALUES / COMPONENTS -- //
+     133             : 
+     134       22633 : void ActionWithValue::addComponent( const std::string& name ) {
+     135       22633 :   if( !keywords.outputComponentExists(name,true) ) {
+     136           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     137             :                   "registerKeywords as described in the developer docs.");
+     138             :   }
+     139       45266 :   std::string thename; thename=getLabel() + "." + name;
+     140    18683668 :   for(unsigned i=0; i<values.size(); ++i) {
+     141    18661035 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     142    18661035 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     143    18661035 :     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"
+     144             :                    "Remove the line addComponent(\"bias\") from your bias.");
+     145             :   }
+     146       22633 :   values.emplace_back(Tools::make_unique<Value>(this,thename, false ) );
+     147       22633 :   std::string msg="  added component to this action:  "+thename+" \n";
+     148       22633 :   log.printf(msg.c_str());
+     149       22633 : }
+     150             : 
+     151       10710 : void ActionWithValue::addComponentWithDerivatives( const std::string& name ) {
+     152       10710 :   if( !keywords.outputComponentExists(name,true) ) {
+     153           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     154             :                   "registerKeywords as described in the developer doc.");
+     155             :   }
+     156       21420 :   std::string thename; thename=getLabel() + "." + name;
+     157     2441407 :   for(unsigned i=0; i<values.size(); ++i) {
+     158     2430697 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     159     2430697 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     160     2430697 :     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"
+     161             :                    "Remove the line addComponentWithDerivatives(\"bias\") from your bias.");
+     162             :   }
+     163       10710 :   values.emplace_back(Tools::make_unique<Value>(this,thename, true ) );
+     164       10710 :   std::string msg="  added component to this action:  "+thename+" \n";
+     165       10710 :   log.printf(msg.c_str());
+     166       10710 : }
+     167             : 
+     168    10628297 : int ActionWithValue::getComponent( const std::string& name ) const {
+     169    10628297 :   plumed_massert( !exists( getLabel() ), "You should not be calling this routine if you are using a value");
+     170    21256594 :   std::string thename; thename=getLabel() + "." + name;
+     171    64111312 :   for(unsigned i=0; i<values.size(); ++i) {
+     172    64178768 :     if (values[i]->name==thename) return i;
+     173             :   }
+     174           0 :   plumed_merror("there is no component with name " + name);
+     175             : }
+     176             : 
+     177           0 : std::string ActionWithValue::getComponentsList( ) const {
+     178             :   std::string complist;
+     179           0 :   for(unsigned i=0; i<values.size(); ++i) {
+     180           0 :     complist+=values[i]->name+" ";
+     181             :   }
+     182           0 :   return complist;
+     183             : }
+     184             : 
+     185        1354 : std::vector<std::string> ActionWithValue::getComponentsVector( ) const {
+     186             :   std::vector<std::string> complist;
+     187      220352 :   for(unsigned i=0; i<values.size(); ++i) {
+     188      218998 :     complist.push_back(values[i]->name);
+     189             :   }
+     190        1354 :   return complist;
+     191           0 : }
+     192             : 
+     193       30152 : void ActionWithValue::componentIsNotPeriodic( const std::string& name ) {
+     194       30152 :   int kk=getComponent(name);
+     195       30152 :   values[kk]->min=0; values[kk]->max=0;
+     196       30152 :   values[kk]->setupPeriodicity();
+     197       30152 : }
+     198             : 
+     199          92 : void ActionWithValue::componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max ) {
+     200          92 :   int kk=getComponent(name);
+     201          92 :   values[kk]->setDomain(min,max);
+     202          92 : }
+     203             : 
+     204     1389822 : void ActionWithValue::setGradientsIfNeeded() {
+     205     2779644 :   if(isOptionOn("GRADIENTS")) {
+     206         366 :     for(unsigned i=0; i<values.size(); i++) values[i]->setGradients();
+     207             :   }
+     208     1389822 : }
+     209             : 
+     210     3493078 : void ActionWithValue::turnOnDerivatives() {
+     211             :   // Turn on the derivatives
+     212     3493078 :   noderiv=false;
+     213             :   // Resize the derivatives
+     214  4106212105 :   for(unsigned i=0; i<values.size(); ++i) values[i]->resizeDerivatives( getNumberOfDerivatives() );
+     215             :   // And turn on the derivatives in all actions on which we are dependent
+     216     7085574 :   for(unsigned i=0; i<getDependencies().size(); ++i) {
+     217     3592496 :     ActionWithValue* vv=dynamic_cast<ActionWithValue*>( getDependencies()[i] );
+     218     3592496 :     if(vv) vv->turnOnDerivatives();
+     219             :   }
+     220     3493078 : }
+     221             : 
+     222    10598053 : Value* ActionWithValue::getPntrToComponent( const std::string& name ) {
+     223    10598053 :   int kk=getComponent(name);
+     224    10598053 :   return values[kk].get();
+     225             : }
+     226             : 
+     227     2139071 : Value* ActionWithValue::getPntrToComponent( int n ) {
+     228             :   plumed_dbg_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     229     2139071 :   return values[n].get();
+     230             : }
+     231             : 
+     232             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..00affac20a --- /dev/null +++ b/coverage/core/ActionWithValue.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:212295.5 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZN4PLMD15ActionWithValue23useNumericalDerivativesEv2
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv5924
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj153914
_ZN4PLMD15ActionWithValue8setValueERKd194067
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv1633909
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2780094
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithValue.h.func.html b/coverage/core/ActionWithValue.h.func.html new file mode 100644 index 0000000000..c253449610 --- /dev/null +++ b/coverage/core/ActionWithValue.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:212295.5 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZN4PLMD15ActionWithValue23useNumericalDerivativesEv2
_ZN4PLMD15ActionWithValue8setValueERKd194067
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2780094
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj153914
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv1633909
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv5924
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithValue.h.gcov.html b/coverage/core/ActionWithValue.h.gcov.html new file mode 100644 index 0000000000..73db79ae45 --- /dev/null +++ b/coverage/core/ActionWithValue.h.gcov.html @@ -0,0 +1,297 @@ + + + + + + + + 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:212295.5 %
Date:2024-06-10 08:19:14Functions: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             : #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             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /**
+      34             : \ingroup MULTIINHERIT
+      35             : Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some derivatives.
+      36             : This is used for PLMD::Bias, PLMD::Colvar and PLMD::Function
+      37             : 
+      38             : The vast majority of the PLMD::Action objects that are implemented in
+      39             : plumed calculate some quantity or a set of quantities.  This could be
+      40             : the value of a CV, the value of a function or the potential due to a bias.
+      41             : PLMD::ActionWithValue provides the functionality for storing these quantities
+      42             : and (in tandem with PLMD::ActionWithArguments) the functionality for passing
+      43             : quantities between PLMD::Actions.  When you are deciding what quantities
+      44             : your new PLMD::Action will need to store using PLMD::ActionWithValue you must
+      45             : ask yourself the following two questions:
+      46             : 
+      47             : - Do I need to differentiate my output quantities
+      48             : - Is my PLMD::Action calculating a single thing or does the output have multiple components
+      49             : 
+      50             : If the answer to the first of these questions is yes then you must setup your values
+      51             : you using either PLMD::ActionWithValue::addValueWithDerivatives() or
+      52             : PLMD::ActionWithValue::addComponentWithDerivatives.  If the answer is no you
+      53             : can set up values using PLMD::ActionWithValue::addValue() or PLMD::ActionWithValue::addComponent().
+      54             : The precise routine you use to setup your values will depend on your answer to the
+      55             : second question.  As you are probably aware if the output of your PLMD::Action is a
+      56             : single quantity you can reference that quantity in the input file using the label of the
+      57             : PLMD::Action it was calculated in.  If your action <b> outputs only one quantity </b>
+      58             : we call that quantity the <b> value </b> of the Action.  To set the <b> value </b> and get pointers to it
+      59             : you should <b> use the set of routines that have the word value in the name </b>.  If, by contrast,
+      60             : your PLMD::Action calculates multiple quantities then these quantities are referenced in input using the
+      61             : label.component syntax.  We refer to these <b> multiple quantities </b> the <b> components </b>
+      62             : of the PLMD::Action.  Perhaps unsurprisingly, when you manipulate the <b> components </b> of an
+      63             : PLMD::Action you should use <b> the routines with the word component in the name. </b>
+      64             : */
+      65             : 
+      66             : class ActionWithValue :
+      67             :   public virtual Action
+      68             : {
+      69             : private:
+      70             : /// An array containing the values for this action
+      71             :   std::vector<std::unique_ptr<Value>> values;
+      72             : /// Are we skipping the calculation of the derivatives
+      73             :   bool noderiv;
+      74             : /// Are we using numerical derivatives to differentiate
+      75             :   bool numericalDerivatives;
+      76             : /// Return the index for the component named name
+      77             :   int getComponent( const std::string& name ) const;
+      78             : public:
+      79             : 
+      80             : // -------- The action has one value only  ---------------- //
+      81             : 
+      82             : /// Add a value with the name label
+      83             :   void addValue();
+      84             : /// Add a value with the name label that has derivatives
+      85             :   void addValueWithDerivatives();
+      86             : /// Set your default value to have no periodicity
+      87             :   void setNotPeriodic();
+      88             : /// Set the value to be periodic with a particular domain
+      89             :   void setPeriodic( const std::string& min, const std::string& max );
+      90             : protected:
+      91             : /// Get a pointer to the default value
+      92             :   Value* getPntrToValue();
+      93             : /// Set the default value (the one without name)
+      94             :   void setValue(const double& d);
+      95             : 
+      96             : // -------- The action has multiple components ---------- //
+      97             : 
+      98             : public:
+      99             : /// Add a value with a name like label.name
+     100             :   void addComponent( const std::string& name );
+     101             : /// Add a value with a name like label.name that has derivatives
+     102             :   void addComponentWithDerivatives( const std::string& name );
+     103             : /// Set your value component to have no periodicity
+     104             :   void componentIsNotPeriodic( const std::string& name );
+     105             : /// Set the value to be periodic with a particular domain
+     106             :   void componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max );
+     107             : protected:
+     108             : /// Return a pointer to the component by index
+     109             :   Value* getPntrToComponent(int i);
+     110             : /// Return a pointer to the value by name
+     111             :   Value* getPntrToComponent(const std::string& name);
+     112             : public:
+     113             :   explicit ActionWithValue(const ActionOptions&ao);
+     114             :   ~ActionWithValue();
+     115             : 
+     116             : /// Register all the relevant keywords for the action
+     117             :   static void registerKeywords( Keywords& keys );
+     118             : /// Insist that numerical derivatives should always be used for an action and make this fact appear in the manual
+     119             :   static void noAnalyticalDerivatives(Keywords& keys);
+     120             : /// Puts a message into the manual that the components always output
+     121             :   static void componentsAreNotOptional(Keywords& keys);
+     122             : /// The components in the action will depend on the user
+     123             :   static void useCustomisableComponents(Keywords& keys);
+     124             : /// Are we not calculating derivatives
+     125             :   virtual bool doNotCalculateDerivatives() const ;
+     126             : /// Get the value of one of the components of the PLMD::Action
+     127             :   double getOutputQuantity( const unsigned j ) const ;
+     128             : /// Get the value with a specific name (N.B. if there is no such value this returns zero)
+     129             :   double getOutputQuantity( const std::string& name ) const ;
+     130             : 
+     131             : //  --- Routines for passing stuff to ActionWithArguments -- //
+     132             : 
+     133             : /// Check if a value with a particular name is present.  This is only used in PLMD::ActionWithArguments.
+     134             : /// You should not use it when manipulating components.
+     135             :   bool exists( const std::string& name ) const;
+     136             : /// Return a pointer to the value with name (this is used to retrieve values in other PLMD::Actions)
+     137             : /// You should NEVER use this routine to refer to the components of your PLMD::Action.  Use
+     138             : /// getPntrToComponent instead.
+     139             :   Value* copyOutput( const std::string&name ) const;
+     140             : /// Return a pointer to the value with this number (this is used to retrieve values in other PLMD::Actions)
+     141             : /// You should NEVER use this routine to refer to the components of your PLMD::Action.  Use
+     142             : /// getPntrToComponent instead.
+     143             :   Value* copyOutput( const unsigned& n ) const;
+     144             : /// get a string that contains all the available components
+     145             :   std::string getComponentsList( ) const ;
+     146             : /// get a vector that contains the label for all the components
+     147             :   std::vector<std::string> getComponentsVector( ) const ;
+     148             : 
+     149             : 
+     150             : // -- Routines for everything else -- //
+     151             : 
+     152             : /// Returns the number of values defined
+     153             :   int getNumberOfComponents() const ;
+     154             : /// Clear the forces on the values
+     155             :   void clearInputForces();
+     156             : /// Clear the derivatives of values wrt parameters
+     157             :   virtual void clearDerivatives();
+     158             : /// Calculate the gradients and store them for all the values (need for projections)
+     159             :   void setGradientsIfNeeded();
+     160             : /// Set the value
+     161             :   void setValue(Value*,double);
+     162             : /// Check if numerical derivatives should be used
+     163             :   bool checkNumericalDerivatives() const override;
+     164             : /// This forces the class to use numerical derivatives
+     165             :   void useNumericalDerivatives();
+     166             : // These are things for using vectors of values as fields
+     167           0 :   virtual void checkFieldsAllowed() { error("cannot use this action as a field"); }
+     168             :   virtual unsigned getNumberOfDerivatives()=0;
+     169             : /// Activate the calculation of derivatives
+     170             :   virtual void turnOnDerivatives();
+     171             : };
+     172             : 
+     173             : inline
+     174      153914 : double ActionWithValue::getOutputQuantity(const unsigned j) const {
+     175      153914 :   plumed_massert(j<values.size(),"index requested is out of bounds");
+     176      153914 :   return values[j]->get();
+     177             : }
+     178             : 
+     179             : inline
+     180     2780094 : double ActionWithValue::getOutputQuantity( const std::string& name ) const {
+     181     5560188 :   std::string thename; thename=getLabel() + "." + name;
+     182     6467996 :   for(unsigned i=0; i<values.size(); ++i) {
+     183     3775267 :     if( values[i]->name==thename ) return values[i]->value;
+     184             :   }
+     185             :   return 0.0;
+     186             : }
+     187             : 
+     188             : inline
+     189      194067 : void ActionWithValue::setValue(const double& d) {
+     190      194067 :   plumed_massert(values.size()==1, "cannot use setValue in multi-component actions");
+     191      194067 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     192      194067 :   values[0]->set(d);
+     193      194067 : }
+     194             : 
+     195             : inline
+     196             : int ActionWithValue::getNumberOfComponents() const {
+     197      142216 :   return values.size();
+     198             : }
+     199             : 
+     200             : inline
+     201           2 : void ActionWithValue::useNumericalDerivatives() {
+     202           4 :   plumed_massert( keywords.exists("NUMERICAL_DERIVATIVES"), "numerical derivatives are not permitted for this action" );
+     203           2 :   numericalDerivatives=true;
+     204           2 : }
+     205             : 
+     206             : inline
+     207     1633909 : bool ActionWithValue::checkNumericalDerivatives() const {
+     208     1633953 :   return numericalDerivatives;
+     209             : }
+     210             : 
+     211             : inline
+     212        5924 : bool ActionWithValue::doNotCalculateDerivatives() const {
+     213    68367370 :   return noderiv;
+     214             : }
+     215             : 
+     216             : 
+     217             : 
+     218             : }
+     219             : 
+     220             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..fc338e1706 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:4646100.0 %
Date:2024-06-10 08:19:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtomD0Ev0
_ZN4PLMD21ActionWithVirtualAtomD1Ev0
_ZN4PLMD21ActionWithVirtualAtom12setGradientsEv9
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt5arrayINS_13TensorGenericILj3ELj3EEELm3EE605
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv605
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE7165
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE7176
_ZN4PLMD21ActionWithVirtualAtomD2Ev7176
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE7181
_ZN4PLMD21ActionWithVirtualAtom5applyEv14328
_ZN4PLMD21ActionWithVirtualAtom20setGradientsIfNeededEv14412
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.func.html b/coverage/core/ActionWithVirtualAtom.cpp.func.html new file mode 100644 index 0000000000..ee192ec12e --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:4646100.0 %
Date:2024-06-10 08:19:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE7165
_ZN4PLMD21ActionWithVirtualAtom12setGradientsEv9
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE7181
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt5arrayINS_13TensorGenericILj3ELj3EEELm3EE605
_ZN4PLMD21ActionWithVirtualAtom20setGradientsIfNeededEv14412
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv605
_ZN4PLMD21ActionWithVirtualAtom5applyEv14328
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE7176
_ZN4PLMD21ActionWithVirtualAtomD0Ev0
_ZN4PLMD21ActionWithVirtualAtomD1Ev0
_ZN4PLMD21ActionWithVirtualAtomD2Ev7176
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.gcov.html b/coverage/core/ActionWithVirtualAtom.cpp.gcov.html new file mode 100644 index 0000000000..c1021be47b --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + 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:4646100.0 %
Date:2024-06-10 08:19:14Functions:91275.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 "ActionWithVirtualAtom.h"
+      23             : #include "Atoms.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27        7181 : void ActionWithVirtualAtom::registerKeywords(Keywords& keys) {
+      28        7181 :   Action::registerKeywords(keys);
+      29        7181 :   ActionAtomistic::registerKeywords(keys);
+      30       14362 :   keys.add("atoms","ATOMS","the list of atoms which are involved the virtual atom's definition");
+      31        7181 : }
+      32             : 
+      33        7176 : ActionWithVirtualAtom::ActionWithVirtualAtom(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   ActionAtomistic(ao),
+      36        7176 :   index(atoms.addVirtualAtom(this))
+      37             : {
+      38        7176 :   log<<"  serial associated to this virtual atom is "<<index.serial()<<"\n";
+      39        7176 : }
+      40             : 
+      41        7176 : ActionWithVirtualAtom::~ActionWithVirtualAtom() {
+      42        7176 :   atoms.removeVirtualAtom(this);
+      43        7176 : }
+      44             : 
+      45       14328 : void ActionWithVirtualAtom::apply() {
+      46       14328 :   Vector & f(atoms.forces[index.index()]);
+      47       94916 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) modifyForces()[i]=matmul(derivatives[i],f);
+      48             :   Tensor & v(modifyVirial());
+      49       57312 :   for(unsigned i=0; i<3; i++) v+=boxDerivatives[i]*f[i];
+      50       14328 :   f.zero(); // after propagating the force to the atoms used to compute the vatom, we reset this to zero
+      51             :   // this is necessary to avoid double counting if then one tries to compute the total force on the c.o.m. of the system.
+      52             :   // notice that this is currently done in FIT_TO_TEMPLATE
+      53       14328 : }
+      54             : 
+      55        7165 : void ActionWithVirtualAtom::requestAtoms(const std::vector<AtomNumber> & a) {
+      56        7165 :   ActionAtomistic::requestAtoms(a);
+      57        7165 :   derivatives.resize(a.size());
+      58        7165 : }
+      59             : 
+      60           9 : void ActionWithVirtualAtom::setGradients() {
+      61             :   gradients.clear();
+      62          45 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+      63          36 :     AtomNumber an=getAbsoluteIndex(i);
+      64             :     // this case if the atom is a virtual one
+      65          36 :     if(atoms.isVirtualAtom(an)) {
+      66             :       const ActionWithVirtualAtom* a=atoms.getVirtualAtomsAction(an);
+      67          36 :       for(const auto & p : a->gradients) {
+      68          30 :         gradients[p.first]+=matmul(derivatives[i],p.second);
+      69             :       }
+      70             :       // this case if the atom is a normal one
+      71             :     } else {
+      72          30 :       gradients[an]+=derivatives[i];
+      73             :     }
+      74             :   }
+      75           9 : }
+      76             : 
+      77         605 : void ActionWithVirtualAtom::setBoxDerivatives(const std::array<Tensor,3> &d) {
+      78         605 :   boxDerivatives=d;
+      79             : // Subtract the trivial part coming from a distorsion applied to the ghost atom first.
+      80             : // Notice that this part alone should exactly cancel the already accumulated virial
+      81             : // due to forces on this atom.
+      82         605 :   Vector pos=atoms.positions[index.index()];
+      83        7865 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) boxDerivatives[j][i][j]+=pos[i];
+      84         605 : }
+      85             : 
+      86         605 : void ActionWithVirtualAtom::setBoxDerivativesNoPbc() {
+      87         605 :   std::array<Tensor,3> bd;
+      88       24200 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) for(unsigned k=0; k<3; k++) {
+      89             : // Notice that this expression is very similar to the one used in Colvar::setBoxDerivativesNoPbc().
+      90             : // Indeed, we have the negative of a sum over dependent atoms (l) of the external product between positions
+      91             : // and derivatives. Notice that this only works only when Pbc have not been used to compute
+      92             : // derivatives.
+      93       16902 :         for(unsigned l=0; l<getNumberOfAtoms(); l++) {
+      94         567 :           bd[k][i][j]-=getPosition(l)[i]*derivatives[l][j][k];
+      95             :         }
+      96             :       }
+      97         605 :   setBoxDerivatives(bd);
+      98         605 : }
+      99             : 
+     100             : 
+     101             : 
+     102       14412 : void ActionWithVirtualAtom::setGradientsIfNeeded() {
+     103       28824 :   if(isOptionOn("GRADIENTS")) {
+     104           9 :     setGradients() ;
+     105             :   }
+     106       14412 : }
+     107             : 
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..1f11379773 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + 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:88100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.func.html b/coverage/core/ActionWithVirtualAtom.h.func.html new file mode 100644 index 0000000000..a16eb1c3d5 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + 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:88100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.gcov.html b/coverage/core/ActionWithVirtualAtom.h.gcov.html new file mode 100644 index 0000000000..7f95c49ba9 --- /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:88100.0 %
Date:2024-06-10 08:19:14Functions: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_ActionWithVirtualAtom_h
+      23             : #define __PLUMED_core_ActionWithVirtualAtom_h
+      24             : 
+      25             : #include "ActionAtomistic.h"
+      26             : #include "tools/AtomNumber.h"
+      27             : #include "tools/Vector.h"
+      28             : #include "tools/Tensor.h"
+      29             : #include "Atoms.h"
+      30             : #include <array>
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : /**
+      35             : \ingroup INHERIT
+      36             : Inherit from here if you are calculating the position of a virtual atom (eg a center of mass)
+      37             : */
+      38             : 
+      39             : /// Class to add a single virtual atom to the system.
+      40             : /// (it might be extended to add multiple virtual atoms).
+      41             : class ActionWithVirtualAtom:
+      42             :   public ActionAtomistic
+      43             : {
+      44             :   const AtomNumber index;
+      45             :   std::vector<Tensor> derivatives;
+      46             :   std::array<Tensor,3> boxDerivatives;
+      47             :   std::map<AtomNumber,Tensor> gradients;
+      48             :   void apply() override;
+      49             : protected:
+      50             : /// Set position of the virtual atom
+      51             :   void setPosition(const Vector &);
+      52             : /// Set its mass
+      53             :   void setMass(double);
+      54             : /// Set its charge
+      55             :   void setCharge(double);
+      56             : /// Request atoms on which the calculation depends
+      57             :   void requestAtoms(const std::vector<AtomNumber> & a);
+      58             : /// Set the derivatives of virtual atom coordinate wrt atoms on which it dependes
+      59             :   void setAtomsDerivatives(const std::vector<Tensor> &d);
+      60             : /// Set the box derivatives.
+      61             : /// This should be an array of size 3. First index corresponds
+      62             : /// to the components of the virtual atom.
+      63             : /// Notice that this routine subtract the trivial term coming from cell deformation
+      64             : /// since this term is already implicitly included. Indeed, if the vatom
+      65             : /// position is a linear function of atomic coordinates it is not necessary
+      66             : /// to call this function (implicit term is fine) (e.g. vatom::COM and vatom::Center).
+      67             : /// On the other hand if the vatom position is a non-linear function of atomic coordinates this
+      68             : /// should be called (see vatom::Ghost).
+      69             :   void setBoxDerivatives(const std::array<Tensor,3> &d);
+      70             : /// Set box derivatives automatically.
+      71             : /// It should be called after the settomsDerivatives has been used for all
+      72             : /// single atoms.
+      73             : /// \warning It only works for virtual atoms NOT using PBCs!
+      74             : ///          This implies that all atoms used + the new virtual atom should be
+      75             : ///          in the same periodic image.
+      76             :   void setBoxDerivativesNoPbc();
+      77             : public:
+      78             :   void setGradients();
+      79             :   const std::map<AtomNumber,Tensor> & getGradients()const;
+      80             : /// Return the atom id of the corresponding virtual atom
+      81             :   AtomNumber getIndex()const;
+      82             :   explicit ActionWithVirtualAtom(const ActionOptions&ao);
+      83             :   ~ActionWithVirtualAtom();
+      84             :   static void registerKeywords(Keywords& keys);
+      85             :   void setGradientsIfNeeded();
+      86             : };
+      87             : 
+      88             : inline
+      89             : AtomNumber ActionWithVirtualAtom::getIndex()const {
+      90        7215 :   return index;
+      91             : }
+      92             : 
+      93             : inline
+      94             : void ActionWithVirtualAtom::setPosition(const Vector & pos) {
+      95       14412 :   atoms.positions[index.index()]=pos;
+      96         598 : }
+      97             : 
+      98             : inline
+      99             : void ActionWithVirtualAtom::setMass(double m) {
+     100         854 :   atoms.masses[index.index()]=m;
+     101             : }
+     102             : 
+     103             : inline
+     104             : void ActionWithVirtualAtom::setCharge(double c) {
+     105       14408 :   atoms.charges[index.index()]=c;
+     106       13798 : }
+     107             : 
+     108             : inline
+     109             : void ActionWithVirtualAtom::setAtomsDerivatives(const std::vector<Tensor> &d) {
+     110       14412 :   derivatives=d;
+     111       14412 : }
+     112             : 
+     113             : inline
+     114             : const std::map<AtomNumber,Tensor> & ActionWithVirtualAtom::getGradients()const {
+     115             :   return gradients;
+     116             : }
+     117             : 
+     118             : }
+     119             : 
+     120             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Atoms.cpp.func-sort-c.html b/coverage/core/Atoms.cpp.func-sort-c.html new file mode 100644 index 0000000000..96362c50f8 --- /dev/null +++ b/coverage/core/Atoms.cpp.func-sort-c.html @@ -0,0 +1,293 @@ + + + + + + + + LCOV - plumed test coverage - core/Atoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Atoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:37439395.2 %
Date:2024-06-10 08:19:14Functions:525594.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Atoms14getLocalMassesERSt6vectorIdSaIdEE0
_ZN4PLMD5Atoms16getLocalMDForcesERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZNK4PLMD5Atoms15getMDKBoltzmannEv0
_ZN4PLMD5Atoms12setPositionsERKNS_11TypesafePtrEi3
_ZN4PLMD5Atoms9setForcesERKNS_11TypesafePtrEi3
_ZN4PLMD5Atoms10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE20
_ZN4PLMD5Atoms15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE20
_ZN4PLMD5Atoms18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd40
_ZN4PLMD5Atoms6setKbTERKNS_11TypesafePtrE59
_ZN4PLMD5Atoms10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE60
_ZN4PLMD5Atoms10readBinaryERSi114
_ZNK4PLMD5Atoms11writeBinaryERSo114
_ZN4PLMD5Atoms11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD5Atoms13clearFullListEv116
_ZN4PLMD5Atoms14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD5Atoms11insertGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_10AtomNumberESaISA_EE119
_ZN4PLMD5Atoms11removeGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE119
_ZN4PLMD5Atoms19DomainDecomposition6enableERNS_12CommunicatorE337
_ZN4PLMD5Atoms22setDomainDecompositionERNS_12CommunicatorE337
_ZN4PLMD5Atoms14getLocalForcesERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE450
_ZN4PLMD5Atoms17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE450
_ZN4PLMD5Atoms18setAtomsContiguousEi489
_ZNK4PLMD5Atoms13getKBoltzmannEv591
_ZN4PLMD5Atoms11setTimeStepERKNS_11TypesafePtrE774
_ZN4PLMD5Atoms16setRealPrecisionEi780
_ZN4PLMD5Atoms9setNatomsEi893
_ZN4PLMD5Atoms8shareAllEv898
_ZN4PLMD5Atoms4initEv914
_ZN4PLMD5Atoms11updateUnitsEv933
_ZN4PLMD5Atoms16setAtomsGatindexERKNS_11TypesafePtrEb988
_ZNK4PLMD5Atoms6getKbTEv1186
_ZN4PLMD5Atoms14setAtomsNlocalEi1477
_ZNK4PLMD5Atoms16getRealPrecisionEv1688
_ZNK4PLMD5Atoms9double2MDERKdRKNS_11TypesafePtrE2365
_ZN4PLMD5Atoms14addVirtualAtomEPNS_21ActionWithVirtualAtomE7176
_ZN4PLMD5Atoms17removeVirtualAtomEPNS_21ActionWithVirtualAtomE7176
_ZN4PLMD5Atoms9setEnergyERKNS_11TypesafePtrE9792
_ZN4PLMD5Atoms3addEPNS_15ActionAtomisticE10109
_ZN4PLMD5Atoms6removeEPNS_15ActionAtomisticE10109
_ZNK4PLMD5Atoms9MD2doubleERKNS_11TypesafePtrERd12830
_ZN4PLMD5Atoms13resizeVectorsEj14352
_ZN4PLMD5Atoms10setChargesERKNS_11TypesafePtrE37570
_ZN4PLMD5Atoms9setVirialERKNS_11TypesafePtrE37675
_ZN4PLMD5Atoms6setBoxERKNS_11TypesafePtrE43333
_ZN4PLMD5Atoms12updateForcesEv46032
_ZN4PLMD5Atoms5shareEv46042
_ZN4PLMD5Atoms4waitEv46156
_ZN4PLMD5Atoms5shareERKSt3setINS_10AtomNumberESt4lessIS2_ESaIS2_EE46156
_ZN4PLMD5Atoms12setPositionsERKNS_11TypesafePtrE47474
_ZN4PLMD5Atoms9setForcesERKNS_11TypesafePtrE47474
_ZN4PLMD5Atoms9setMassesERKNS_11TypesafePtrE47478
_ZN4PLMD5Atoms9startStepEv247830
_ZN4PLMD5AtomsC2ERNS_10PlumedMainE404395
_ZN4PLMD5AtomsD2Ev404395
_ZNK4PLMD5Atoms11getTimeStepEv3158863
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Atoms.cpp.func.html b/coverage/core/Atoms.cpp.func.html new file mode 100644 index 0000000000..fb39c51437 --- /dev/null +++ b/coverage/core/Atoms.cpp.func.html @@ -0,0 +1,293 @@ + + + + + + + + LCOV - plumed test coverage - core/Atoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Atoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:37439395.2 %
Date:2024-06-10 08:19:14Functions:525594.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Atoms10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE60
_ZN4PLMD5Atoms10readBinaryERSi114
_ZN4PLMD5Atoms10setChargesERKNS_11TypesafePtrE37570
_ZN4PLMD5Atoms10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE20
_ZN4PLMD5Atoms11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD5Atoms11insertGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_10AtomNumberESaISA_EE119
_ZN4PLMD5Atoms11removeGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE119
_ZN4PLMD5Atoms11setTimeStepERKNS_11TypesafePtrE774
_ZN4PLMD5Atoms11updateUnitsEv933
_ZN4PLMD5Atoms12setPositionsERKNS_11TypesafePtrE47474
_ZN4PLMD5Atoms12setPositionsERKNS_11TypesafePtrEi3
_ZN4PLMD5Atoms12updateForcesEv46032
_ZN4PLMD5Atoms13clearFullListEv116
_ZN4PLMD5Atoms13resizeVectorsEj14352
_ZN4PLMD5Atoms14addVirtualAtomEPNS_21ActionWithVirtualAtomE7176
_ZN4PLMD5Atoms14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD5Atoms14getLocalForcesERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE450
_ZN4PLMD5Atoms14getLocalMassesERSt6vectorIdSaIdEE0
_ZN4PLMD5Atoms14setAtomsNlocalEi1477
_ZN4PLMD5Atoms15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE20
_ZN4PLMD5Atoms16getLocalMDForcesERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMD5Atoms16setAtomsGatindexERKNS_11TypesafePtrEb988
_ZN4PLMD5Atoms16setRealPrecisionEi780
_ZN4PLMD5Atoms17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE450
_ZN4PLMD5Atoms17removeVirtualAtomEPNS_21ActionWithVirtualAtomE7176
_ZN4PLMD5Atoms18setAtomsContiguousEi489
_ZN4PLMD5Atoms18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd40
_ZN4PLMD5Atoms19DomainDecomposition6enableERNS_12CommunicatorE337
_ZN4PLMD5Atoms22setDomainDecompositionERNS_12CommunicatorE337
_ZN4PLMD5Atoms3addEPNS_15ActionAtomisticE10109
_ZN4PLMD5Atoms4initEv914
_ZN4PLMD5Atoms4waitEv46156
_ZN4PLMD5Atoms5shareERKSt3setINS_10AtomNumberESt4lessIS2_ESaIS2_EE46156
_ZN4PLMD5Atoms5shareEv46042
_ZN4PLMD5Atoms6removeEPNS_15ActionAtomisticE10109
_ZN4PLMD5Atoms6setBoxERKNS_11TypesafePtrE43333
_ZN4PLMD5Atoms6setKbTERKNS_11TypesafePtrE59
_ZN4PLMD5Atoms8shareAllEv898
_ZN4PLMD5Atoms9setEnergyERKNS_11TypesafePtrE9792
_ZN4PLMD5Atoms9setForcesERKNS_11TypesafePtrE47474
_ZN4PLMD5Atoms9setForcesERKNS_11TypesafePtrEi3
_ZN4PLMD5Atoms9setMassesERKNS_11TypesafePtrE47478
_ZN4PLMD5Atoms9setNatomsEi893
_ZN4PLMD5Atoms9setVirialERKNS_11TypesafePtrE37675
_ZN4PLMD5Atoms9startStepEv247830
_ZN4PLMD5AtomsC2ERNS_10PlumedMainE404395
_ZN4PLMD5AtomsD2Ev404395
_ZNK4PLMD5Atoms11getTimeStepEv3158863
_ZNK4PLMD5Atoms11writeBinaryERSo114
_ZNK4PLMD5Atoms13getKBoltzmannEv591
_ZNK4PLMD5Atoms15getMDKBoltzmannEv0
_ZNK4PLMD5Atoms16getRealPrecisionEv1688
_ZNK4PLMD5Atoms6getKbTEv1186
_ZNK4PLMD5Atoms9MD2doubleERKNS_11TypesafePtrERd12830
_ZNK4PLMD5Atoms9double2MDERKdRKNS_11TypesafePtrE2365
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Atoms.cpp.gcov.html b/coverage/core/Atoms.cpp.gcov.html new file mode 100644 index 0000000000..6b55da2925 --- /dev/null +++ b/coverage/core/Atoms.cpp.gcov.html @@ -0,0 +1,684 @@ + + + + + + + + LCOV - plumed test coverage - core/Atoms.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Atoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:37439395.2 %
Date:2024-06-10 08:19:14Functions:525594.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 "Atoms.h"
+      23             : #include "ActionAtomistic.h"
+      24             : #include "MDAtoms.h"
+      25             : #include "PlumedMain.h"
+      26             : #include "tools/Pbc.h"
+      27             : #include <algorithm>
+      28             : #include <iostream>
+      29             : #include <string>
+      30             : #include <cmath>
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : /// We assume that charges and masses are constant along the simulation
+      35             : /// Set this to false if you want to revert to the original (expensive) behavior
+      36             : static const bool shareMassAndChargeOnlyAtFirstStep=true;
+      37             : 
+      38             : class PlumedMain;
+      39             : 
+      40      404395 : Atoms::Atoms(PlumedMain&plumed):
+      41      404395 :   natoms(0),
+      42      404395 :   md_energy(0.0),
+      43      404395 :   energy(0.0),
+      44      404395 :   dataCanBeSet(false),
+      45      404395 :   collectEnergy(false),
+      46      404395 :   energyHasBeenSet(false),
+      47      404395 :   positionsHaveBeenSet(0),
+      48      404395 :   massesHaveBeenSet(false),
+      49      404395 :   chargesHaveBeenSet(false),
+      50      404395 :   boxHasBeenSet(false),
+      51      404395 :   forcesHaveBeenSet(0),
+      52      404395 :   virialHasBeenSet(false),
+      53      404395 :   massAndChargeOK(false),
+      54      404395 :   shuffledAtoms(0),
+      55      404395 :   mdatoms(MDAtomsBase::create(sizeof(double))),
+      56      404395 :   plumed(plumed),
+      57      404395 :   naturalUnits(false),
+      58      404395 :   MDnaturalUnits(false),
+      59      404395 :   timestep(0.0),
+      60      404395 :   forceOnEnergy(0.0),
+      61      404395 :   zeroallforces(false),
+      62      404395 :   kbT(0.0),
+      63      404395 :   asyncSent(false),
+      64      404395 :   atomsNeeded(false),
+      65      808790 :   ddStep(0)
+      66             : {
+      67      404395 : }
+      68             : 
+      69      404395 : Atoms::~Atoms() {
+      70      404395 :   if(actions.size()>0) {
+      71           0 :     std::cerr<<"WARNING: there is some inconsistency in action added to atoms, as some of them were not properly destroyed. This might indicate an internal bug!!\n";
+      72             :   }
+      73      808790 : }
+      74             : 
+      75      247830 : void Atoms::startStep() {
+      76      247830 :   collectEnergy=false; energyHasBeenSet=false; positionsHaveBeenSet=0;
+      77      247830 :   massesHaveBeenSet=false; chargesHaveBeenSet=false; boxHasBeenSet=false;
+      78      247830 :   forcesHaveBeenSet=0; virialHasBeenSet=false; dataCanBeSet=true;
+      79      247830 : }
+      80             : 
+      81       43333 : void Atoms::setBox(const TypesafePtr & p) {
+      82       43333 :   mdatoms->setBox(p);
+      83       43333 :   Tensor b; mdatoms->getBox(b); boxHasBeenSet=true;
+      84       43333 : }
+      85             : 
+      86       47474 : void Atoms::setPositions(const TypesafePtr & p) {
+      87       47474 :   plumed_massert( dataCanBeSet,"setPositions must be called after setStep in MD code interface");
+      88       47474 :   plumed_massert( p || gatindex.size()==0, "NULL position pointer with non-zero local atoms");
+      89       47474 :   mdatoms->setp(p); positionsHaveBeenSet=3;
+      90       47474 : }
+      91             : 
+      92       47478 : void Atoms::setMasses(const TypesafePtr & p) {
+      93       47481 :   plumed_massert( dataCanBeSet,"setMasses must be called after setStep in MD code interface");
+      94       47475 :   plumed_massert( p || gatindex.size()==0, "NULL mass pointer with non-zero local atoms");
+      95       47475 :   mdatoms->setm(p); massesHaveBeenSet=true;
+      96             : 
+      97       47475 : }
+      98             : 
+      99       37570 : void Atoms::setCharges(const TypesafePtr & p) {
+     100       37570 :   plumed_massert( dataCanBeSet, "setCharges must be called after setStep in MD code interface");
+     101       37570 :   plumed_massert( p || gatindex.size()==0, "NULL charges pointer with non-zero local atoms");
+     102       37570 :   mdatoms->setc(p); chargesHaveBeenSet=true;
+     103       37570 : }
+     104             : 
+     105       37675 : void Atoms::setVirial(const TypesafePtr & p) {
+     106       37675 :   plumed_massert( dataCanBeSet,"setVirial must be called after setStep in MD code interface");
+     107       37675 :   mdatoms->setVirial(p); virialHasBeenSet=true;
+     108       37673 : }
+     109             : 
+     110        9792 : void Atoms::setEnergy(const TypesafePtr & p) {
+     111        9792 :   plumed_massert( dataCanBeSet,"setEnergy must be called after setStep in MD code interface");
+     112        9792 :   MD2double(p,md_energy);
+     113        9792 :   md_energy*=MDUnits.getEnergy()/units.getEnergy();
+     114        9792 :   energyHasBeenSet=true;
+     115        9792 : }
+     116             : 
+     117       47474 : void Atoms::setForces(const TypesafePtr & p) {
+     118       47474 :   plumed_massert( dataCanBeSet,"setForces must be called after setStep in MD code interface");
+     119       47474 :   plumed_massert( p || gatindex.size()==0, "NULL force pointer with non-zero local atoms");
+     120       47474 :   forcesHaveBeenSet=3;
+     121       47474 :   mdatoms->setf(p);
+     122       47474 : }
+     123             : 
+     124           3 : void Atoms::setPositions(const TypesafePtr & p,int i) {
+     125           3 :   plumed_massert( dataCanBeSet,"setPositions must be called after setStep in MD code interface");
+     126           3 :   plumed_massert( p || gatindex.size()==0, "NULL positions pointer with non-zero local atoms");
+     127           3 :   mdatoms->setp(p,i); positionsHaveBeenSet++;
+     128           3 : }
+     129             : 
+     130           3 : void Atoms::setForces(const TypesafePtr & p,int i) {
+     131           3 :   plumed_massert( dataCanBeSet,"setForces must be called after setStep in MD code interface");
+     132           3 :   plumed_massert( p || gatindex.size()==0, "NULL force pointer with non-zero local atoms");
+     133           3 :   mdatoms->setf(p,i); forcesHaveBeenSet++;
+     134           3 : }
+     135             : 
+     136       46042 : void Atoms::share() {
+     137             : // At first step I scatter all the atoms so as to store their mass and charge
+     138             : // Notice that this works with the assumption that charges and masses are
+     139             : // not changing during the simulation!
+     140       46042 :   if(!massAndChargeOK && shareMassAndChargeOnlyAtFirstStep) {
+     141         784 :     shareAll();
+     142         784 :     return;
+     143             :   }
+     144             : 
+     145       45258 :   if(!(int(gatindex.size())==natoms && shuffledAtoms==0)) {
+     146       19665 :     for(unsigned i=0; i<actions.size(); i++) {
+     147       17639 :       if(actions[i]->isActive()) {
+     148       12107 :         if(!actions[i]->getUnique().empty()) {
+     149       10629 :           atomsNeeded=true;
+     150             :           // unique are the local atoms
+     151       10629 :           unique.insert(actions[i]->getUniqueLocal().begin(),actions[i]->getUniqueLocal().end());
+     152             :         }
+     153             :       }
+     154             :     }
+     155             :   } else {
+     156      220789 :     for(unsigned i=0; i<actions.size(); i++) {
+     157      177557 :       if(actions[i]->isActive()) {
+     158      133775 :         if(!actions[i]->getUnique().empty()) {
+     159      115117 :           atomsNeeded=true;
+     160             :         }
+     161             :       }
+     162             :     }
+     163             : 
+     164             :   }
+     165             : 
+     166       45258 :   share(unique);
+     167             : }
+     168             : 
+     169         898 : void Atoms::shareAll() {
+     170             :   unique.clear();
+     171             :   // keep in unique only those atoms that are local
+     172         898 :   if(dd && shuffledAtoms>0) {
+     173       17616 :     for(int i=0; i<natoms; i++) if(g2l[i]>=0) unique.insert(AtomNumber::index(i));
+     174             :   } else {
+     175      477612 :     for(int i=0; i<natoms; i++) unique.insert(AtomNumber::index(i));
+     176             :   }
+     177         898 :   atomsNeeded=true;
+     178         898 :   share(unique);
+     179         898 : }
+     180             : 
+     181       46156 : void Atoms::share(const std::set<AtomNumber>& unique) {
+     182       46156 :   plumed_assert( positionsHaveBeenSet==3 && massesHaveBeenSet );
+     183             : 
+     184       46156 :   virial.zero();
+     185       46156 :   if(zeroallforces || int(gatindex.size())==natoms) {
+     186     4633356 :     for(int i=0; i<natoms; i++) forces[i].zero();
+     187             :   } else {
+     188       31126 :     for(const auto & p : unique) forces[p.index()].zero();
+     189             :   }
+     190       61703 :   for(unsigned i=getNatoms(); i<positions.size(); i++) forces[i].zero(); // virtual atoms
+     191       46156 :   forceOnEnergy=0.0;
+     192       46156 :   mdatoms->getBox(box);
+     193             : 
+     194       46156 :   if(!atomsNeeded) return;
+     195       44914 :   atomsNeeded=false;
+     196             : 
+     197       44914 :   if(int(gatindex.size())==natoms && shuffledAtoms==0) {
+     198             : // faster version, which retrieves all atoms
+     199       42702 :     mdatoms->getPositions(0,natoms,positions);
+     200             :   } else {
+     201        2212 :     uniq_index.clear();
+     202        2212 :     uniq_index.reserve(unique.size());
+     203        2212 :     if(shuffledAtoms>0) {
+     204       33181 :       for(const auto & p : unique) uniq_index.push_back(g2l[p.index()]);
+     205             :     }
+     206        2212 :     mdatoms->getPositions(unique,uniq_index,positions);
+     207             :   }
+     208             : 
+     209             : 
+     210             : // how many double per atom should be scattered:
+     211             :   int ndata=3;
+     212       44914 :   if(!massAndChargeOK) {
+     213             :     ndata=5;
+     214         784 :     masses.assign(masses.size(),std::numeric_limits<double>::quiet_NaN());
+     215         784 :     charges.assign(charges.size(),std::numeric_limits<double>::quiet_NaN());
+     216         784 :     mdatoms->getCharges(gatindex,charges);
+     217         784 :     mdatoms->getMasses(gatindex,masses);
+     218             :   }
+     219             : 
+     220       44914 :   if(dd && shuffledAtoms>0) {
+     221        2142 :     if(dd.async) {
+     222        9510 :       for(unsigned i=0; i<dd.mpi_request_positions.size(); i++) dd.mpi_request_positions[i].wait();
+     223        9510 :       for(unsigned i=0; i<dd.mpi_request_index.size(); i++)     dd.mpi_request_index[i].wait();
+     224             :     }
+     225        2142 :     int count=0;
+     226       29699 :     for(const auto & p : unique) {
+     227       27557 :       dd.indexToBeSent[count]=p.index();
+     228       27557 :       dd.positionsToBeSent[ndata*count+0]=positions[p.index()][0];
+     229       27557 :       dd.positionsToBeSent[ndata*count+1]=positions[p.index()][1];
+     230       27557 :       dd.positionsToBeSent[ndata*count+2]=positions[p.index()][2];
+     231       27557 :       if(!massAndChargeOK) {
+     232        2477 :         dd.positionsToBeSent[ndata*count+3]=masses[p.index()];
+     233        2477 :         dd.positionsToBeSent[ndata*count+4]=charges[p.index()];
+     234             :       }
+     235       27557 :       count++;
+     236             :     }
+     237        2142 :     if(dd.async) {
+     238        2122 :       asyncSent=true;
+     239        2122 :       dd.mpi_request_positions.resize(dd.Get_size());
+     240        2122 :       dd.mpi_request_index.resize(dd.Get_size());
+     241        9710 :       for(int i=0; i<dd.Get_size(); i++) {
+     242        7588 :         dd.mpi_request_index[i]=dd.Isend(&dd.indexToBeSent[0],count,i,666);
+     243        7588 :         dd.mpi_request_positions[i]=dd.Isend(&dd.positionsToBeSent[0],ndata*count,i,667);
+     244             :       }
+     245             :     } else {
+     246          20 :       const int n=(dd.Get_size());
+     247          20 :       std::vector<int> counts(n);
+     248          20 :       std::vector<int> displ(n);
+     249          20 :       std::vector<int> counts5(n);
+     250          20 :       std::vector<int> displ5(n);
+     251          20 :       dd.Allgather(count,counts);
+     252          20 :       displ[0]=0;
+     253          80 :       for(int i=1; i<n; ++i) displ[i]=displ[i-1]+counts[i-1];
+     254         100 :       for(int i=0; i<n; ++i) counts5[i]=counts[i]*ndata;
+     255         100 :       for(int i=0; i<n; ++i) displ5[i]=displ[i]*ndata;
+     256          20 :       dd.Allgatherv(&dd.indexToBeSent[0],count,&dd.indexToBeReceived[0],&counts[0],&displ[0]);
+     257          20 :       dd.Allgatherv(&dd.positionsToBeSent[0],ndata*count,&dd.positionsToBeReceived[0],&counts5[0],&displ5[0]);
+     258          20 :       int tot=displ[n-1]+counts[n-1];
+     259        1620 :       for(int i=0; i<tot; i++) {
+     260        1600 :         positions[dd.indexToBeReceived[i]][0]=dd.positionsToBeReceived[ndata*i+0];
+     261        1600 :         positions[dd.indexToBeReceived[i]][1]=dd.positionsToBeReceived[ndata*i+1];
+     262        1600 :         positions[dd.indexToBeReceived[i]][2]=dd.positionsToBeReceived[ndata*i+2];
+     263        1600 :         if(!massAndChargeOK) {
+     264         432 :           masses[dd.indexToBeReceived[i]]      =dd.positionsToBeReceived[ndata*i+3];
+     265         432 :           charges[dd.indexToBeReceived[i]]     =dd.positionsToBeReceived[ndata*i+4];
+     266             :         }
+     267             :       }
+     268             :     }
+     269             :   }
+     270             : }
+     271             : 
+     272       46156 : void Atoms::wait() {
+     273       46156 :   dataCanBeSet=false; // Everything should be set by this stage
+     274             : // How many double per atom should be scattered
+     275             :   std::size_t ndata=3;
+     276       46156 :   if(!massAndChargeOK)ndata=5;
+     277             : 
+     278       46156 :   if(dd) {
+     279       21591 :     dd.Bcast(box,0);
+     280             :   }
+     281       46156 :   pbc.setBox(box);
+     282             : 
+     283       46156 :   if(collectEnergy) energy=md_energy;
+     284             : 
+     285       46156 :   if(dd && shuffledAtoms>0) {
+     286             : // receive toBeReceived
+     287        2142 :     if(asyncSent) {
+     288             :       Communicator::Status status;
+     289             :       std::size_t count=0;
+     290        9710 :       for(int i=0; i<dd.Get_size(); i++) {
+     291        7588 :         dd.Recv(&dd.indexToBeReceived[count],dd.indexToBeReceived.size()-count,i,666,status);
+     292        7588 :         int c=status.Get_count<int>();
+     293        7588 :         dd.Recv(&dd.positionsToBeReceived[ndata*count],dd.positionsToBeReceived.size()-ndata*count,i,667);
+     294        7588 :         count+=c;
+     295             :       }
+     296       65772 :       for(int i=0; i<count; i++) {
+     297       63650 :         positions[dd.indexToBeReceived[i]][0]=dd.positionsToBeReceived[ndata*i+0];
+     298       63650 :         positions[dd.indexToBeReceived[i]][1]=dd.positionsToBeReceived[ndata*i+1];
+     299       63650 :         positions[dd.indexToBeReceived[i]][2]=dd.positionsToBeReceived[ndata*i+2];
+     300       63650 :         if(!massAndChargeOK) {
+     301        5946 :           masses[dd.indexToBeReceived[i]]      =dd.positionsToBeReceived[ndata*i+3];
+     302        5946 :           charges[dd.indexToBeReceived[i]]     =dd.positionsToBeReceived[ndata*i+4];
+     303             :         }
+     304             :       }
+     305        2122 :       asyncSent=false;
+     306             :     }
+     307        2142 :     if(collectEnergy) dd.Sum(energy);
+     308             :   }
+     309             : // I take note that masses and charges have been set once for all
+     310             : // at the beginning of the simulation.
+     311       46156 :   if(shareMassAndChargeOnlyAtFirstStep) massAndChargeOK=true;
+     312       46156 : }
+     313             : 
+     314       46032 : void Atoms::updateForces() {
+     315       46032 :   plumed_assert( forcesHaveBeenSet==3 );
+     316       46032 :   if(forceOnEnergy*forceOnEnergy>epsilon) {
+     317          50 :     double alpha=1.0-forceOnEnergy;
+     318          50 :     mdatoms->rescaleForces(gatindex,alpha);
+     319          50 :     mdatoms->updateForces(gatindex,forces);
+     320             :   } else {
+     321       45982 :     if(int(gatindex.size())==natoms && shuffledAtoms==0) mdatoms->updateForces(gatindex,forces);
+     322        2098 :     else mdatoms->updateForces(unique,uniq_index,forces);
+     323             :   }
+     324       46032 :   if( !plumed.novirial && dd.Get_rank()==0 ) {
+     325       31465 :     plumed_assert( virialHasBeenSet );
+     326       31465 :     mdatoms->updateVirial(virial);
+     327             :   }
+     328       46032 : }
+     329             : 
+     330         893 : void Atoms::setNatoms(int n) {
+     331         893 :   natoms=n;
+     332         893 :   positions.resize(n);
+     333         893 :   forces.resize(n);
+     334         893 :   masses.resize(n);
+     335         893 :   charges.resize(n);
+     336         893 :   gatindex.resize(n);
+     337      485359 :   for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=i;
+     338         893 : }
+     339             : 
+     340             : 
+     341       10109 : void Atoms::add(ActionAtomistic*a) {
+     342       10109 :   actions.push_back(a);
+     343       10109 : }
+     344             : 
+     345       10109 : void Atoms::remove(ActionAtomistic*a) {
+     346       10109 :   auto f=find(actions.begin(),actions.end(),a);
+     347       10109 :   plumed_massert(f!=actions.end(),"cannot remove an action registered to atoms");
+     348       10109 :   actions.erase(f);
+     349       10109 : }
+     350             : 
+     351             : 
+     352         337 : void Atoms::DomainDecomposition::enable(Communicator& c) {
+     353         337 :   on=true;
+     354         337 :   Set_comm(c.Get_comm());
+     355         337 :   async=Get_size()<10;
+     356         337 :   if(std::getenv("PLUMED_ASYNC_SHARE")) {
+     357           4 :     std::string s(std::getenv("PLUMED_ASYNC_SHARE"));
+     358           4 :     if(s=="yes") async=true;
+     359           4 :     else if(s=="no") async=false;
+     360           0 :     else plumed_merror("PLUMED_ASYNC_SHARE variable is set to " + s + "; should be yes or no");
+     361             :   }
+     362         337 : }
+     363             : 
+     364        1477 : void Atoms::setAtomsNlocal(int n) {
+     365        1477 :   gatindex.resize(n);
+     366        1477 :   g2l.resize(natoms,-1);
+     367        1477 :   if(dd) {
+     368             : // Since these vectors are sent with MPI by using e.g.
+     369             : // &dd.positionsToBeSent[0]
+     370             : // we make sure they are non-zero-sized so as to
+     371             : // avoid errors when doing boundary check
+     372        1445 :     if(n==0) n++;
+     373        1445 :     dd.positionsToBeSent.resize(n*5,0.0);
+     374        1445 :     dd.positionsToBeReceived.resize(natoms*5,0.0);
+     375        1445 :     dd.indexToBeSent.resize(n,0);
+     376        1445 :     dd.indexToBeReceived.resize(natoms,0);
+     377             :   }
+     378        1477 : }
+     379             : 
+     380         988 : void Atoms::setAtomsGatindex(const TypesafePtr & g,bool fortran) {
+     381         988 :   plumed_massert( g || gatindex.size()==0, "NULL gatindex pointer with non-zero local atoms");
+     382             :   auto gg=g.get<const int*>(gatindex.size());
+     383         988 :   ddStep=plumed.getStep();
+     384         988 :   if(fortran) {
+     385           0 :     for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=gg[i]-1;
+     386             :   } else {
+     387       22140 :     for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=gg[i];
+     388             :   }
+     389       57530 :   for(unsigned i=0; i<g2l.size(); i++) g2l[i]=-1;
+     390         988 :   if( gatindex.size()==natoms ) {
+     391           9 :     shuffledAtoms=0;
+     392        1005 :     for(unsigned i=0; i<gatindex.size(); i++) {
+     393         996 :       if( gatindex[i]!=i ) { shuffledAtoms=1; break; }
+     394             :     }
+     395             :   } else {
+     396         979 :     shuffledAtoms=1;
+     397             :   }
+     398         988 :   if(dd) {
+     399         956 :     dd.Sum(shuffledAtoms);
+     400             :   }
+     401       22140 :   for(unsigned i=0; i<gatindex.size(); i++) g2l[gatindex[i]]=i;
+     402             : 
+     403       10390 :   for(unsigned i=0; i<actions.size(); i++) {
+     404             :     // keep in unique only those atoms that are local
+     405        9402 :     actions[i]->updateUniqueLocal();
+     406             :   }
+     407             :   unique.clear();
+     408         988 : }
+     409             : 
+     410         489 : void Atoms::setAtomsContiguous(int start) {
+     411         489 :   ddStep=plumed.getStep();
+     412      184532 :   for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=start+i;
+     413      196844 :   for(unsigned i=0; i<g2l.size(); i++) g2l[i]=-1;
+     414      184532 :   for(unsigned i=0; i<gatindex.size(); i++) g2l[gatindex[i]]=i;
+     415         489 :   if(gatindex.size()<natoms) shuffledAtoms=1;
+     416         737 :   for(unsigned i=0; i<actions.size(); i++) {
+     417             :     // keep in unique only those atoms that are local
+     418         248 :     actions[i]->updateUniqueLocal();
+     419             :   }
+     420             :   unique.clear();
+     421         489 : }
+     422             : 
+     423         780 : void Atoms::setRealPrecision(int p) {
+     424        1560 :   mdatoms=MDAtomsBase::create(p);
+     425         780 : }
+     426             : 
+     427        1688 : int Atoms::getRealPrecision()const {
+     428        1688 :   return mdatoms->getRealPrecision();
+     429             : }
+     430             : 
+     431       12830 : void Atoms::MD2double(const TypesafePtr & m,double&d)const {
+     432       12830 :   plumed_assert(mdatoms); mdatoms->MD2double(m,d);
+     433       12830 : }
+     434        2365 : void Atoms::double2MD(const double&d,const TypesafePtr & m)const {
+     435        2365 :   plumed_assert(mdatoms); mdatoms->double2MD(d,m);
+     436        2365 : }
+     437             : 
+     438         933 : void Atoms::updateUnits() {
+     439         933 :   mdatoms->setUnits(units,MDUnits);
+     440         933 : }
+     441             : 
+     442         774 : void Atoms::setTimeStep(const TypesafePtr & p) {
+     443         774 :   MD2double(p,timestep);
+     444             : // The following is to avoid extra digits in case the MD code uses floats
+     445             : // e.g.: float f=0.002 when converted to double becomes 0.002000000094995
+     446             : // To avoid this, we keep only up to 6 significant digits after first one
+     447         774 :   if(getRealPrecision()<=4) {
+     448           0 :     double magnitude=std::pow(10,std::floor(std::log10(timestep)));
+     449           0 :     timestep=std::round(timestep/magnitude*1e6)/1e6*magnitude;
+     450             :   }
+     451         774 : }
+     452             : 
+     453     3158863 : double Atoms::getTimeStep()const {
+     454     3158863 :   return timestep/units.getTime()*MDUnits.getTime();
+     455             : }
+     456             : 
+     457          59 : void Atoms::setKbT(const TypesafePtr & p) {
+     458          59 :   MD2double(p,kbT);
+     459          59 : }
+     460             : 
+     461        1186 : double Atoms::getKbT()const {
+     462        1186 :   return kbT/units.getEnergy()*MDUnits.getEnergy();
+     463             : }
+     464             : 
+     465             : 
+     466         116 : void Atoms::createFullList(const TypesafePtr & n) {
+     467         116 :   if(!massAndChargeOK && shareMassAndChargeOnlyAtFirstStep) {
+     468           7 :     n.set(int(natoms));
+     469           7 :     fullList.resize(natoms);
+     470         803 :     for(unsigned i=0; i<natoms; i++) fullList[i]=i;
+     471             :   } else {
+     472             : // We update here the unique list defined at Atoms::unique.
+     473             : // This is not very clear, and probably should be coded differently.
+     474             : // Hopefully this fix the longstanding issue with NAMD.
+     475             :     unique.clear();
+     476         892 :     for(unsigned i=0; i<actions.size(); i++) {
+     477         783 :       if(actions[i]->isActive()) {
+     478         625 :         if(!actions[i]->getUnique().empty()) {
+     479         546 :           atomsNeeded=true;
+     480             :           // unique are the local atoms
+     481         546 :           unique.insert(actions[i]->getUnique().begin(),actions[i]->getUnique().end());
+     482             :         }
+     483             :       }
+     484             :     }
+     485         109 :     fullList.resize(0);
+     486         109 :     fullList.reserve(unique.size());
+     487        5012 :     for(const auto & p : unique) fullList.push_back(p.index());
+     488         109 :     n.set(int(fullList.size()));
+     489             :   }
+     490         116 : }
+     491             : 
+     492         116 : void Atoms::getFullList(const TypesafePtr & x) {
+     493             :   auto xx=x.template get<const int**>();
+     494         116 :   if(!fullList.empty()) *xx=&fullList[0];
+     495           6 :   else *xx=NULL;
+     496         116 : }
+     497             : 
+     498         116 : void Atoms::clearFullList() {
+     499         116 :   fullList.resize(0);
+     500         116 : }
+     501             : 
+     502         914 : void Atoms::init() {
+     503             : // Default: set domain decomposition to NO-decomposition, waiting for
+     504             : // further instruction
+     505         914 :   if(dd) {
+     506         337 :     setAtomsNlocal(natoms);
+     507         337 :     setAtomsContiguous(0);
+     508             :   }
+     509         914 : }
+     510             : 
+     511         337 : void Atoms::setDomainDecomposition(Communicator& comm) {
+     512         337 :   dd.enable(comm);
+     513         337 : }
+     514             : 
+     515       14352 : void Atoms::resizeVectors(unsigned n) {
+     516       14352 :   positions.resize(n);
+     517       14352 :   forces.resize(n);
+     518       14352 :   masses.resize(n);
+     519       14352 :   charges.resize(n);
+     520       14352 : }
+     521             : 
+     522        7176 : AtomNumber Atoms::addVirtualAtom(ActionWithVirtualAtom*a) {
+     523        7176 :   unsigned n=positions.size();
+     524        7176 :   resizeVectors(n+1);
+     525        7176 :   virtualAtomsActions.push_back(a);
+     526        7176 :   return AtomNumber::index(n);
+     527             : }
+     528             : 
+     529        7176 : void Atoms::removeVirtualAtom(ActionWithVirtualAtom*a) {
+     530        7176 :   unsigned n=positions.size();
+     531        7176 :   plumed_massert(a==virtualAtomsActions[virtualAtomsActions.size()-1],"virtual atoms should be destroyed in reverse creation order");
+     532        7176 :   resizeVectors(n-1);
+     533             :   virtualAtomsActions.pop_back();
+     534        7176 : }
+     535             : 
+     536         119 : void Atoms::insertGroup(const std::string&name,const std::vector<AtomNumber>&a) {
+     537           0 :   plumed_massert(groups.count(name)==0,"group named "+name+" already exists");
+     538         119 :   groups[name]=a;
+     539         119 : }
+     540             : 
+     541         119 : void Atoms::removeGroup(const std::string&name) {
+     542           0 :   plumed_massert(groups.count(name)==1,"cannot remove group named "+name);
+     543             :   groups.erase(name);
+     544         119 : }
+     545             : 
+     546         114 : void Atoms::writeBinary(std::ostream&o)const {
+     547         114 :   o.write(reinterpret_cast<const char*>(&positions[0][0]),natoms*3*sizeof(double));
+     548         114 :   o.write(reinterpret_cast<const char*>(&box(0,0)),9*sizeof(double));
+     549         114 :   o.write(reinterpret_cast<const char*>(&energy),sizeof(double));
+     550         114 : }
+     551             : 
+     552         114 : void Atoms::readBinary(std::istream&i) {
+     553         114 :   i.read(reinterpret_cast<char*>(&positions[0][0]),natoms*3*sizeof(double));
+     554         114 :   i.read(reinterpret_cast<char*>(&box(0,0)),9*sizeof(double));
+     555         114 :   i.read(reinterpret_cast<char*>(&energy),sizeof(double));
+     556         114 :   pbc.setBox(box);
+     557         114 : }
+     558             : 
+     559         591 : double Atoms::getKBoltzmann()const {
+     560         591 :   if(naturalUnits || MDnaturalUnits) return 1.0;
+     561         585 :   else return kBoltzmann/units.getEnergy();
+     562             : }
+     563             : 
+     564           0 : double Atoms::getMDKBoltzmann()const {
+     565           0 :   if(naturalUnits || MDnaturalUnits) return 1.0;
+     566           0 :   else return kBoltzmann/MDUnits.getEnergy();
+     567             : }
+     568             : 
+     569           0 : void Atoms::getLocalMasses(std::vector<double>& localMasses) {
+     570           0 :   localMasses.resize(gatindex.size());
+     571           0 :   for(unsigned i=0; i<gatindex.size(); i++) localMasses[i] = masses[gatindex[i]];
+     572           0 : }
+     573             : 
+     574         450 : void Atoms::getLocalPositions(std::vector<Vector>& localPositions) {
+     575         450 :   localPositions.resize(gatindex.size());
+     576         450 :   mdatoms->getLocalPositions(localPositions);
+     577         450 : }
+     578             : 
+     579         450 : void Atoms::getLocalForces(std::vector<Vector>& localForces) {
+     580         450 :   localForces.resize(gatindex.size());
+     581       16650 :   for(unsigned i=0; i<gatindex.size(); i++) localForces[i] = forces[gatindex[i]];
+     582         450 : }
+     583             : 
+     584           0 : void Atoms::getLocalMDForces(std::vector<Vector>& localForces) {
+     585           0 :   localForces.resize(gatindex.size());
+     586           0 :   for(unsigned i=0; i<gatindex.size(); i++) {
+     587           0 :     localForces[i] = mdatoms->getMDforces(i);
+     588             :   }
+     589           0 : }
+     590             : 
+     591          20 : void Atoms::setExtraCV(const std::string &name,const TypesafePtr & p) {
+     592          20 :   mdatoms->setExtraCV(name,p);
+     593          20 : }
+     594             : 
+     595          20 : void Atoms::setExtraCVForce(const std::string &name,const TypesafePtr & p) {
+     596          20 :   mdatoms->setExtraCVForce(name,p);
+     597          20 : }
+     598             : 
+     599          60 : double Atoms::getExtraCV(const std::string &name) {
+     600          60 :   return mdatoms->getExtraCV(name);
+     601             : }
+     602             : 
+     603          40 : void Atoms::updateExtraCVForce(const std::string &name,double f) {
+     604          40 :   mdatoms->updateExtraCVForce(name,f);
+     605          40 : }
+     606             : 
+     607             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Atoms.h.func-sort-c.html b/coverage/core/Atoms.h.func-sort-c.html new file mode 100644 index 0000000000..2e3255202f --- /dev/null +++ b/coverage/core/Atoms.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/Atoms.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Atoms.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD5Atoms9getEnergyEv3989
_ZN4PLMD5Atoms19DomainDecompositionC2Ev404395
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Atoms.h.func.html b/coverage/core/Atoms.h.func.html new file mode 100644 index 0000000000..ffb81c8d2f --- /dev/null +++ b/coverage/core/Atoms.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/Atoms.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Atoms.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Atoms19DomainDecompositionC2Ev404395
_ZNK4PLMD5Atoms9getEnergyEv3989
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Atoms.h.gcov.html b/coverage/core/Atoms.h.gcov.html new file mode 100644 index 0000000000..78c1f0f01c --- /dev/null +++ b/coverage/core/Atoms.h.gcov.html @@ -0,0 +1,377 @@ + + + + + + + + LCOV - plumed test coverage - core/Atoms.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Atoms.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-06-10 08:19:14Functions: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_core_Atoms_h
+      23             : #define __PLUMED_core_Atoms_h
+      24             : 
+      25             : #include "tools/TypesafePtr.h"
+      26             : #include "tools/Communicator.h"
+      27             : #include "tools/Tensor.h"
+      28             : #include "tools/Units.h"
+      29             : #include "tools/Exception.h"
+      30             : #include "tools/AtomNumber.h"
+      31             : #include "tools/ForwardDecl.h"
+      32             : #include <vector>
+      33             : #include <set>
+      34             : #include <map>
+      35             : #include <string>
+      36             : #include <memory>
+      37             : 
+      38             : namespace PLMD {
+      39             : 
+      40             : class MDAtomsBase;
+      41             : class PlumedMain;
+      42             : class ActionAtomistic;
+      43             : class ActionWithVirtualAtom;
+      44             : class Pbc;
+      45             : 
+      46             : /// Class containing atom related quantities from the MD code.
+      47             : /// IT IS STILL UNDOCUMENTED. IT PROBABLY NEEDS A STRONG CLEANUP
+      48             : class Atoms
+      49             : {
+      50             :   friend class ActionAtomistic;
+      51             :   friend class ActionWithVirtualAtom;
+      52             :   int natoms;
+      53             :   std::set<AtomNumber> unique;
+      54             :   std::vector<unsigned> uniq_index;
+      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             :   std::vector<Vector> positions;
+      62             :   std::vector<Vector> forces;
+      63             :   std::vector<double> masses;
+      64             :   std::vector<double> charges;
+      65             :   std::vector<ActionWithVirtualAtom*> virtualAtomsActions;
+      66             :   Tensor box;
+      67             :   ForwardDecl<Pbc> pbc_fwd;
+      68             :   Pbc&   pbc=*pbc_fwd;
+      69             :   Tensor virial;
+      70             : // this is the energy set by each processor:
+      71             :   double md_energy;
+      72             : // this is the summed energy:
+      73             :   double energy;
+      74             : 
+      75             :   bool   dataCanBeSet;
+      76             :   bool   collectEnergy;
+      77             :   bool   energyHasBeenSet;
+      78             :   unsigned positionsHaveBeenSet;
+      79             :   bool massesHaveBeenSet;
+      80             :   bool chargesHaveBeenSet;
+      81             :   bool boxHasBeenSet;
+      82             :   unsigned forcesHaveBeenSet;
+      83             :   bool virialHasBeenSet;
+      84             :   bool massAndChargeOK;
+      85             :   unsigned shuffledAtoms;
+      86             : 
+      87             :   std::map<std::string,std::vector<AtomNumber> > groups;
+      88             : 
+      89             :   void resizeVectors(unsigned);
+      90             : 
+      91             :   std::vector<int> fullList;
+      92             : 
+      93             :   std::unique_ptr<MDAtomsBase> mdatoms;
+      94             : 
+      95             :   PlumedMain & plumed;
+      96             : 
+      97             :   Units MDUnits;
+      98             :   Units units;
+      99             : 
+     100             :   bool naturalUnits;
+     101             :   bool MDnaturalUnits;
+     102             : 
+     103             :   double timestep;
+     104             :   double forceOnEnergy;
+     105             : 
+     106             : /// if set to true, all the forces in the global array are zeroes
+     107             : /// at every step. It should not be necessary in general, but it is
+     108             : /// for actions accessing to modifyGlobalForce() (e.g. FIT_TO_TEMPLATE).
+     109             :   bool zeroallforces;
+     110             : 
+     111             :   double kbT;
+     112             : 
+     113             :   std::vector<ActionAtomistic*> actions;
+     114             :   std::vector<int>    gatindex;
+     115             : 
+     116             :   bool asyncSent;
+     117             :   bool atomsNeeded;
+     118             : 
+     119             :   class DomainDecomposition:
+     120             :     public Communicator
+     121             :   {
+     122             :   public:
+     123             :     bool on;
+     124             :     bool async;
+     125             : 
+     126             :     std::vector<Communicator::Request> mpi_request_positions;
+     127             :     std::vector<Communicator::Request> mpi_request_index;
+     128             : 
+     129             :     std::vector<double> positionsToBeSent;
+     130             :     std::vector<double> positionsToBeReceived;
+     131             :     std::vector<int>    indexToBeSent;
+     132             :     std::vector<int>    indexToBeReceived;
+     133      161297 :     operator bool() const {return on;}
+     134      404395 :     DomainDecomposition():
+     135      404395 :       on(false), async(false)
+     136      404395 :     {}
+     137             :     void enable(Communicator& c);
+     138             :   };
+     139             : 
+     140             :   DomainDecomposition dd;
+     141             :   long int ddStep;  //last step in which dd happened
+     142             : 
+     143             :   void share(const std::set<AtomNumber>&);
+     144             : 
+     145             : public:
+     146             : 
+     147             :   explicit Atoms(PlumedMain&plumed);
+     148             :   ~Atoms();
+     149             : 
+     150             :   void init();
+     151             : 
+     152             :   void share();
+     153             :   void shareAll();
+     154             :   void wait();
+     155             :   void updateForces();
+     156             : 
+     157             :   void setRealPrecision(int);
+     158             :   int  getRealPrecision()const;
+     159             : 
+     160             :   void setTimeStep(const TypesafePtr &);
+     161             :   double getTimeStep()const;
+     162             : 
+     163             :   void setKbT(const TypesafePtr &);
+     164             :   double getKbT()const;
+     165             : 
+     166             :   void setNatoms(int);
+     167             :   int getNatoms()const;
+     168             :   int getNVirtualAtoms()const;
+     169             : 
+     170             :   const long int& getDdStep()const;
+     171             :   const std::vector<int>& getGatindex()const;
+     172             :   const Pbc& getPbc()const;
+     173             :   void getLocalMasses(std::vector<double>&);
+     174             :   void getLocalPositions(std::vector<Vector>&);
+     175             :   void getLocalForces(std::vector<Vector>&);
+     176             :   void getLocalMDForces(std::vector<Vector>&);
+     177             :   const Tensor& getVirial()const;
+     178             : 
+     179        3989 :   void setCollectEnergy(bool b) { collectEnergy=b; }
+     180             : 
+     181             :   void setDomainDecomposition(Communicator&);
+     182             :   void setAtomsGatindex(const TypesafePtr &,bool);
+     183             :   void setAtomsContiguous(int);
+     184             :   void setAtomsNlocal(int);
+     185             : 
+     186             :   void startStep();
+     187             :   void setEnergy(const TypesafePtr &);
+     188             :   void setBox(const TypesafePtr &);
+     189             :   void setVirial(const TypesafePtr &);
+     190             :   void setPositions(const TypesafePtr &);
+     191             :   void setPositions(const TypesafePtr &,int);
+     192             :   void setForces(const TypesafePtr &);
+     193             :   void setForces(const TypesafePtr &,int);
+     194             :   void setMasses(const TypesafePtr &);
+     195             :   void setCharges(const TypesafePtr &);
+     196             :   bool chargesWereSet() const ;
+     197             :   bool boxWasSet() const ;
+     198             : 
+     199             :   void MD2double(const TypesafePtr & m,double&d)const;
+     200             :   void double2MD(const double&d,const TypesafePtr & m)const;
+     201             : 
+     202             :   void createFullList(const TypesafePtr &);
+     203             :   void getFullList(const TypesafePtr &);
+     204             :   void clearFullList();
+     205             : 
+     206             :   void add(ActionAtomistic*);
+     207             :   void remove(ActionAtomistic*);
+     208             : 
+     209        3989 :   double getEnergy()const {plumed_assert(collectEnergy && energyHasBeenSet); return energy;}
+     210             : 
+     211          96 :   bool isEnergyNeeded()const {return collectEnergy;}
+     212             : 
+     213          45 :   void setMDEnergyUnits(double d) {MDUnits.setEnergy(d);}
+     214         718 :   void setMDLengthUnits(double d) {MDUnits.setLength(d);}
+     215           6 :   void setMDTimeUnits(double d) {MDUnits.setTime(d);}
+     216         718 :   void setMDChargeUnits(double d) {MDUnits.setCharge(d);}
+     217         718 :   void setMDMassUnits(double d) {MDUnits.setMass(d);}
+     218             :   const Units& getMDUnits() {return MDUnits;}
+     219          19 :   void setUnits(const Units&u) {units=u;}
+     220             :   const Units& getUnits() {return units;}
+     221             :   void updateUnits();
+     222             : 
+     223             :   AtomNumber addVirtualAtom(ActionWithVirtualAtom*);
+     224             :   void removeVirtualAtom(ActionWithVirtualAtom*);
+     225             :   ActionWithVirtualAtom* getVirtualAtomsAction(AtomNumber)const;
+     226             :   bool isVirtualAtom(AtomNumber)const;
+     227             :   void insertGroup(const std::string&name,const std::vector<AtomNumber>&a);
+     228             :   void removeGroup(const std::string&name);
+     229             :   void writeBinary(std::ostream&)const;
+     230             :   void readBinary(std::istream&);
+     231             :   double getKBoltzmann()const;
+     232             :   double getMDKBoltzmann()const;
+     233             :   bool usingNaturalUnits()const;
+     234          19 :   void setNaturalUnits(bool n) {naturalUnits=n;}
+     235           0 :   void setMDNaturalUnits(bool n) {MDnaturalUnits=n;}
+     236             : 
+     237             :   void setExtraCV(const std::string &name,const TypesafePtr & p);
+     238             :   void setExtraCVForce(const std::string &name,const TypesafePtr & p);
+     239             :   double getExtraCV(const std::string &name);
+     240             :   void updateExtraCVForce(const std::string &name,double f);
+     241             : };
+     242             : 
+     243             : inline
+     244             : int Atoms::getNatoms()const {
+     245      795366 :   return natoms;
+     246             : }
+     247             : 
+     248             : inline
+     249             : int Atoms::getNVirtualAtoms()const {
+     250          10 :   return virtualAtomsActions.size();
+     251             : }
+     252             : 
+     253             : inline
+     254             : const long int& Atoms::getDdStep()const {
+     255             :   return ddStep;
+     256             : }
+     257             : 
+     258             : inline
+     259             : const std::vector<int>& Atoms::getGatindex()const {
+     260           9 :   return gatindex;
+     261             : }
+     262             : 
+     263             : inline
+     264             : const Pbc& Atoms::getPbc()const {
+     265         900 :   return pbc;
+     266             : }
+     267             : 
+     268             : inline
+     269             : bool Atoms::isVirtualAtom(AtomNumber i)const {
+     270     1178139 :   return i.index()>=(unsigned) getNatoms();
+     271             : }
+     272             : 
+     273             : inline
+     274             : ActionWithVirtualAtom* Atoms::getVirtualAtomsAction(AtomNumber i)const {
+     275        7230 :   return virtualAtomsActions[i.index()-getNatoms()];
+     276             : }
+     277             : 
+     278             : inline
+     279             : bool Atoms::usingNaturalUnits() const {
+     280        2440 :   return naturalUnits || MDnaturalUnits;
+     281             : }
+     282             : 
+     283             : inline
+     284             : bool Atoms::chargesWereSet() const {
+     285      168223 :   return chargesHaveBeenSet;
+     286             : }
+     287             : 
+     288             : inline
+     289             : bool Atoms::boxWasSet() const {
+     290             :   return boxHasBeenSet;
+     291             : }
+     292             : 
+     293             : inline
+     294             : const Tensor& Atoms::getVirial()const {
+     295         450 :   return virial;
+     296             : }
+     297             : 
+     298             : 
+     299             : }
+     300             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..78ec60145a --- /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:8510085.0 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE2233
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE2285
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_2285
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2345
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE2345
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE2345
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb14795
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE45149
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/CLTool.cpp.func.html b/coverage/core/CLTool.cpp.func.html new file mode 100644 index 0000000000..8bc5d1e278 --- /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:8510085.0 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2345
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE2345
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE45149
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE2233
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE2285
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb14795
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_2285
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE2345
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/CLTool.cpp.gcov.html b/coverage/core/CLTool.cpp.gcov.html new file mode 100644 index 0000000000..6218355c5f --- /dev/null +++ b/coverage/core/CLTool.cpp.gcov.html @@ -0,0 +1,290 @@ + + + + + + + + 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:8510085.0 %
Date:2024-06-10 08:19:14Functions: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        2345 : CLToolOptions::CLToolOptions(const std::string &name):
+      29        2345 :   line(1,name),
+      30        2345 :   keys(emptyKeys)
+      31             : {
+      32        2345 : }
+      33             : 
+      34        2345 : CLToolOptions::CLToolOptions(const CLToolOptions& co, const Keywords& k):
+      35        2345 :   line(co.line),
+      36        2345 :   keys(k)
+      37             : {
+      38        2345 : }
+      39             : 
+      40       45149 : void CLTool::registerKeywords( Keywords& keys ) {
+      41       90298 :   keys.addFlag("--help/-h",false,"print this help");
+      42       45149 : }
+      43             : 
+      44        2345 : CLTool::CLTool(const CLToolOptions& co ):
+      45        2345 :   name(co.line[0]),
+      46        2345 :   keywords(co.keys),
+      47        2345 :   inputdata(unset)
+      48             : {
+      49        2345 : }
+      50             : 
+      51       14795 : void CLTool::parseFlag( const std::string&key, bool&t ) {
+      52       14795 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+      53       29590 :   plumed_massert(keywords.style(key,"flag"),"keyword " + key + " has not been registered as a flag");
+      54           0 :   plumed_assert(inputData.count(key)>0);
+      55       29590 :   if( inputData[key]=="true") t=true;
+      56       26438 :   else if( inputData[key]=="false") t=false;
+      57           0 :   else plumed_error();
+      58       14795 : }
+      59             : 
+      60        2285 : bool CLTool::readInput( int argc, char**argv, FILE* in, FILE*out ) {
+      61        2285 :   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        2285 :   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        2233 : bool CLTool::readCommandLineArgs( int argc, char**argv, FILE*out ) {
+      71        2233 :   plumed_assert(inputdata==commandline);
+      72        2233 :   std::string prefix(""), a(""), thiskey;
+      73             : 
+      74             :   // Set all flags to default false
+      75       44957 :   for(unsigned k=0; k<keywords.size(); ++k) {
+      76       42724 :     thiskey=keywords.get(k);
+      77      102766 :     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       10523 :   for(int i=1; i<argc; i++) {
+      83       16580 :     a=prefix+argv[i];
+      84        8290 :     if(a.length()==0) continue;
+      85       16580 :     if(a=="-h" || a=="--help") {
+      86             :       printhelp=true;
+      87             :     } else {
+      88             :       bool found=false;
+      89      274673 :       for(unsigned k=0; k<keywords.size(); ++k) {
+      90      266383 :         thiskey=keywords.get(k);
+      91      532766 :         if( keywords.style(thiskey,"flag") ) {
+      92       51589 :           if( a==thiskey ) { found=true; inputData[thiskey]="true"; }
+      93             :         } else {
+      94      214794 :           if( a==thiskey ) {
+      95        3100 :             prefix=thiskey+"="; found=true;
+      96        6200 :             inputData.insert(std::pair<std::string,std::string>(thiskey,""));
+      97      423388 :           } else if(Tools::startWith(a,thiskey+"=")) {
+      98        3616 :             a.erase(0,a.find("=")+1); prefix=""; found=true;
+      99             :             if(inputData.count(thiskey)==0) {
+     100        1034 :               inputData.insert(std::pair<std::string,std::string>(thiskey,a));
+     101             :             } else {
+     102        3099 :               inputData[thiskey]=a;
+     103             :             }
+     104             :           }
+     105             :         }
+     106             :       }
+     107        8290 :       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        8290 :     if(printhelp) break;
+     116             :   }
+     117             : 
+     118        2233 :   if(!printhelp) setRemainingToDefault(out);
+     119             : 
+     120        2233 :   if(printhelp) {
+     121             :     std::fprintf(out,"Usage: %s [options] \n\n", name.c_str() );
+     122           0 :     keywords.print( out );
+     123             :   }
+     124             : 
+     125        2233 :   return !printhelp;
+     126             : }
+     127             : 
+     128        2285 : void CLTool::setRemainingToDefault(FILE* out) {
+     129             :   std::string def, thiskey;
+     130       46008 :   for(unsigned k=0; k<keywords.size(); ++k) {
+     131       43723 :     thiskey=keywords.get(k);
+     132       87446 :     if( keywords.style(thiskey,"compulsory") ) {
+     133             :       if( inputData.count(thiskey)==0 ) {
+     134        2728 :         if( keywords.getDefaultValue(thiskey,def) ) {
+     135        1364 :           plumed_assert( def.length()>0 );
+     136        2728 :           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        2285 : }
+     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          52 :   if(argc==2) {
+     164          43 :     mystdin=fopen(argv[1],"r");
+     165          43 :     if(!mystdin) {
+     166           0 :       std::fprintf(stderr,"ERROR: cannot open file %s\n\n",argv[1]);
+     167             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     168             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     169           0 :       keywords.print( out );
+     170             :       return false;
+     171             :     }
+     172             :   }
+     173             : 
+     174          52 :   plumed_assert(mystdin);
+     175             : 
+     176             :   char buffer[256]; std::string line; line.resize(256);
+     177         864 :   while(fgets(buffer,256,mystdin)) {
+     178             :     line=buffer;
+     179       24516 :     for(unsigned i=0; i<line.length(); ++i) if(line[i]=='#' || line[i]=='\n') line.erase(i);
+     180         812 :     Tools::stripLeadingAndTrailingBlanks( line );
+     181         812 :     if(line.length()==0) continue;
+     182         775 :     std::sscanf(line.c_str(),"%255s",buffer);
+     183         775 :     std::string keyword=buffer; bool found=false;
+     184       16142 :     for(unsigned i=0; i<keywords.size(); ++i) {
+     185       15367 :       std::string thiskey=keywords.get(i);
+     186       15367 :       if(thiskey==keyword) {
+     187             :         found=true;
+     188         775 :         std::size_t keypos=line.find_first_of(keyword)+keyword.length();
+     189        1550 :         inputData.insert(std::pair<std::string,std::string>(thiskey,line.substr(keypos)));
+     190         775 :         Tools::stripLeadingAndTrailingBlanks( inputData[thiskey] );
+     191             :       }
+     192             :     }
+     193         775 :     if(!found) {
+     194           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());
+     195             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     196             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     197           0 :       keywords.print( out );
+     198           0 :       fclose(mystdin);
+     199             :       return false;
+     200             :     }
+     201             :   }
+     202             : 
+     203          52 :   if(argc==2) fclose(mystdin);
+     204          52 :   setRemainingToDefault(out);
+     205             :   return true;
+     206             : }
+     207             : 
+     208           0 : [[noreturn]] void CLTool::error( const std::string& msg ) {
+     209           0 :   std::fprintf(stderr,"ERROR : in input for command line tool %s : %s\n",name.c_str(),msg.c_str());
+     210           0 :   plumed_error();
+     211             : }
+     212             : 
+     213             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..39f759e4f7 --- /dev/null +++ b/coverage/core/CLTool.h.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + 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-06-10 08:19:14Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD6CLTool5parseImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_80
_ZN4PLMD6CLTool11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RSt6vectorIT_SaISB_EE158
_ZN4PLMD6CLTool11parseVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE166
_ZN4PLMD6CLTool5parseIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_712
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_800
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1415
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1496
_ZN4PLMD6CLToolD2Ev2345
_ZN4PLMD6CLTool5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RT_19191
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/CLTool.h.func.html b/coverage/core/CLTool.h.func.html new file mode 100644 index 0000000000..567cb805c0 --- /dev/null +++ b/coverage/core/CLTool.h.func.html @@ -0,0 +1,129 @@ + + + + + + + + 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-06-10 08:19:14Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_19191
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1496
_ZN4PLMD6CLTool5parseIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1415
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_800
_ZN4PLMD6CLTool5parseIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_712
_ZN4PLMD6CLTool5parseImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_80
_ZN4PLMD6CLToolD0Ev0
_ZN4PLMD6CLToolD2Ev2345
_ZNK4PLMD6CLTool11descriptionB5cxx11Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/CLTool.h.gcov.html b/coverage/core/CLTool.h.gcov.html new file mode 100644 index 0000000000..3c9cf9fe9a --- /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-06-10 08:19:14Functions:111478.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             : #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        4690 : 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        2345 :   virtual ~CLTool() {}
+     100             : };
+     101             : 
+     102             : template<class T>
+     103       23694 : bool CLTool::parse(const std::string&key,T&t) {
+     104       23694 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     105       47388 :   if(keywords.style(key,"compulsory") ) {
+     106           0 :     if(inputData.count(key)==0) error("missing data for keyword " + key);
+     107        3709 :     bool check=Tools::convertNoexcept(inputData[key],t);
+     108        3709 :     if(!check) error("data input for keyword " + key + " has wrong type");
+     109             :     return true;
+     110             :   }
+     111       18243 :   if( inputData.count(key)==0 ) return false;
+     112        1742 :   Tools::convert(inputData[key],t);
+     113        1742 :   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.15
+
+ + + 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 0000000000..6ced93a708 --- /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-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE3445
_ZN4PLMD10CLToolMainC2Ev3445
_ZN4PLMD10CLToolMainD0Ev3445
_ZN4PLMD10CLToolMainD2Ev3445
_ZN4PLMD10CLToolMain3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE10668
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.func.html b/coverage/core/CLToolMain.cpp.func.html new file mode 100644 index 0000000000..543636a720 --- /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-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE10668
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE3445
_ZN4PLMD10CLToolMainC2Ev3445
_ZN4PLMD10CLToolMainD0Ev3445
_ZN4PLMD10CLToolMainD2Ev3445
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.gcov.html b/coverage/core/CLToolMain.cpp.gcov.html new file mode 100644 index 0000000000..938c788afb --- /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-06-10 08:19:14Functions: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             : #include <unordered_map>
+      37             : 
+      38             : namespace PLMD {
+      39             : 
+      40        3445 : CLToolMain::CLToolMain():
+      41        3445 :   argc(0),
+      42        3445 :   in(stdin),
+      43        3445 :   out(stdout)
+      44             : {
+      45        3445 : }
+      46             : 
+      47        6890 : CLToolMain::~CLToolMain() {
+      48             : // empty destructor to delete unique_ptr
+      49        6890 : }
+      50             : 
+      51             : #define CHECK_NULL(val,word) plumed_massert(val,"NULL pointer received in cmd(\"CLTool " + word + "\")");
+      52             : 
+      53       10668 : void CLToolMain::cmd(const std::string& word,const TypesafePtr & val) {
+      54             : 
+      55             : // Enumerate all possible commands:
+      56             :   enum {
+      57             : #include "CLToolMainEnum.inc"
+      58             :   };
+      59             : 
+      60             : // Static object (initialized once) containing the map of commands:
+      61             :   const static std::unordered_map<std::string, int> word_map = {
+      62             : #include "CLToolMainMap.inc"
+      63       41655 :   };
+      64             : 
+      65       10668 :   std::vector<std::string> words=Tools::getWords(word);
+      66       10668 :   unsigned nw=words.size();
+      67       10668 :   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       10668 :     if(it!=word_map.end()) iword=it->second;
+      75       10668 :     switch(iword) {
+      76             :     case cmd_setArgc:
+      77        3441 :       CHECK_NULL(val,word);
+      78        3441 :       argc=val.get<int>();
+      79        3441 :       break;
+      80             :     case cmd_setArgv:
+      81        3441 :       CHECK_NULL(val,word);
+      82        3441 :       v=val.get<const char*const*>(argc);
+      83       23258 :       for(int i=0; i<argc; ++i) argv.push_back(std::string(v[i]));
+      84             :       break;
+      85             :     case cmd_setArgvLine:
+      86           4 :       CHECK_NULL(val,word);
+      87             :       vv=val.get<const char*>();
+      88           4 :       argv=Tools::getWords(vv);
+      89           4 :       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         336 :     case cmd_setMPIComm:
+      99         336 :       comm.Set_comm(val);
+     100             :       break;
+     101           0 :     case cmd_setMPIFComm:
+     102           0 :       comm.Set_fcomm(val);
+     103             :       break;
+     104             :     case cmd_run:
+     105        3445 :       CHECK_NULL(val,word);
+     106        3445 :       argc=argv.size();
+     107             :       {
+     108       23270 :         int n=0; for(int i=0; i<argc; ++i) n+=argv[i].length()+1;
+     109        3445 :         std::vector<char> args(n);
+     110        3445 :         std::vector<char*> vvv(argc);
+     111             :         char* ptr=&args[0];
+     112       23270 :         for(int i=0; i<argc; ++i) {
+     113       19825 :           vvv[i]=ptr;
+     114      174134 :           for(unsigned c=0; c<argv[i].length(); ++c) {
+     115      154309 :             *ptr=argv[i][c]; ptr++;
+     116             :           }
+     117       19825 :           *ptr=0; ptr++;
+     118             :         }
+     119        3445 :         val.set(int(run(argc,&vvv[0],in,out,comm)));
+     120             :       }
+     121        3445 :       break;
+     122           0 :     default:
+     123           0 :       plumed_merror("cannot interpret cmd(\"CLTool " + word + "\"). check plumed developers manual to see the available commands.");
+     124             :       break;
+     125             :     }
+     126             :   }
+     127       10668 : }
+     128             : 
+     129             : /**
+     130             : This is the entry point to the command line tools
+     131             : included in the plumed library.
+     132             : */
+     133             : 
+     134        3445 : int CLToolMain::run(int argc, char **argv,FILE*in,FILE*out,Communicator& pc) {
+     135             :   int i;
+     136             :   bool printhelp=false;
+     137             : 
+     138        3445 :   DLLoader dlloader;
+     139             : 
+     140        3445 :   std::string root=config::getPlumedRoot();
+     141             : 
+     142             :   bool standalone_executable=false;
+     143             : 
+     144             : // Start parsing options
+     145        3445 :   std::string prefix("");
+     146        3445 :   std::string a("");
+     147        6550 :   for(i=1; i<argc; i++) {
+     148       13100 :     a=prefix+argv[i];
+     149        6550 :     if(a.length()==0) continue;
+     150       19650 :     if(a=="help" || a=="-h" || a=="--help") {
+     151             :       printhelp=true;
+     152             :       break;
+     153        6546 :     } else if(a=="--has-mpi") {
+     154           0 :       if(Communicator::initialized()) return 0;
+     155           0 :       else return 1;
+     156        6546 :     } else if(a=="--has-cregex") {
+     157           0 :       return (config::hasCregex()?0:1);
+     158        6546 :     } else if(a=="--has-dlopen") {
+     159           0 :       return (config::hasDlopen()?0:1);
+     160        6546 :     } else if(a=="--has-molfile") {
+     161           0 :       return (config::hasMolfile()?0:1);
+     162        6546 :     } else if(a=="--has-external-molfile") {
+     163           0 :       return (config::hasExternalMolfile()?0:1);
+     164        6546 :     } else if(a=="--has-zlib") {
+     165           0 :       return (config::hasZlib()?0:1);
+     166        6546 :     } else if(a=="--has-xdrfile") {
+     167             :       return 0; // always ok
+     168        6546 :     } else if(a=="--is-installed") {
+     169         619 :       return (config::isInstalled()?0:1);
+     170        5927 :     } else if(a=="--no-mpi") {
+     171             : // this is ignored, as it is parsed in main
+     172        3105 :       continue;
+     173        2822 :     } else if(a=="--mpi") {
+     174             : // this is ignored, as it is parsed in main
+     175           0 :       continue;
+     176        2822 :     } else if(a=="--standalone-executable") {
+     177             :       standalone_executable=true;
+     178        5644 :     } 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        2822 :     } else if(a=="--load") {
+     188             :       prefix="--load=";
+     189        2822 :     } 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        2826 :   if(!standalone_executable) {
+     198        2826 :     std::vector<std::string> files=Tools::ls(root);
+     199        2826 :     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        2826 :   }
+     205             : 
+     206             : // Build list of available C++ tools:
+     207        2826 :   std::vector<std::string> availableCxx=cltoolRegister().list();
+     208             : // Build list of available shell tools:
+     209             :   std::vector<std::string> availableShell;
+     210        2826 :   if(!standalone_executable) {
+     211             :     std::vector<std::string> tmp;
+     212        5652 :     tmp=Tools::ls(std::string(root+"/scripts"));
+     213       22608 :     for(unsigned j=0; j<tmp.size(); ++j) {
+     214       19782 :       size_t ff=tmp[j].find(".sh");
+     215       19782 :       if(ff==std::string::npos) tmp[j].erase();
+     216       19782 :       else                 tmp[j].erase(ff);
+     217             :     }
+     218       22608 :     for(unsigned j=0; j<tmp.size(); ++j) if(tmp[j].length()>0) availableShell.push_back(tmp[j]);
+     219        2826 :   }
+     220             : 
+     221        2826 :   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          64 :     for(unsigned j=0; j<availableCxx.size(); ++j) {
+     235         120 :       auto cl=cltoolRegister().create(CLToolOptions(availableCxx[j]));
+     236          60 :       plumed_assert(cl);
+     237         176 :       std::string manual=availableCxx[j]+" : "+cl->description();
+     238             :       std::fprintf(out,"  plumed %s\n", manual.c_str());
+     239          60 :     }
+     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          56 :       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        2822 :   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        2822 :   std::string command(argv[i]);
+     263             : 
+     264        2822 :   if(find(availableCxx.begin(),availableCxx.end(),command)!=availableCxx.end()) {
+     265        4570 :     auto cl=cltoolRegister().create(CLToolOptions(command));
+     266        2285 :     plumed_assert(cl);
+     267             :     // Read the command line options (returns false if we are just printing help)
+     268        2285 :     if( !cl->readInput( argc-i,&argv[i],in,out ) ) { return 0; }
+     269        2285 :     int ret=cl->main(in,out,pc);
+     270             :     return ret;
+     271        2285 :   }
+     272             : 
+     273         537 :   if(find(availableShell.begin(),availableShell.end(),command)!=availableShell.end()) {
+     274         537 :     plumed_massert(in==stdin,"shell tools can only work on stdin");
+     275         537 :     plumed_massert(out==stdout,"shell tools can only work on stdin");
+     276        1074 :     std::string cmd=config::getEnvCommand()+" \""+root+"/scripts/"+command+".sh\"";
+     277        2034 :     for(int j=i+1; j<argc; j++) cmd+=std::string(" ")+argv[j];
+     278         537 :     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         537 :     if(r!=0) return 1;
+     283         426 :     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        6271 : }
+     291             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..c97be2ae84 --- /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-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD14CLToolRegister7getKeysERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD14CLToolRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb1
_ZN4PLMDlsERSoRKNS_14CLToolRegisterE288
_ZN4PLMD14CLToolRegister6createERKNS_13CLToolOptionsE2345
_ZNK4PLMD14CLToolRegister5checkENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2346
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev3114
_ZN4PLMD14CLToolRegisterD2Ev3473
_ZN4PLMD14CLToolRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS8_EERKNS_13CLToolOptionsEEPFvRNS_8KeywordsEE52095
_ZN4PLMD14CLToolRegister6removeEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS2_EERKNS_13CLToolOptionsEE52095
_ZN4PLMD14cltoolRegisterEv109650
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.func.html b/coverage/core/CLToolRegister.cpp.func.html new file mode 100644 index 0000000000..f880eb7f55 --- /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-06-10 08:19:14Functions: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_8KeywordsEE52095
_ZN4PLMD14CLToolRegister6createERKNS_13CLToolOptionsE2345
_ZN4PLMD14CLToolRegister6removeEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS2_EERKNS_13CLToolOptionsEE52095
_ZN4PLMD14CLToolRegisterD2Ev3473
_ZN4PLMD14cltoolRegisterEv109650
_ZN4PLMDlsERSoRKNS_14CLToolRegisterE288
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev3114
_ZNK4PLMD14CLToolRegister5checkENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2346
_ZNK4PLMD14CLToolRegister7getKeysERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.gcov.html b/coverage/core/CLToolRegister.cpp.gcov.html new file mode 100644 index 0000000000..21e765a14f --- /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-06-10 08:19:14Functions: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        3473 : CLToolRegister::~CLToolRegister() {
+      32        3473 :   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        3473 : }
+      38             : 
+      39      109650 : CLToolRegister& cltoolRegister() {
+      40      109650 :   static CLToolRegister ans;
+      41      109650 :   return ans;
+      42             : }
+      43             : 
+      44       52095 : void CLToolRegister::remove(creator_pointer f) {
+      45      350773 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      46      350773 :     if((*p).second==f) {
+      47       52095 :       m.erase(p); break;
+      48             :     }
+      49             :   }
+      50       52095 : }
+      51             : 
+      52       52095 : 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       52095 :     m.insert(std::pair<std::string,creator_pointer>(key,f));
+      58       52095 :     Keywords keys; kf(keys);
+      59      104190 :     mk.insert(std::pair<std::string,Keywords>(key,keys));
+      60       52095 :   };
+      61       52095 : }
+      62             : 
+      63        2346 : bool CLToolRegister::check(std::string key)const {
+      64        2345 :   if(m.count(key)>0) return true;
+      65             :   return false;
+      66             : }
+      67             : 
+      68        2345 : std::unique_ptr<CLTool> CLToolRegister::create(const CLToolOptions&ao) {
+      69        2345 :   if(ao.line.size()<1)return NULL;
+      70        2345 :   std::unique_ptr<CLTool> cltool;
+      71        4690 :   if(check(ao.line[0])) {
+      72        2345 :     CLToolOptions nao( ao,mk[ao.line[0]] );
+      73        4690 :     cltool=m[ao.line[0]](nao);
+      74             :   }
+      75             :   return cltool;
+      76        2345 : }
+      77             : 
+      78             : 
+      79         288 : std::ostream & operator<<(std::ostream &log,const CLToolRegister&ar) {
+      80         288 :   std::vector<std::string> s(ar.list());
+      81        4608 :   for(unsigned i=0; i<s.size(); i++) log<<"  "<<s[i]<<"\n";
+      82         288 :   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         288 :   return log;
+      92         288 : }
+      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           2 :   } 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        3114 : std::vector<std::string> CLToolRegister::list()const {
+     117             :   std::vector<std::string> s;
+     118       49824 :   for(const auto & it : m) s.push_back(it.first);
+     119        3114 :   std::sort(s.begin(),s.end());
+     120        3114 :   return s;
+     121           0 : }
+     122             : 
+     123             : 
+     124             : 
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..74b201623c --- /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:4242100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE1847
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE1871
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2260
_ZN4PLMD6Colvar5applyEv115500
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE190288
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Colvar.cpp.func.html b/coverage/core/Colvar.cpp.func.html new file mode 100644 index 0000000000..671ee95262 --- /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:4242100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2260
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE1847
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE190288
_ZN4PLMD6Colvar5applyEv115500
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE1871
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Colvar.cpp.gcov.html b/coverage/core/Colvar.cpp.gcov.html new file mode 100644 index 0000000000..1623c5ae80 --- /dev/null +++ b/coverage/core/Colvar.cpp.gcov.html @@ -0,0 +1,202 @@ + + + + + + + + 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:4242100.0 %
Date:2024-06-10 08:19:14Functions: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        1871 : Colvar::Colvar(const ActionOptions&ao):
+      30             :   Action(ao),
+      31             :   ActionAtomistic(ao),
+      32             :   ActionWithValue(ao),
+      33        1871 :   isEnergy(false),
+      34        1871 :   isExtraCV(false)
+      35             : {
+      36        1871 : }
+      37             : 
+      38        1847 : void Colvar::registerKeywords( Keywords& keys ) {
+      39        1847 :   Action::registerKeywords( keys );
+      40        1847 :   ActionWithValue::registerKeywords( keys );
+      41        1847 :   ActionAtomistic::registerKeywords( keys );
+      42        3694 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      43        1847 : }
+      44             : 
+      45        2260 : void Colvar::requestAtoms(const std::vector<AtomNumber> & a) {
+      46        2260 :   plumed_massert(!isEnergy,"request atoms should not be called if this is energy");
+      47             : // Tell actionAtomistic what atoms we are getting
+      48        2260 :   ActionAtomistic::requestAtoms(a);
+      49             : // Resize the derivatives of all atoms
+      50        5961 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(3*a.size()+9);
+      51        2259 : }
+      52             : 
+      53      115500 : void Colvar::apply() {
+      54             :   std::vector<Vector>&   f(modifyForces());
+      55             :   Tensor&           v(modifyVirial());
+      56             :   const unsigned    nat=getNumberOfAtoms();
+      57      115500 :   const unsigned    ncp=getNumberOfComponents();
+      58      115500 :   const unsigned    fsz=f.size();
+      59             : 
+      60             :   unsigned stride=1;
+      61             :   unsigned rank=0;
+      62      115500 :   if(ncp>4*comm.Get_size()) {
+      63        1560 :     stride=comm.Get_size();
+      64        1560 :     rank=comm.Get_rank();
+      65             :   }
+      66             : 
+      67      115500 :   unsigned nt=OpenMP::getNumThreads();
+      68      115500 :   if(nt>ncp/(4*stride)) nt=1;
+      69             : 
+      70      115500 :   if(!isEnergy && !isExtraCV) {
+      71      111471 :     #pragma omp parallel num_threads(nt)
+      72             :     {
+      73             :       std::vector<Vector> omp_f(fsz);
+      74             :       Tensor              omp_v;
+      75             :       std::vector<double> forces(3*nat+9);
+      76             :       #pragma omp for
+      77             :       for(unsigned i=rank; i<ncp; i+=stride) {
+      78             :         if(getPntrToComponent(i)->applyForce(forces)) {
+      79             :           for(unsigned j=0; j<nat; ++j) {
+      80             :             omp_f[j][0]+=forces[3*j+0];
+      81             :             omp_f[j][1]+=forces[3*j+1];
+      82             :             omp_f[j][2]+=forces[3*j+2];
+      83             :           }
+      84             :           omp_v(0,0)+=forces[3*nat+0];
+      85             :           omp_v(0,1)+=forces[3*nat+1];
+      86             :           omp_v(0,2)+=forces[3*nat+2];
+      87             :           omp_v(1,0)+=forces[3*nat+3];
+      88             :           omp_v(1,1)+=forces[3*nat+4];
+      89             :           omp_v(1,2)+=forces[3*nat+5];
+      90             :           omp_v(2,0)+=forces[3*nat+6];
+      91             :           omp_v(2,1)+=forces[3*nat+7];
+      92             :           omp_v(2,2)+=forces[3*nat+8];
+      93             :         }
+      94             :       }
+      95             :       #pragma omp critical
+      96             :       {
+      97             :         for(unsigned j=0; j<nat; ++j) f[j]+=omp_f[j];
+      98             :         v+=omp_v;
+      99             :       }
+     100             :     }
+     101             : 
+     102      111471 :     if(ncp>4*comm.Get_size()) {
+     103        1560 :       if(fsz>0) comm.Sum(&f[0][0],3*fsz);
+     104        1560 :       comm.Sum(&v[0][0],9);
+     105             :     }
+     106             : 
+     107        4029 :   } else if( isEnergy ) {
+     108        3989 :     std::vector<double> forces(1);
+     109        3989 :     if(getPntrToComponent(0)->applyForce(forces)) modifyForceOnEnergy()+=forces[0];
+     110          40 :   } else if( isExtraCV ) {
+     111          40 :     std::vector<double> forces(1);
+     112          40 :     if(getPntrToComponent(0)->applyForce(forces)) modifyForceOnExtraCV()+=forces[0];
+     113             :   }
+     114      115500 : }
+     115             : 
+     116      190288 : void Colvar::setBoxDerivativesNoPbc(Value* v) {
+     117      190288 :   Tensor virial;
+     118             :   unsigned nat=getNumberOfAtoms();
+     119    33611768 :   for(unsigned i=0; i<nat; i++) virial-=Tensor(getPosition(i),
+     120    16710740 :                                           Vector(v->getDerivative(3*i+0),
+     121             :                                               v->getDerivative(3*i+1),
+     122    33421480 :                                               v->getDerivative(3*i+2)));
+     123      190288 :   setBoxDerivatives(v,virial);
+     124      190288 : }
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9e5e8fd464 --- /dev/null +++ b/coverage/core/Colvar.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2929100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarD2Ev1870
_ZN4PLMD6Colvar22getNumberOfDerivativesEv4879
_ZN4PLMD6Colvar17setBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE13246
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEv118901
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE228947
_ZN4PLMD6Colvar19setAtomsDerivativesEiRKNS_13VectorGenericILj3EEE16116836
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE17928231
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Colvar.h.func.html b/coverage/core/Colvar.h.func.html new file mode 100644 index 0000000000..11a4679787 --- /dev/null +++ b/coverage/core/Colvar.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2929100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE228947
_ZN4PLMD6Colvar17setBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE13246
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE17928231
_ZN4PLMD6Colvar19setAtomsDerivativesEiRKNS_13VectorGenericILj3EEE16116836
_ZN4PLMD6Colvar22getNumberOfDerivativesEv4879
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEv118901
_ZN4PLMD6ColvarD2Ev1870
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Colvar.h.gcov.html b/coverage/core/Colvar.h.gcov.html new file mode 100644 index 0000000000..7796e099a0 --- /dev/null +++ b/coverage/core/Colvar.h.gcov.html @@ -0,0 +1,196 @@ + + + + + + + + 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:2929100.0 %
Date:2024-06-10 08:19:14Functions:77100.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             :   bool isEnergy;
+      46             :   bool isExtraCV;
+      47             :   void requestAtoms(const std::vector<AtomNumber> & a);
+      48             : // Set the derivatives for a particular atom equal to the input Vector
+      49             : // This routine is called setAtomsDerivatives because not because you
+      50             : // are setting the derivative of many atoms but because you are setting
+      51             : // the derivatives of a particular atom.  The s is an apostrophe s
+      52             : // but you can't put apostrophes in function names
+      53             :   void           setAtomsDerivatives(int,const Vector&);
+      54             :   void           setAtomsDerivatives(Value*,int,const Vector&);
+      55             :   void           setBoxDerivatives(const Tensor&);
+      56             :   void           setBoxDerivatives(Value*,const Tensor&);
+      57             :   const Tensor & getBoxDerivatives()const;
+      58             :   const double & getForce()const;
+      59             :   void apply() override;
+      60             : /// Set box derivatives automatically.
+      61             : /// It should be called after the setAtomsDerivatives has been used for all
+      62             : /// single atoms.
+      63             : /// \warning It only works for collective variable NOT using PBCs!
+      64             :   void           setBoxDerivativesNoPbc();
+      65             :   void           setBoxDerivativesNoPbc(Value*);
+      66             : public:
+      67      115866 :   bool checkIsEnergy() {return isEnergy;}
+      68             :   explicit Colvar(const ActionOptions&);
+      69        1870 :   ~Colvar() {}
+      70             :   static void registerKeywords( Keywords& keys );
+      71             :   unsigned getNumberOfDerivatives() override;
+      72             : };
+      73             : 
+      74             : inline
+      75    17928231 : void Colvar::setAtomsDerivatives(Value*v,int i,const Vector&d) {
+      76    17928231 :   v->addDerivative(3*i+0,d[0]);
+      77    17928231 :   v->addDerivative(3*i+1,d[1]);
+      78    17928231 :   v->addDerivative(3*i+2,d[2]);
+      79    17928231 : }
+      80             : 
+      81             : 
+      82             : inline
+      83      228947 : void Colvar::setBoxDerivatives(Value* v,const Tensor&d) {
+      84             :   unsigned nat=getNumberOfAtoms();
+      85      228947 :   v->addDerivative(3*nat+0,d(0,0));
+      86      228947 :   v->addDerivative(3*nat+1,d(0,1));
+      87      228947 :   v->addDerivative(3*nat+2,d(0,2));
+      88      228947 :   v->addDerivative(3*nat+3,d(1,0));
+      89      228947 :   v->addDerivative(3*nat+4,d(1,1));
+      90      228947 :   v->addDerivative(3*nat+5,d(1,2));
+      91      228947 :   v->addDerivative(3*nat+6,d(2,0));
+      92      228947 :   v->addDerivative(3*nat+7,d(2,1));
+      93      228947 :   v->addDerivative(3*nat+8,d(2,2));
+      94      228947 : }
+      95             : 
+      96             : inline
+      97    16116836 : void Colvar::setAtomsDerivatives(int i,const Vector&d) {
+      98    16116836 :   setAtomsDerivatives(getPntrToValue(),i,d);
+      99    16116836 : }
+     100             : 
+     101             : inline
+     102       13246 : void Colvar::setBoxDerivatives(const Tensor&d) {
+     103       13246 :   setBoxDerivatives(getPntrToValue(),d);
+     104       13246 : }
+     105             : 
+     106             : inline
+     107      118901 : void Colvar::setBoxDerivativesNoPbc() {
+     108      118901 :   setBoxDerivativesNoPbc(getPntrToValue());
+     109      118901 : }
+     110             : 
+     111             : inline
+     112        4879 : unsigned Colvar::getNumberOfDerivatives() {
+     113        4879 :   return 3*getNumberOfAtoms() + 9;
+     114             : }
+     115             : 
+     116             : 
+     117             : }
+     118             : 
+     119             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/DataFetchingObject.cpp.func-sort-c.html b/coverage/core/DataFetchingObject.cpp.func-sort-c.html new file mode 100644 index 0000000000..0073b2d76b --- /dev/null +++ b/coverage/core/DataFetchingObject.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - core/DataFetchingObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataFetchingObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:476968.1 %
Date:2024-06-10 08:19:14Functions:131681.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18DataFetchingObject9get_shapeERKNS_9ActionSetERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_RKNS_11TypesafePtrE0
_ZN4PLMD23DataFetchingObjectTypedIfE14finishDataGrabEv0
_ZN4PLMD23DataFetchingObjectTypedIfE7setDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_11TypesafePtrE0
_ZN4PLMD23DataFetchingObjectTypedIfEC2ERNS_10PlumedMainE1
_ZN4PLMD23DataFetchingObjectTypedIfED0Ev1
_ZN4PLMD23DataFetchingObjectTypedIfED2Ev1
_ZN4PLMD18DataFetchingObject8get_rankERKNS_9ActionSetERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_RKNS_11TypesafePtrE64
_ZN4PLMD23DataFetchingObjectTypedIdE7setDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_11TypesafePtrE64
_ZN4PLMD18DataFetchingObject10findActionERKNS_9ActionSetERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE128
_ZN4PLMD23DataFetchingObjectTypedIdE14finishDataGrabEv245726
_ZNK4PLMD18DataFetchingObject8activateEv248113
_ZN4PLMD23DataFetchingObjectTypedIdEC2ERNS_10PlumedMainE405174
_ZN4PLMD23DataFetchingObjectTypedIdED0Ev405174
_ZN4PLMD23DataFetchingObjectTypedIdED2Ev405174
_ZN4PLMD18DataFetchingObject6createEjRNS_10PlumedMainE405175
_ZN4PLMD18DataFetchingObjectC2ERNS_10PlumedMainE405175
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/DataFetchingObject.cpp.func.html b/coverage/core/DataFetchingObject.cpp.func.html new file mode 100644 index 0000000000..f13b33167c --- /dev/null +++ b/coverage/core/DataFetchingObject.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - core/DataFetchingObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataFetchingObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:476968.1 %
Date:2024-06-10 08:19:14Functions:131681.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18DataFetchingObject10findActionERKNS_9ActionSetERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE128
_ZN4PLMD18DataFetchingObject6createEjRNS_10PlumedMainE405175
_ZN4PLMD18DataFetchingObject8get_rankERKNS_9ActionSetERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_RKNS_11TypesafePtrE64
_ZN4PLMD18DataFetchingObject9get_shapeERKNS_9ActionSetERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_RKNS_11TypesafePtrE0
_ZN4PLMD18DataFetchingObjectC2ERNS_10PlumedMainE405175
_ZN4PLMD23DataFetchingObjectTypedIdE14finishDataGrabEv245726
_ZN4PLMD23DataFetchingObjectTypedIdE7setDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_11TypesafePtrE64
_ZN4PLMD23DataFetchingObjectTypedIdEC2ERNS_10PlumedMainE405174
_ZN4PLMD23DataFetchingObjectTypedIdED0Ev405174
_ZN4PLMD23DataFetchingObjectTypedIdED2Ev405174
_ZN4PLMD23DataFetchingObjectTypedIfE14finishDataGrabEv0
_ZN4PLMD23DataFetchingObjectTypedIfE7setDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_11TypesafePtrE0
_ZN4PLMD23DataFetchingObjectTypedIfEC2ERNS_10PlumedMainE1
_ZN4PLMD23DataFetchingObjectTypedIfED0Ev1
_ZN4PLMD23DataFetchingObjectTypedIfED2Ev1
_ZNK4PLMD18DataFetchingObject8activateEv248113
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/DataFetchingObject.cpp.gcov.html b/coverage/core/DataFetchingObject.cpp.gcov.html new file mode 100644 index 0000000000..3ef0f8b500 --- /dev/null +++ b/coverage/core/DataFetchingObject.cpp.gcov.html @@ -0,0 +1,236 @@ + + + + + + + + LCOV - plumed test coverage - core/DataFetchingObject.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataFetchingObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:476968.1 %
Date:2024-06-10 08:19:14Functions:131681.2 %
+
+ + + + + + + + +

+
          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 "DataFetchingObject.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionSet.h"
+      25             : #include "Action.h"
+      26             : #include "ActionWithValue.h"
+      27             : #include "Value.h"
+      28             : #include "tools/Tools.h"
+      29             : #include "tools/TypesafePtr.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : template <class T>
+      34             : class DataFetchingObjectTyped : public DataFetchingObject {
+      35             : private:
+      36             : /// A map containing the data we are grabbing
+      37             :   std::map<std::string,TypesafePtr> data;
+      38             : public:
+      39             :   explicit DataFetchingObjectTyped(PlumedMain&plumed);
+      40      810350 :   ~DataFetchingObjectTyped() {}
+      41             :   void setData( const std::string& key, const std::string& type, const TypesafePtr & outval ) override;
+      42             :   void finishDataGrab() override;
+      43             : };
+      44             : 
+      45      405175 : std::unique_ptr<DataFetchingObject> DataFetchingObject::create(unsigned n, PlumedMain& p) {
+      46      405175 :   if(n==sizeof(double)) {
+      47      405174 :     return Tools::make_unique<DataFetchingObjectTyped<double>>(p);
+      48           1 :   } else  if(n==sizeof(float)) {
+      49           1 :     return Tools::make_unique<DataFetchingObjectTyped<float>>(p);
+      50             :   }
+      51           0 :   std::string pp; Tools::convert(n,pp);
+      52           0 :   plumed_merror("cannot create an MD interface with sizeof(real)=="+ pp);
+      53             : }
+      54             : 
+      55      405175 : DataFetchingObject::DataFetchingObject(PlumedMain&p):
+      56      405175 :   plumed(p)
+      57             : {
+      58      405175 : }
+      59             : 
+      60      248113 : bool DataFetchingObject::activate() const {
+      61      248753 :   for(unsigned j=0; j<myactions.size(); ++j) myactions[j]->activate();
+      62      248113 :   if( myactions.size()>0 ) return true;
+      63             :   return false;
+      64             : }
+      65             : 
+      66         128 : ActionWithValue* DataFetchingObject::findAction( const ActionSet& a, const std::string& key ) {
+      67         128 :   std::string aname = key; std::size_t dot = key.find(".");
+      68         128 :   if( dot!=std::string::npos ) aname = key.substr(0,dot);
+      69         256 :   return a.selectWithLabel<ActionWithValue*>( aname );
+      70             : }
+      71             : 
+      72          64 : void DataFetchingObject::get_rank( const ActionSet& a, const std::string& key, const std::string& type, const TypesafePtr & dims ) {
+      73          64 :   plumed_assert( Tools::getWords(key,"\t\n ,").size()==1 );
+      74          64 :   plumed_massert( key.find("*")==std::string::npos, "cannot use wildcards in python interface");
+      75             : 
+      76             :   // Find the appropriate action and store value containing quantity of interest
+      77          64 :   ActionWithValue* myv = findAction( a, key );
+      78          64 :   Value* val = myv->copyOutput( key );
+      79             : 
+      80             :   // Now work out what we are returning for this action
+      81          64 :   if( type=="" ) {
+      82             :     // Return a single value in this case
+      83          64 :     dims.set(long(1));
+      84           0 :   } else if( type=="derivatives" ) {
+      85           0 :     plumed_merror("not yet implemented");
+      86           0 :   } else if( type=="forces" ) {
+      87           0 :     plumed_merror("not yet implemented");
+      88             :   } else {
+      89           0 :     plumed_merror("invalid type specifier");
+      90             :   }
+      91          64 : }
+      92             : 
+      93           0 : void DataFetchingObject::get_shape( const ActionSet& a, const std::string& key, const std::string& type, const TypesafePtr & dims ) {
+      94           0 :   plumed_assert( Tools::getWords(key,"\t\n ,").size()==1 );
+      95           0 :   plumed_massert( key.find("*")==std::string::npos, "cannot use wildcards in python interface");
+      96             : 
+      97             :   // Find the appropriate action and store value containing quantity of interest
+      98           0 :   ActionWithValue* myv = findAction( a, key );
+      99           0 :   Value* val = myv->copyOutput( key );
+     100             : 
+     101             :   // Now work out what we are returning for this action
+     102           0 :   if( type=="" ) {
+     103             :     // Return a single value in this case
+     104           0 :     dims.set(long(1));
+     105           0 :   } else if( type=="derivatives" ) {
+     106           0 :     plumed_merror("not yet implemented");
+     107           0 :   } else if( type=="forces" ) {
+     108           0 :     plumed_merror("not yet implemented");
+     109             :   } else {
+     110           0 :     plumed_merror("invalid type specifier");
+     111             :   }
+     112           0 : }
+     113             : 
+     114             : template <class T>
+     115      405175 : DataFetchingObjectTyped<T>::DataFetchingObjectTyped(PlumedMain&p):
+     116      405175 :   DataFetchingObject(p)
+     117             : {
+     118      405175 : }
+     119             : 
+     120             : template <class T>
+     121          64 : void DataFetchingObjectTyped<T>::setData( const std::string& key, const std::string& type, const TypesafePtr & outval ) {
+     122          64 :   plumed_assert( Tools::getWords(key,"\t\n ,").size()==1 );
+     123          64 :   plumed_massert( key.find("*")==std::string::npos, "cannot use wildcards in python interface");
+     124         128 :   plumed_massert( !data.count(key + " " + type), "already collecting this data elsewhere");
+     125             :   // Add the space to store the data to the data map
+     126          64 :   T* f=outval.get<T*>();
+     127         128 :   data.insert(std::pair<std::string,TypesafePtr>(key + " " + type,f));
+     128             : 
+     129             :   // Find the appropriate action and store value containing quantity of interest
+     130          64 :   ActionWithValue* myv = DataFetchingObject::findAction( plumed.getActionSet(), key );
+     131             :   // Store the action if not already stored
+     132             :   bool found=false;
+     133        1056 :   for(const auto & p : myactions) {
+     134         992 :     if( p->getLabel()==myv->getLabel() ) { found=true; break; }
+     135             :   }
+     136          64 :   if( !found ) myactions.push_back( myv );
+     137             :   // Store the value
+     138          64 :   myvalues.push_back( myv->copyOutput( key ) );
+     139          64 : }
+     140             : 
+     141             : template <class T>
+     142      245726 : void DataFetchingObjectTyped<T>::finishDataGrab() {
+     143             :   // Run over all values and collect data
+     144      246366 :   for(const auto & p : myvalues ) {
+     145        1280 :     auto val=data.find(p->getName() + " ");
+     146        1280 :     if( data.find(p->getName() + " ")!=data.end() ) {
+     147         640 :       val->second.set(static_cast<T>( p->get() ));
+     148             :     }
+     149        1280 :     if( data.find(p->getName() + " derivatives")!=data.end() ) {
+     150           0 :       plumed_merror("not implemented yet");
+     151             :     }
+     152        1280 :     if( data.find(p->getName() + " forces")!=data.end() ) {
+     153           0 :       plumed_merror("not implemented yet");
+     154             :     }
+     155             :   }
+     156      245726 : }
+     157             : 
+     158             : }
+     159             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/DataFetchingObject.h.func-sort-c.html b/coverage/core/DataFetchingObject.h.func-sort-c.html new file mode 100644 index 0000000000..7ae3a84bf9 --- /dev/null +++ b/coverage/core/DataFetchingObject.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/DataFetchingObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataFetchingObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18DataFetchingObjectD0Ev0
_ZN4PLMD18DataFetchingObjectD2Ev405175
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/DataFetchingObject.h.func.html b/coverage/core/DataFetchingObject.h.func.html new file mode 100644 index 0000000000..1572dacc34 --- /dev/null +++ b/coverage/core/DataFetchingObject.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/DataFetchingObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataFetchingObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18DataFetchingObjectD0Ev0
_ZN4PLMD18DataFetchingObjectD2Ev405175
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/DataFetchingObject.h.gcov.html b/coverage/core/DataFetchingObject.h.gcov.html new file mode 100644 index 0000000000..3529bb5a86 --- /dev/null +++ b/coverage/core/DataFetchingObject.h.gcov.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - core/DataFetchingObject.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataFetchingObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-06-10 08:19:14Functions: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_DataFetchingObject_h
+      23             : #define __PLUMED_core_DataFetchingObject_h
+      24             : 
+      25             : #include <string>
+      26             : #include <vector>
+      27             : #include <set>
+      28             : #include <map>
+      29             : #include <memory>
+      30             : 
+      31             : #include "tools/TypesafePtr.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : class ActionSet;
+      36             : class PlumedMain;
+      37             : class ActionWithValue;
+      38             : class Value;
+      39             : 
+      40             : class DataFetchingObject {
+      41             : protected:
+      42             : /// Pointers to the various actions required by the grabber
+      43             :   std::vector<ActionWithValue*> myactions;
+      44             : /// The values required by the user
+      45             :   std::vector<Value*> myvalues;
+      46             : /// A copy of the plumed main object
+      47             :   PlumedMain & plumed;
+      48             : public:
+      49             :   static std::unique_ptr<DataFetchingObject> create(unsigned n, PlumedMain& p);
+      50             : /// A constructor so that we can create the plumed main object
+      51             :   explicit DataFetchingObject(PlumedMain&p);
+      52      405175 :   virtual ~DataFetchingObject() {}
+      53             : ///
+      54             :   bool activate() const ;
+      55             : /// Return the rank required for a particular key
+      56             :   static void get_rank( const ActionSet& a, const std::string& key, const std::string& type, const TypesafePtr & rank );
+      57             : /// Return the shape required for a particular key
+      58             :   static void get_shape( const ActionSet& a, const std::string& key, const std::string& type, const TypesafePtr & dims );
+      59             : /// Find the action that calculates a particular value
+      60             :   static ActionWithValue* findAction( const ActionSet& a, const std::string& key );
+      61             : /// Set the pointer to the data
+      62             :   virtual void setData( const std::string& key, const std::string& type, const TypesafePtr & outval )=0;
+      63             : /// After calc has been performed grab all the data and put it in the relevant arrays
+      64             :   virtual void finishDataGrab()=0;
+      65             : };
+      66             : 
+      67             : }
+      68             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..19e259af09 --- /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-06-10 08:19:14Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev404395
_ZN4PLMD16ExchangePatternsD2Ev404395
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.func.html b/coverage/core/ExchangePatterns.cpp.func.html new file mode 100644 index 0000000000..9a3da8391d --- /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-06-10 08:19:14Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev404395
_ZN4PLMD16ExchangePatternsD2Ev404395
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.gcov.html b/coverage/core/ExchangePatterns.cpp.gcov.html new file mode 100644 index 0000000000..976c7ae431 --- /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-06-10 08:19:14Functions: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      404395 : ExchangePatterns::ExchangePatterns():
+      28      404395 :   PatternFlag(NONE),
+      29      404395 :   NumberOfReplicas(1)
+      30      404395 : {}
+      31             : 
+      32      404395 : 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.15
+
+ + + 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 0000000000..66cdea776b --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/core/FlexibleBin.cpp.func.html b/coverage/core/FlexibleBin.cpp.func.html new file mode 100644 index 0000000000..6cbf88e143 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/core/FlexibleBin.cpp.gcov.html b/coverage/core/FlexibleBin.cpp.gcov.html new file mode 100644 index 0000000000..3111955858 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..2347242828 --- /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:10314073.6 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4GREX13savePositionsEv114
_ZN4PLMD4GREX9calculateEv114
_ZN4PLMD4GREXC2ERNS_10PlumedMainE204
_ZN4PLMD4GREXD0Ev204
_ZN4PLMD4GREXD2Ev204
_ZN4PLMD4GREX3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1077
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/GREX.cpp.func.html b/coverage/core/GREX.cpp.func.html new file mode 100644 index 0000000000..42b32eff5d --- /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:10314073.6 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4GREX13savePositionsEv114
_ZN4PLMD4GREX3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1077
_ZN4PLMD4GREX9calculateEv114
_ZN4PLMD4GREXC2ERNS_10PlumedMainE204
_ZN4PLMD4GREXD0Ev204
_ZN4PLMD4GREXD2Ev204
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/GREX.cpp.gcov.html b/coverage/core/GREX.cpp.gcov.html new file mode 100644 index 0000000000..844f8618dd --- /dev/null +++ b/coverage/core/GREX.cpp.gcov.html @@ -0,0 +1,299 @@ + + + + + + + + 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:10314073.6 %
Date:2024-06-10 08:19:14Functions: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 "Atoms.h"
+      25             : #include "tools/Tools.h"
+      26             : #include "tools/Communicator.h"
+      27             : #include <sstream>
+      28             : #include <unordered_map>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32         204 : GREX::GREX(PlumedMain&p):
+      33         204 :   initialized(false),
+      34         204 :   plumedMain(p),
+      35         204 :   atoms(p.getAtoms()),
+      36         204 :   partner(-1), // = unset
+      37         204 :   localDeltaBias(0),
+      38         204 :   foreignDeltaBias(0),
+      39         204 :   localUNow(0),
+      40         204 :   localUSwap(0),
+      41         204 :   myreplica(-1) // = unset
+      42             : {
+      43         204 :   p.setSuffix(".NA");
+      44         204 : }
+      45             : 
+      46         408 : GREX::~GREX() {
+      47             : // empty destructor to delete unique_ptr
+      48         408 : }
+      49             : 
+      50             : #define CHECK_INIT(ini,word) plumed_massert(ini,"cmd(\"" + word +"\") should be only used after GREX initialization")
+      51             : #define CHECK_NOTINIT(ini,word) plumed_massert(!(ini),"cmd(\"" + word +"\") should be only used before GREX initialization")
+      52             : #define CHECK_NOTNULL(val,word) plumed_massert(val,"NULL pointer received in cmd(\"GREX " + word + "\")");
+      53             : 
+      54        1077 : void GREX::cmd(const std::string&key,const TypesafePtr & val) {
+      55             : // Enumerate all possible commands:
+      56             :   enum {
+      57             : #include "GREXEnum.inc"
+      58             :   };
+      59             : 
+      60             : // Static object (initialized once) containing the map of commands:
+      61             :   const static std::unordered_map<std::string, int> word_map = {
+      62             : #include "GREXMap.inc"
+      63        4494 :   };
+      64             : 
+      65        1077 :   std::vector<std::string> words=Tools::getWords(key);
+      66        1077 :   unsigned nw=words.size();
+      67        1077 :   if(nw==0) {
+      68             :     // do nothing
+      69             :   } else {
+      70             :     int iword=-1;
+      71             :     const auto it=word_map.find(words[0]);
+      72        1077 :     if(it!=word_map.end()) iword=it->second;
+      73        1077 :     switch(iword) {
+      74             :     case cmd_initialized:
+      75           0 :       CHECK_NOTNULL(val,key);
+      76           0 :       val.set(int(initialized));
+      77             :       break;
+      78         204 :     case cmd_setMPIIntracomm:
+      79         204 :       CHECK_NOTINIT(initialized,key);
+      80         408 :       intracomm.Set_comm(val.get<const void*>());
+      81         204 :       break;
+      82         156 :     case cmd_setMPIIntercomm:
+      83         156 :       CHECK_NOTINIT(initialized,key);
+      84         312 :       intercomm.Set_comm(val.get<const void*>());
+      85         312 :       plumedMain.multi_sim_comm.Set_comm(val.get<const void*>());
+      86         156 :       break;
+      87           0 :     case cmd_setMPIFIntracomm:
+      88           0 :       CHECK_NOTINIT(initialized,key);
+      89           0 :       intracomm.Set_fcomm(val.get<const void*>());
+      90           0 :       break;
+      91           0 :     case cmd_setMPIFIntercomm:
+      92           0 :       CHECK_NOTINIT(initialized,key);
+      93           0 :       intercomm.Set_fcomm(val.get<const void*>());
+      94           0 :       plumedMain.multi_sim_comm.Set_fcomm(val.get<const void*>());
+      95           0 :       break;
+      96         204 :     case cmd_init:
+      97         204 :       CHECK_NOTINIT(initialized,key);
+      98         204 :       initialized=true;
+      99             : // note that for PEs!=root this is automatically 0 (comm defaults to MPI_COMM_SELF)
+     100         204 :       myreplica=intercomm.Get_rank();
+     101         204 :       intracomm.Sum(myreplica);
+     102             :       {
+     103             :         std::string s;
+     104         204 :         Tools::convert(myreplica,s);
+     105         408 :         plumedMain.setSuffix("."+s);
+     106             :       }
+     107         204 :       break;
+     108          57 :     case cmd_prepare:
+     109          57 :       CHECK_INIT(initialized,key);
+     110          57 :       if(intracomm.Get_rank()==0) return;
+     111          57 :       intracomm.Bcast(partner,0);
+     112          57 :       calculate();
+     113             :       break;
+     114          57 :     case cmd_setPartner:
+     115          57 :       CHECK_INIT(initialized,key);
+     116          57 :       partner=val.get<int>();
+     117          57 :       break;
+     118         114 :     case cmd_savePositions:
+     119         114 :       CHECK_INIT(initialized,key);
+     120         114 :       savePositions();
+     121             :       break;
+     122          57 :     case cmd_calculate:
+     123          57 :       CHECK_INIT(initialized,key);
+     124          57 :       if(intracomm.Get_rank()!=0) return;
+     125          57 :       intracomm.Bcast(partner,0);
+     126          57 :       calculate();
+     127             :       break;
+     128           0 :     case cmd_getLocalDeltaBias:
+     129           0 :       CHECK_INIT(initialized,key);
+     130           0 :       CHECK_NOTNULL(val,key);
+     131           0 :       atoms.double2MD(localDeltaBias/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy()),val);
+     132           0 :       break;
+     133           0 :     case cmd_cacheLocalUNow:
+     134           0 :       CHECK_INIT(initialized,key);
+     135           0 :       CHECK_NOTNULL(val,key);
+     136             :       {
+     137             :         double x;
+     138           0 :         atoms.MD2double(val,x);
+     139           0 :         localUNow=x*(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy());
+     140           0 :         intracomm.Sum(localUNow);
+     141             :       }
+     142           0 :       break;
+     143           0 :     case cmd_cacheLocalUSwap:
+     144           0 :       CHECK_INIT(initialized,key);
+     145           0 :       CHECK_NOTNULL(val,key);
+     146             :       {
+     147             :         double x;
+     148           0 :         atoms.MD2double(val,x);
+     149           0 :         localUSwap=x*(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy());
+     150           0 :         intracomm.Sum(localUSwap);
+     151             :       }
+     152           0 :       break;
+     153           0 :     case cmd_getForeignDeltaBias:
+     154           0 :       CHECK_INIT(initialized,key);
+     155           0 :       CHECK_NOTNULL(val,key);
+     156           0 :       atoms.double2MD(foreignDeltaBias/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy()),val);
+     157           0 :       break;
+     158          57 :     case cmd_shareAllDeltaBias:
+     159          57 :       CHECK_INIT(initialized,key);
+     160          57 :       if(intracomm.Get_rank()!=0) return;
+     161          57 :       allDeltaBias.assign(intercomm.Get_size(),0.0);
+     162          57 :       allDeltaBias[intercomm.Get_rank()]=localDeltaBias;
+     163          57 :       intercomm.Sum(allDeltaBias);
+     164             :       break;
+     165         171 :     case cmd_getDeltaBias:
+     166         171 :       CHECK_INIT(initialized,key);
+     167         171 :       CHECK_NOTNULL(val,key);
+     168         171 :       plumed_assert(nw==2);
+     169         171 :       plumed_massert(allDeltaBias.size()==static_cast<unsigned>(intercomm.Get_size()),
+     170             :                      "to retrieve bias with cmd(\"GREX getDeltaBias\"), first share it with cmd(\"GREX shareAllDeltaBias\")");
+     171             :       {
+     172             :         unsigned rep;
+     173         171 :         Tools::convert(words[1],rep);
+     174         171 :         plumed_massert(rep<allDeltaBias.size(),"replica index passed to cmd(\"GREX getDeltaBias\") is out of range");
+     175         171 :         double d=allDeltaBias[rep]/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy());
+     176         171 :         atoms.double2MD(d,val);
+     177             :       }
+     178         171 :       break;
+     179           0 :     default:
+     180           0 :       plumed_merror("cannot interpret cmd(\" GREX" + key + "\"). check plumed developers manual to see the available commands.");
+     181             :       break;
+     182             :     }
+     183             :   }
+     184        1077 : }
+     185             : 
+     186         114 : void GREX::savePositions() {
+     187         114 :   plumedMain.prepareDependencies();
+     188         114 :   plumedMain.resetActive(true);
+     189         114 :   atoms.shareAll();
+     190         114 :   plumedMain.waitData();
+     191         114 :   std::ostringstream o;
+     192         114 :   atoms.writeBinary(o);
+     193         114 :   buffer=o.str();
+     194         114 : }
+     195             : 
+     196         114 : void GREX::calculate() {
+     197             :   unsigned nn=buffer.size();
+     198         114 :   std::vector<char> rbuf(nn);
+     199         114 :   localDeltaBias=-plumedMain.getBias();
+     200         114 :   if(intracomm.Get_rank()==0) {
+     201          57 :     Communicator::Request req=intercomm.Isend(buffer,partner,1066);
+     202          57 :     intercomm.Recv(rbuf,partner,1066);
+     203          57 :     req.wait();
+     204             :   }
+     205         114 :   intracomm.Bcast(rbuf,0);
+     206         114 :   std::istringstream i(std::string(&rbuf[0],rbuf.size()));
+     207         114 :   atoms.readBinary(i);
+     208         114 :   plumedMain.setExchangeStep(true);
+     209         114 :   plumedMain.prepareDependencies();
+     210         114 :   plumedMain.justCalculate();
+     211         114 :   plumedMain.setExchangeStep(false);
+     212         114 :   localDeltaBias+=plumedMain.getBias();
+     213         114 :   localDeltaBias+=localUSwap-localUNow;
+     214         114 :   if(intracomm.Get_rank()==0) {
+     215          57 :     Communicator::Request req=intercomm.Isend(localDeltaBias,partner,1067);
+     216          57 :     intercomm.Recv(foreignDeltaBias,partner,1067);
+     217          57 :     req.wait();
+     218             :   }
+     219         114 :   intracomm.Bcast(foreignDeltaBias,0);
+     220         228 : }
+     221             : 
+     222             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..fde2029f82 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.func-sort-c.html @@ -0,0 +1,141 @@ + + + + + + + + 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:15118581.6 %
Date:2024-06-10 08:19:14Functions:131776.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfoC2ERKNS_13ActionOptionsE0
_ZN4PLMD14GenericMolInfoD2Ev0
_ZNK4PLMD14GenericMolInfo10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD14GenericMolInfo7isWholeEv0
_ZNK4PLMD14GenericMolInfo11getPositionENS_10AtomNumberE2
_ZNK4PLMD14GenericMolInfo12checkForAtomENS_10AtomNumberE4
_ZN4PLMD14GenericMolInfo11getBackboneERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS1_IS1_INS_10AtomNumberESaISD_EESaISF_EE25
_ZN4PLMD14GenericMolInfoC1ERKNS_13ActionOptionsE84
_ZN4PLMD14GenericMolInfoD0Ev84
_ZN4PLMD14GenericMolInfoD1Ev84
_ZN4PLMD14GenericMolInfo16registerKeywordsERNS_8KeywordsE85
_ZN4PLMD14GenericMolInfo15interpretSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE617
_ZN4PLMD14GenericMolInfo7prepareEv5121
_ZNK4PLMD14GenericMolInfo14getResidueNameB5cxx11ENS_10AtomNumberE14769
_ZNK4PLMD14GenericMolInfo10getPDBsizeEv16599
_ZNK4PLMD14GenericMolInfo11getAtomNameB5cxx11ENS_10AtomNumberE32447
_ZNK4PLMD14GenericMolInfo16getResidueNumberENS_10AtomNumberE60821
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/GenericMolInfo.cpp.func.html b/coverage/core/GenericMolInfo.cpp.func.html new file mode 100644 index 0000000000..94dd59190c --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.func.html @@ -0,0 +1,141 @@ + + + + + + + + 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:15118581.6 %
Date:2024-06-10 08:19:14Functions:131776.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_EE617
_ZN4PLMD14GenericMolInfo16registerKeywordsERNS_8KeywordsE85
_ZN4PLMD14GenericMolInfo7prepareEv5121
_ZN4PLMD14GenericMolInfoC1ERKNS_13ActionOptionsE84
_ZN4PLMD14GenericMolInfoC2ERKNS_13ActionOptionsE0
_ZN4PLMD14GenericMolInfoD0Ev84
_ZN4PLMD14GenericMolInfoD1Ev84
_ZN4PLMD14GenericMolInfoD2Ev0
_ZNK4PLMD14GenericMolInfo10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD14GenericMolInfo10getPDBsizeEv16599
_ZNK4PLMD14GenericMolInfo11getAtomNameB5cxx11ENS_10AtomNumberE32447
_ZNK4PLMD14GenericMolInfo11getPositionENS_10AtomNumberE2
_ZNK4PLMD14GenericMolInfo12checkForAtomENS_10AtomNumberE4
_ZNK4PLMD14GenericMolInfo14getResidueNameB5cxx11ENS_10AtomNumberE14769
_ZNK4PLMD14GenericMolInfo16getResidueNumberENS_10AtomNumberE60821
_ZNK4PLMD14GenericMolInfo7isWholeEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/GenericMolInfo.cpp.gcov.html b/coverage/core/GenericMolInfo.cpp.gcov.html new file mode 100644 index 0000000000..8f47c54ec3 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.gcov.html @@ -0,0 +1,409 @@ + + + + + + + + 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:15118581.6 %
Date:2024-06-10 08:19:14Functions:131776.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 "GenericMolInfo.h"
+      23             : #include "Atoms.h"
+      24             : #include "ActionRegister.h"
+      25             : #include "ActionSet.h"
+      26             : #include "PlumedMain.h"
+      27             : #include "tools/MolDataClass.h"
+      28             : #include "tools/PDB.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          85 : void GenericMolInfo::registerKeywords( Keywords& keys ) {
+      42          85 :   ActionSetup::registerKeywords(keys);
+      43         170 :   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         170 :   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         170 :   keys.add("compulsory","PYTHON_BIN","default","python interpreter");
+      48         170 :   keys.add("atoms","CHAIN","(for masochists ( mostly Davide Branduardi ) ) The atoms involved in each of the chains of interest in the structure.");
+      49         170 :   keys.add("hidden","STRIDE","frequency for resetting the python interpreter. Should be 1.");
+      50         170 :   keys.addFlag("WHOLE", false, "The reference structure is whole, i.e. not broken by PBC");
+      51          85 : }
+      52             : 
+      53         168 : GenericMolInfo::~GenericMolInfo() {
+      54             : // empty destructor to delete unique_ptr
+      55         336 : }
+      56             : 
+      57          84 : GenericMolInfo::GenericMolInfo( const ActionOptions&ao ):
+      58             :   Action(ao),
+      59             :   ActionAnyorder(ao),
+      60             :   ActionPilot(ao),
+      61             :   ActionAtomistic(ao),
+      62          84 :   iswhole_(false)
+      63             : {
+      64          84 :   plumed_assert(getStride()==1);
+      65             :   // Read what is contained in the pdb file
+      66          84 :   parse("MOLTYPE",mytype);
+      67             : 
+      68             :   // check if whole
+      69          84 :   parseFlag("WHOLE", iswhole_);
+      70             : 
+      71          84 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      72          84 :   if( moldat ) log<<"  overriding last MOLINFO with label " << moldat->getLabel()<<"\n";
+      73             : 
+      74             :   std::vector<AtomNumber> backbone;
+      75         168 :   parseAtomList("CHAIN",backbone);
+      76          84 :   if( read_backbone.size()==0 ) {
+      77           0 :     for(unsigned i=1;; ++i) {
+      78         168 :       parseAtomList("CHAIN",i,backbone);
+      79          84 :       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          84 :   if( read_backbone.size()==0 ) {
+      87          84 :     parse("STRUCTURE",reference);
+      88             : 
+      89         168 :     if( ! pdb.read(reference,plumed.getAtoms().usingNaturalUnits(),0.1/plumed.getAtoms().getUnits().getLength()))plumed_merror("missing input file " + reference );
+      90             : 
+      91          84 :     std::vector<std::string> chains; pdb.getChainNames( chains );
+      92          84 :     log.printf("  pdb file named %s contains %u chains \n",reference.c_str(), static_cast<unsigned>(chains.size()));
+      93         242 :     for(unsigned i=0; i<chains.size(); ++i) {
+      94             :       unsigned start,end; std::string errmsg;
+      95         158 :       pdb.getResidueRange( chains[i], start, end, errmsg );
+      96         158 :       if( errmsg.length()!=0 ) error( errmsg );
+      97             :       AtomNumber astart,aend;
+      98         158 :       pdb.getAtomRange( chains[i], astart, aend, errmsg );
+      99         158 :       if( errmsg.length()!=0 ) error( errmsg );
+     100         158 :       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         168 :     parse("PYTHON_BIN",python_bin);
+     105          84 :     if(python_bin=="no") {
+     106           0 :       log<<"  python interpreter disabled\n";
+     107             :     } else {
+     108         168 :       pythonCmd=config::getEnvCommand();
+     109          84 :       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          84 :       const auto & at=pdb.getAtomNumbers();
+     115       89826 :       for(unsigned i=0; i<at.size(); i++) {
+     116       89742 :         if(at[i].index()!=i) sorted=false;
+     117             :       }
+     118          84 :       if(!sorted) {
+     119           1 :         log<<"  PDB is not sorted, python interpreter will be disabled\n";
+     120          83 :       } else if(!Subprocess::available()) {
+     121           0 :         log<<"  subprocess is not available, python interpreter will be disabled\n";
+     122             :       } else {
+     123          83 :         enablePythonInterpreter=true;
+     124             :       }
+     125             :     }
+     126          84 :   }
+     127          84 : }
+     128             : 
+     129          25 : void GenericMolInfo::getBackbone( std::vector<std::string>& restrings, const std::string& fortype, std::vector< std::vector<AtomNumber> >& backbone ) {
+     130          25 :   if( fortype!=mytype ) error("cannot calculate a variable designed for " + fortype + " molecules for molecule type " + mytype );
+     131          25 :   if( MolDataClass::numberOfAtomsPerResidueInBackbone( mytype )==0 ) error("backbone is not defined for molecule type " + mytype );
+     132             : 
+     133          25 :   if( read_backbone.size()!=0 ) {
+     134           0 :     if( restrings.size()!=1 ) error("cannot interpret anything other than all for residues when using CHAIN keywords");
+     135           0 :     if( restrings[0]!="all" ) error("cannot interpret anything other than all for residues when using CHAIN keywords");
+     136           0 :     backbone.resize( read_backbone.size() );
+     137           0 :     for(unsigned i=0; i<read_backbone.size(); ++i) {
+     138           0 :       backbone[i].resize( read_backbone[i].size() );
+     139           0 :       for(unsigned j=0; j<read_backbone[i].size(); ++j) backbone[i][j]=read_backbone[i][j];
+     140             :     }
+     141             :   } else {
+     142             :     bool useter=false; // This is used to deal with terminal groups in WHOLEMOLECULES
+     143          25 :     if( restrings.size()==1 ) {
+     144          23 :       useter=( restrings[0].find("ter")!=std::string::npos );
+     145          23 :       if( restrings[0].find("all")!=std::string::npos ) {
+     146          21 :         std::vector<std::string> chains; pdb.getChainNames( chains );
+     147         348 :         for(unsigned i=0; i<chains.size(); ++i) {
+     148             :           unsigned r_start, r_end; std::string errmsg, mm, nn;
+     149         327 :           pdb.getResidueRange( chains[i], r_start, r_end, errmsg );
+     150         327 :           if( !useter ) {
+     151         327 :             std::string resname = pdb.getResidueName( r_start );
+     152         327 :             if( MolDataClass::isTerminalGroup( mytype, resname ) ) r_start++;
+     153         327 :             resname = pdb.getResidueName( r_end );
+     154         327 :             if( MolDataClass::isTerminalGroup( mytype, resname ) ) r_end--;
+     155             :           }
+     156         327 :           Tools::convert(r_start,mm); Tools::convert(r_end,nn);
+     157         348 :           if(i==0) restrings[0] = mm + "-" + nn;
+     158         612 :           else restrings.push_back(  mm + "-" + nn );
+     159             :         }
+     160          21 :       }
+     161             :     }
+     162          25 :     Tools::interpretRanges(restrings);
+     163             : 
+     164             :     // Convert the list of involved residues into a list of segments of chains
+     165             :     int nk, nj; std::vector< std::vector<unsigned> > segments;
+     166             :     std::vector<unsigned> thissegment;
+     167          25 :     Tools::convert(restrings[0],nk); thissegment.push_back(nk);
+     168        2652 :     for(unsigned i=1; i<restrings.size(); ++i) {
+     169        2627 :       Tools::convert(restrings[i-1],nk);
+     170        2627 :       Tools::convert(restrings[i],nj);
+     171        7265 :       if( (nk+1)!=nj || pdb.getChainID(nk)!=pdb.getChainID(nj) ) {
+     172         308 :         segments.push_back(thissegment);
+     173         308 :         thissegment.resize(0);
+     174             :       }
+     175        2627 :       thissegment.push_back(nj);
+     176             :     }
+     177          25 :     segments.push_back( thissegment );
+     178             : 
+     179             :     // And now get the backbone atoms from each segment
+     180          25 :     backbone.resize( segments.size() );
+     181             :     std::vector<AtomNumber> atomnumbers;
+     182         358 :     for(unsigned i=0; i<segments.size(); ++i) {
+     183        2985 :       for(unsigned j=0; j<segments[i].size(); ++j) {
+     184        2652 :         std::string resname=pdb.getResidueName( segments[i][j] );
+     185        2652 :         if( !MolDataClass::allowedResidue(mytype, resname) ) {
+     186           0 :           std::string num; Tools::convert( segments[i][j], num );
+     187           0 :           error("residue " + num + " is not recognized for moltype " + mytype );
+     188             :         }
+     189        2652 :         if( !useter && MolDataClass::isTerminalGroup( mytype, resname ) ) {
+     190           0 :           std::string num; Tools::convert( segments[i][j], num );
+     191           0 :           error("residue " + num + " appears to be a terminal group");
+     192             :         }
+     193        2652 :         if( resname=="GLY" ) warning("GLY residues are achiral - assuming HA1 atom is in CB position");
+     194        2652 :         MolDataClass::getBackboneForResidue( mytype, segments[i][j], pdb, atomnumbers );
+     195        2652 :         if( atomnumbers.size()==0 ) {
+     196           0 :           std::string num; Tools::convert( segments[i][j], num );
+     197           0 :           error("Could not find required backbone atom in residue number " + num );
+     198             :         } else {
+     199       15912 :           for(unsigned k=0; k<atomnumbers.size(); ++k) backbone[i].push_back( atomnumbers[k] );
+     200             :         }
+     201        2652 :         atomnumbers.resize(0);
+     202             :       }
+     203             :     }
+     204          25 :   }
+     205          25 : }
+     206             : 
+     207         617 : void GenericMolInfo::interpretSymbol( const std::string& symbol, std::vector<AtomNumber>& atoms ) {
+     208        2414 :   if(Tools::startWith(symbol,"mdt:") || Tools::startWith(symbol,"mda:") || Tools::startWith(symbol,"vmd:") || Tools::startWith(symbol,"vmdexec:")) {
+     209             : 
+     210          24 :     plumed_assert(enablePythonInterpreter);
+     211             : 
+     212          48 :     log<<"  symbol " + symbol + " will be sent to python interpreter\n";
+     213          24 :     if(!selector_running) {
+     214           3 :       log<<"  MOLINFO "<<getLabel()<<": starting python interpreter\n";
+     215           3 :       if(comm.Get_rank()==0) {
+     216           8 :         selector=Tools::make_unique<Subprocess>(pythonCmd+" \""+config::getPlumedRoot()+"\"/scripts/selector.sh --pdb " + reference);
+     217           2 :         selector->stop();
+     218             :       }
+     219           3 :       selector_running=true;
+     220             :     }
+     221             : 
+     222          24 :     atoms.resize(0);
+     223             : 
+     224          24 :     if(comm.Get_rank()==0) {
+     225          16 :       int ok=0;
+     226             :       std::string error_msg;
+     227             :       // this is a complicated way to have the exception propagated with MPI.
+     228             :       // It is necessary since only one process calls the selector.
+     229             :       // Probably I should recycle the exception propagation at library boundaries
+     230             :       // to allow transferring the exception to other processes.
+     231             :       try {
+     232          16 :         plumed_assert(selector) << "Python interpreter is disabled, selection " + symbol + " cannot be interpreted";
+     233             :         auto h=selector->contStop(); // stops again when it goes out of scope
+     234          16 :         (*selector) << symbol << "\n";
+     235          16 :         selector->flush();
+     236             :         std::string res;
+     237             :         std::vector<std::string> words;
+     238             :         while(true) {
+     239          16 :           selector->getline(res);
+     240          32 :           words=Tools::getWords(res);
+     241          32 :           if(!words.empty() && words[0]=="Error") plumed_error()<<res;
+     242          32 :           if(!words.empty() && words[0]=="Selection:") break;
+     243             :         }
+     244             :         words.erase(words.begin());
+     245         712 :         for(auto & w : words) {
+     246             :           int n;
+     247         696 :           if(w.empty()) continue;
+     248         696 :           Tools::convert(w,n);
+     249        1392 :           atoms.push_back(AtomNumber::serial(n));
+     250             :         }
+     251          16 :         ok=1;
+     252          32 :       } catch (const Exception & e) {
+     253           0 :         error_msg=e.what();
+     254           0 :       }
+     255          16 :       comm.Bcast(ok,0);
+     256          16 :       if(!ok) {
+     257           0 :         size_t s=error_msg.length();
+     258           0 :         comm.Bcast(s,0);
+     259           0 :         comm.Bcast(error_msg,0);
+     260           0 :         throw Exception()<<error_msg;
+     261             :       }
+     262          16 :       size_t nat=atoms.size();
+     263          16 :       comm.Bcast(nat,0);
+     264          16 :       comm.Bcast(atoms,0);
+     265             :     } else {
+     266           8 :       int ok=0;
+     267             :       std::string error_msg;
+     268           8 :       comm.Bcast(ok,0);
+     269           8 :       if(!ok) {
+     270             :         size_t s;
+     271           0 :         comm.Bcast(s,0);
+     272           0 :         error_msg.resize(s);
+     273           0 :         comm.Bcast(error_msg,0);
+     274           0 :         throw Exception()<<error_msg;
+     275             :       }
+     276           8 :       size_t nat=0;
+     277           8 :       comm.Bcast(nat,0);
+     278           8 :       atoms.resize(nat);
+     279           8 :       comm.Bcast(atoms,0);
+     280             :     }
+     281          24 :     log<<"  selection interpreted using ";
+     282          60 :     if(Tools::startWith(symbol,"mdt:")) log<<"mdtraj "<<cite("McGibbon et al, Biophys. J., 109, 1528 (2015)")<<"\n";
+     283          84 :     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";
+     284          48 :     if(Tools::startWith(symbol,"vmdexec:")) log<<"VMD "<<cite("Humphrey, Dalke, and Schulten, K., J. Molec. Graphics, 14, 33 (1996)")<<"\n";
+     285          48 :     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";
+     286          24 :     return;
+     287             :   }
+     288         593 :   MolDataClass::specialSymbol( mytype, symbol, pdb, atoms );
+     289         593 :   if(atoms.empty()) error(symbol + " not found in your MOLINFO structure");
+     290             : }
+     291             : 
+     292       32447 : std::string GenericMolInfo::getAtomName(AtomNumber a)const {
+     293       32447 :   return pdb.getAtomName(a);
+     294             : }
+     295             : 
+     296           4 : bool GenericMolInfo::checkForAtom(AtomNumber a)const {
+     297           4 :   return pdb.checkForAtom(a);
+     298             : }
+     299             : 
+     300       60821 : unsigned GenericMolInfo::getResidueNumber(AtomNumber a)const {
+     301       60821 :   return pdb.getResidueNumber(a);
+     302             : }
+     303             : 
+     304       16599 : unsigned GenericMolInfo::getPDBsize()const {
+     305       16599 :   return pdb.size();
+     306             : }
+     307             : 
+     308       14769 : std::string GenericMolInfo::getResidueName(AtomNumber a)const {
+     309       14769 :   return pdb.getResidueName(a);
+     310             : }
+     311             : 
+     312           0 : std::string GenericMolInfo::getChainID(AtomNumber a)const {
+     313           0 :   return pdb.getChainID(a);
+     314             : }
+     315             : 
+     316           2 : Vector GenericMolInfo::getPosition(AtomNumber a)const {
+     317           2 :   return pdb.getPosition(a);
+     318             : }
+     319             : 
+     320           0 : bool GenericMolInfo::isWhole() const {
+     321           0 :   return iswhole_;
+     322             : }
+     323             : 
+     324        5121 : void GenericMolInfo::prepare() {
+     325        5121 :   if(selector_running) {
+     326           3 :     log<<"  MOLINFO "<<getLabel()<<": killing python interpreter\n";
+     327             :     selector.reset();
+     328           3 :     selector_running=false;
+     329             :   }
+     330        5121 : }
+     331             : 
+     332             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..1d506e465e --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo5applyEv5121
_ZN4PLMD14GenericMolInfo9calculateEv5121
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.func.html b/coverage/core/GenericMolInfo.h.func.html new file mode 100644 index 0000000000..77c74f3834 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo5applyEv5121
_ZN4PLMD14GenericMolInfo9calculateEv5121
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.gcov.html b/coverage/core/GenericMolInfo.h.gcov.html new file mode 100644 index 0000000000..8c2247c7dd --- /dev/null +++ b/coverage/core/GenericMolInfo.h.gcov.html @@ -0,0 +1,164 @@ + + + + + + + + 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-06-10 08:19:14Functions: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             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : class PDB;
+      37             : 
+      38             : class GenericMolInfo :
+      39             :   public ActionAnyorder,
+      40             :   public ActionPilot,
+      41             :   public ActionAtomistic {
+      42             : private:
+      43             :   ForwardDecl<PDB> pdb_fwd;
+      44             : /// A pdb file containing the topology
+      45             :   PDB& pdb=*pdb_fwd;
+      46             : /// The type of molecule in the pdb
+      47             :   std::string mytype;
+      48             : /// The name of the reference pdb file
+      49             :   std::string reference;
+      50             : /// The backbone that was read in from the pdb file
+      51             :   std::vector< std::vector<AtomNumber> > read_backbone;
+      52             : /// Python interpreter is enabled
+      53             :   bool enablePythonInterpreter=false;
+      54             : /// Python command
+      55             :   std::string pythonCmd;
+      56             : /// Selector subprocess
+      57             :   std::unique_ptr<Subprocess> selector;
+      58             : /// Track is selector is running
+      59             : /// Needed on Get_rank()>0
+      60             :   bool selector_running=false;
+      61             : /// Structure in pdb file is whole
+      62             :   bool iswhole_;
+      63             : public:
+      64             :   ~GenericMolInfo();
+      65        5121 :   void calculate() override {}
+      66        5121 :   void apply() override {}
+      67             :   static void registerKeywords( Keywords& keys );
+      68             :   explicit GenericMolInfo(const ActionOptions&ao);
+      69             :   void getBackbone( std::vector<std::string>& resstrings, const std::string& fortype, std::vector< std::vector<AtomNumber> >& backbone );
+      70             :   std::string getAtomName(AtomNumber a)const;
+      71             :   bool checkForAtom(AtomNumber a)const;
+      72             :   unsigned getResidueNumber(AtomNumber a)const;
+      73             :   std::string getChainID(AtomNumber a)const;
+      74             :   Vector getPosition(AtomNumber a)const;
+      75             :   bool isWhole() const;
+      76             :   unsigned getPDBsize()const ;
+      77             :   std::string getResidueName(AtomNumber a)const;
+      78             :   void interpretSymbol( const std::string& symbol, std::vector<AtomNumber>& atoms );
+      79             : /// Calculate is used to kill the python interpreter.
+      80             : /// We do this in order to avoid possible interference or slowing down of the simulation
+      81             : /// due to the extra subprocess.
+      82             :   void prepare() override;
+      83             : };
+      84             : 
+      85             : }
+      86             : 
+      87             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/MDAtoms.cpp.func-sort-c.html b/coverage/core/MDAtoms.cpp.func-sort-c.html new file mode 100644 index 0000000000..6b91a865ba --- /dev/null +++ b/coverage/core/MDAtoms.cpp.func-sort-c.html @@ -0,0 +1,317 @@ + + + + + + + + LCOV - plumed test coverage - core/MDAtoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - MDAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15817391.3 %
Date:2024-06-10 08:19:14Functions:306149.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MDAtomsTypedIfE10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD12MDAtomsTypedIfE10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE12updateForcesERKSt3setINS_10AtomNumberESt4lessIS3_ESaIS3_EERKSt6vectorIjSaIjEERKSA_INS_13VectorGenericILj3EEESaISG_EE0
_ZN4PLMD12MDAtomsTypedIfE12updateForcesERKSt6vectorIiSaIiEERKS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZN4PLMD12MDAtomsTypedIfE13rescaleForcesERKSt6vectorIiSaIiEEd0
_ZN4PLMD12MDAtomsTypedIfE15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd0
_ZN4PLMD12MDAtomsTypedIfE4setcERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE4setfERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE4setfERKNS_11TypesafePtrEi0
_ZN4PLMD12MDAtomsTypedIfE4setmERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE4setpERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE4setpERKNS_11TypesafePtrEi0
_ZN4PLMD12MDAtomsTypedIfE6setBoxERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE8setUnitsERKNS_5UnitsES4_0
_ZN4PLMD12MDAtomsTypedIfE9setVirialERKNS_11TypesafePtrE0
_ZN4PLMDL11getPointersIKfEEvRKNS_11TypesafePtrES4_S4_S4_jRPT_S7_S7_Rj0
_ZN4PLMDL11getPointersIfEEvRKNS_11TypesafePtrES3_S3_S3_jRPT_S6_S6_Rj0
_ZNK4PLMD12MDAtomsTypedIdE11getMDforcesEj0
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsERKSt6vectorIiSaIiEERS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZNK4PLMD12MDAtomsTypedIfE10getChargesERKSt6vectorIiSaIiEERS2_IdSaIdEE0
_ZNK4PLMD12MDAtomsTypedIfE11getMDforcesEj0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsERKSt3setINS_10AtomNumberESt4lessIS3_ESaIS3_EERKSt6vectorIjSaIjEERSA_INS_13VectorGenericILj3EEESaISG_EE0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsERKSt6vectorIiSaIiEERS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsEjjRSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZNK4PLMD12MDAtomsTypedIfE12updateVirialERKNS_13TensorGenericILj3ELj3EEE0
_ZNK4PLMD12MDAtomsTypedIfE16getRealPrecisionEv0
_ZNK4PLMD12MDAtomsTypedIfE17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZNK4PLMD12MDAtomsTypedIfE6getBoxERNS_13TensorGenericILj3ELj3EEE0
_ZNK4PLMD12MDAtomsTypedIfE9MD2doubleERKNS_11TypesafePtrERd0
_ZNK4PLMD12MDAtomsTypedIfE9getMassesERKSt6vectorIiSaIiEERS2_IdSaIdEE0
_ZNK4PLMD12MDAtomsTypedIfE9double2MDERKdRKNS_11TypesafePtrE1
_ZN4PLMD12MDAtomsTypedIdE4setfERKNS_11TypesafePtrEi3
_ZN4PLMD12MDAtomsTypedIdE4setpERKNS_11TypesafePtrEi3
_ZN4PLMD12MDAtomsTypedIdE10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE20
_ZN4PLMD12MDAtomsTypedIdE15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE20
_ZN4PLMD12MDAtomsTypedIdE18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd40
_ZN4PLMD12MDAtomsTypedIdE13rescaleForcesERKSt6vectorIiSaIiEEd50
_ZN4PLMD12MDAtomsTypedIdE10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE60
_ZNK4PLMD12MDAtomsTypedIdE17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE450
_ZNK4PLMD12MDAtomsTypedIdE10getChargesERKSt6vectorIiSaIiEERS2_IdSaIdEE784
_ZNK4PLMD12MDAtomsTypedIdE9getMassesERKSt6vectorIiSaIiEERS2_IdSaIdEE784
_ZN4PLMD12MDAtomsTypedIdE8setUnitsERKNS_5UnitsES4_933
_ZNK4PLMD12MDAtomsTypedIdE16getRealPrecisionEv1688
_ZN4PLMD12MDAtomsTypedIdE12updateForcesERKSt3setINS_10AtomNumberESt4lessIS3_ESaIS3_EERKSt6vectorIjSaIjEERKSA_INS_13VectorGenericILj3EEESaISG_EE2098
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsERKSt3setINS_10AtomNumberESt4lessIS3_ESaIS3_EERKSt6vectorIjSaIjEERSA_INS_13VectorGenericILj3EEESaISG_EE2212
_ZNK4PLMD12MDAtomsTypedIdE9double2MDERKdRKNS_11TypesafePtrE2364
_ZNK4PLMD12MDAtomsTypedIdE9MD2doubleERKNS_11TypesafePtrERd12830
_ZNK4PLMD12MDAtomsTypedIdE12updateVirialERKNS_13TensorGenericILj3ELj3EEE31465
_ZN4PLMD12MDAtomsTypedIdE4setcERKNS_11TypesafePtrE37570
_ZN4PLMD12MDAtomsTypedIdE9setVirialERKNS_11TypesafePtrE37675
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsEjjRSt6vectorINS_13VectorGenericILj3EEESaIS4_EE42702
_ZN4PLMD12MDAtomsTypedIdE6setBoxERKNS_11TypesafePtrE43333
_ZN4PLMD12MDAtomsTypedIdE12updateForcesERKSt6vectorIiSaIiEERKS2_INS_13VectorGenericILj3EEESaIS8_EE43934
_ZN4PLMDL11getPointersIKdEEvRKNS_11TypesafePtrES4_S4_S4_jRPT_S7_S7_Rj45364
_ZN4PLMDL11getPointersIdEEvRKNS_11TypesafePtrES3_S3_S3_jRPT_S6_S6_Rj46082
_ZN4PLMD12MDAtomsTypedIdE4setfERKNS_11TypesafePtrE47474
_ZN4PLMD12MDAtomsTypedIdE4setpERKNS_11TypesafePtrE47474
_ZN4PLMD12MDAtomsTypedIdE4setmERKNS_11TypesafePtrE47475
_ZNK4PLMD12MDAtomsTypedIdE6getBoxERNS_13TensorGenericILj3ELj3EEE89489
_ZN4PLMD11MDAtomsBase6createEj405175
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/MDAtoms.cpp.func.html b/coverage/core/MDAtoms.cpp.func.html new file mode 100644 index 0000000000..9084e06419 --- /dev/null +++ b/coverage/core/MDAtoms.cpp.func.html @@ -0,0 +1,317 @@ + + + + + + + + LCOV - plumed test coverage - core/MDAtoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - MDAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15817391.3 %
Date:2024-06-10 08:19:14Functions:306149.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11MDAtomsBase6createEj405175
_ZN4PLMD12MDAtomsTypedIdE10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE60
_ZN4PLMD12MDAtomsTypedIdE10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE20
_ZN4PLMD12MDAtomsTypedIdE12updateForcesERKSt3setINS_10AtomNumberESt4lessIS3_ESaIS3_EERKSt6vectorIjSaIjEERKSA_INS_13VectorGenericILj3EEESaISG_EE2098
_ZN4PLMD12MDAtomsTypedIdE12updateForcesERKSt6vectorIiSaIiEERKS2_INS_13VectorGenericILj3EEESaIS8_EE43934
_ZN4PLMD12MDAtomsTypedIdE13rescaleForcesERKSt6vectorIiSaIiEEd50
_ZN4PLMD12MDAtomsTypedIdE15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE20
_ZN4PLMD12MDAtomsTypedIdE18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd40
_ZN4PLMD12MDAtomsTypedIdE4setcERKNS_11TypesafePtrE37570
_ZN4PLMD12MDAtomsTypedIdE4setfERKNS_11TypesafePtrE47474
_ZN4PLMD12MDAtomsTypedIdE4setfERKNS_11TypesafePtrEi3
_ZN4PLMD12MDAtomsTypedIdE4setmERKNS_11TypesafePtrE47475
_ZN4PLMD12MDAtomsTypedIdE4setpERKNS_11TypesafePtrE47474
_ZN4PLMD12MDAtomsTypedIdE4setpERKNS_11TypesafePtrEi3
_ZN4PLMD12MDAtomsTypedIdE6setBoxERKNS_11TypesafePtrE43333
_ZN4PLMD12MDAtomsTypedIdE8setUnitsERKNS_5UnitsES4_933
_ZN4PLMD12MDAtomsTypedIdE9setVirialERKNS_11TypesafePtrE37675
_ZN4PLMD12MDAtomsTypedIfE10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD12MDAtomsTypedIfE10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE12updateForcesERKSt3setINS_10AtomNumberESt4lessIS3_ESaIS3_EERKSt6vectorIjSaIjEERKSA_INS_13VectorGenericILj3EEESaISG_EE0
_ZN4PLMD12MDAtomsTypedIfE12updateForcesERKSt6vectorIiSaIiEERKS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZN4PLMD12MDAtomsTypedIfE13rescaleForcesERKSt6vectorIiSaIiEEd0
_ZN4PLMD12MDAtomsTypedIfE15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd0
_ZN4PLMD12MDAtomsTypedIfE4setcERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE4setfERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE4setfERKNS_11TypesafePtrEi0
_ZN4PLMD12MDAtomsTypedIfE4setmERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE4setpERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE4setpERKNS_11TypesafePtrEi0
_ZN4PLMD12MDAtomsTypedIfE6setBoxERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE8setUnitsERKNS_5UnitsES4_0
_ZN4PLMD12MDAtomsTypedIfE9setVirialERKNS_11TypesafePtrE0
_ZN4PLMDL11getPointersIKdEEvRKNS_11TypesafePtrES4_S4_S4_jRPT_S7_S7_Rj45364
_ZN4PLMDL11getPointersIKfEEvRKNS_11TypesafePtrES4_S4_S4_jRPT_S7_S7_Rj0
_ZN4PLMDL11getPointersIdEEvRKNS_11TypesafePtrES3_S3_S3_jRPT_S6_S6_Rj46082
_ZN4PLMDL11getPointersIfEEvRKNS_11TypesafePtrES3_S3_S3_jRPT_S6_S6_Rj0
_ZNK4PLMD12MDAtomsTypedIdE10getChargesERKSt6vectorIiSaIiEERS2_IdSaIdEE784
_ZNK4PLMD12MDAtomsTypedIdE11getMDforcesEj0
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsERKSt3setINS_10AtomNumberESt4lessIS3_ESaIS3_EERKSt6vectorIjSaIjEERSA_INS_13VectorGenericILj3EEESaISG_EE2212
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsERKSt6vectorIiSaIiEERS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsEjjRSt6vectorINS_13VectorGenericILj3EEESaIS4_EE42702
_ZNK4PLMD12MDAtomsTypedIdE12updateVirialERKNS_13TensorGenericILj3ELj3EEE31465
_ZNK4PLMD12MDAtomsTypedIdE16getRealPrecisionEv1688
_ZNK4PLMD12MDAtomsTypedIdE17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE450
_ZNK4PLMD12MDAtomsTypedIdE6getBoxERNS_13TensorGenericILj3ELj3EEE89489
_ZNK4PLMD12MDAtomsTypedIdE9MD2doubleERKNS_11TypesafePtrERd12830
_ZNK4PLMD12MDAtomsTypedIdE9double2MDERKdRKNS_11TypesafePtrE2364
_ZNK4PLMD12MDAtomsTypedIdE9getMassesERKSt6vectorIiSaIiEERS2_IdSaIdEE784
_ZNK4PLMD12MDAtomsTypedIfE10getChargesERKSt6vectorIiSaIiEERS2_IdSaIdEE0
_ZNK4PLMD12MDAtomsTypedIfE11getMDforcesEj0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsERKSt3setINS_10AtomNumberESt4lessIS3_ESaIS3_EERKSt6vectorIjSaIjEERSA_INS_13VectorGenericILj3EEESaISG_EE0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsERKSt6vectorIiSaIiEERS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsEjjRSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZNK4PLMD12MDAtomsTypedIfE12updateVirialERKNS_13TensorGenericILj3ELj3EEE0
_ZNK4PLMD12MDAtomsTypedIfE16getRealPrecisionEv0
_ZNK4PLMD12MDAtomsTypedIfE17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZNK4PLMD12MDAtomsTypedIfE6getBoxERNS_13TensorGenericILj3ELj3EEE0
_ZNK4PLMD12MDAtomsTypedIfE9MD2doubleERKNS_11TypesafePtrERd0
_ZNK4PLMD12MDAtomsTypedIfE9double2MDERKdRKNS_11TypesafePtrE1
_ZNK4PLMD12MDAtomsTypedIfE9getMassesERKSt6vectorIiSaIiEERS2_IdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/MDAtoms.cpp.gcov.html b/coverage/core/MDAtoms.cpp.gcov.html new file mode 100644 index 0000000000..75ef7de005 --- /dev/null +++ b/coverage/core/MDAtoms.cpp.gcov.html @@ -0,0 +1,464 @@ + + + + + + + + LCOV - plumed test coverage - core/MDAtoms.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - MDAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15817391.3 %
Date:2024-06-10 08:19:14Functions:306149.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             : #include "MDAtoms.h"
+      23             : #include "tools/Tools.h"
+      24             : #include "tools/OpenMP.h"
+      25             : #include "tools/Exception.h"
+      26             : #include "tools/Units.h"
+      27             : #include <algorithm>
+      28             : #include <string>
+      29             : #include <map>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : template<typename T>
+      34       91446 : static void getPointers(const TypesafePtr & p,const TypesafePtr & px,const TypesafePtr & py,const TypesafePtr & pz,unsigned maxel,T*&ppx,T*&ppy,T*&ppz,unsigned & stride) {
+      35       91446 :   if(p) {
+      36       91408 :     auto p_=p.get<T*>({maxel,3});
+      37       91408 :     ppx=p_;
+      38       91408 :     ppy=p_+1;
+      39       91408 :     ppz=p_+2;
+      40       91408 :     stride=3;
+      41          38 :   } else if(px && py && pz) {
+      42           2 :     ppx=px.get<T*>(maxel);
+      43           2 :     ppy=py.get<T*>(maxel);
+      44           2 :     ppz=pz.get<T*>(maxel);
+      45           2 :     stride=1;
+      46             :   } else {
+      47          36 :     ppx=nullptr;
+      48          36 :     ppy=nullptr;
+      49          36 :     ppz=nullptr;
+      50          36 :     stride=0;
+      51             :   }
+      52       91446 : }
+      53             : 
+      54             : /// Class containing the pointers to the MD data
+      55             : /// It is templated so that single and double precision versions coexist
+      56             : /// IT IS STILL UNDOCUMENTED. IT PROBABLY NEEDS A STRONG CLEANUP
+      57             : template <class T>
+      58             : class MDAtomsTyped:
+      59             :   public MDAtomsBase
+      60             : {
+      61             :   T scalep=1.0; // factor to scale positions
+      62             :   T scalef=1.0; // factor to scale forces
+      63             :   T scaleb=1.0; // factor to scale box
+      64             :   T scalev=1.0; // factor to scale virial
+      65             :   T scalec=1.0; // factor to scale charges
+      66             :   T scalem=1.0; // factor to scale masses
+      67             :   TypesafePtr m;
+      68             :   TypesafePtr c;
+      69             :   TypesafePtr p;
+      70             :   TypesafePtr px,py,pz;
+      71             :   TypesafePtr f;
+      72             :   TypesafePtr fx,fy,fz;
+      73             :   TypesafePtr box;
+      74             :   TypesafePtr virial;
+      75             :   std::map<std::string,TypesafePtr> extraCV;
+      76             :   std::map<std::string,TypesafePtr> extraCVForce;
+      77             : public:
+      78             :   void setm(const TypesafePtr & m) override;
+      79             :   void setc(const TypesafePtr & m) override;
+      80             :   void setBox(const TypesafePtr & ) override;
+      81             :   void setp(const TypesafePtr & p) override;
+      82             :   void setVirial(const TypesafePtr & ) override;
+      83             :   void setf(const TypesafePtr & f) override;
+      84             :   void setp(const TypesafePtr & p,int i) override;
+      85             :   void setf(const TypesafePtr & f,int i) override;
+      86             :   void setUnits(const Units&,const Units&) override;
+      87          20 :   void setExtraCV(const std::string &name,const TypesafePtr & p) override {
+      88          20 :     p.get<T>(); // just check type and discard pointer
+      89          20 :     extraCV[name]=p.copy();
+      90          20 :   }
+      91          20 :   void setExtraCVForce(const std::string &name,const TypesafePtr & p) override {
+      92          20 :     p.get<T*>(); // just check type and discard pointer
+      93          20 :     extraCVForce[name]=p.copy();
+      94          20 :   }
+      95          60 :   double getExtraCV(const std::string &name) override {
+      96             :     auto search=extraCV.find(name);
+      97          60 :     if(search != extraCV.end()) {
+      98          60 :       return static_cast<double>(search->second.template get<T>());
+      99             :     } else {
+     100           0 :       plumed_error() << "Unable to access extra cv named '" << name << "'.\nNotice that extra cvs need to be calculated in the MD code.";
+     101             :     }
+     102             :   }
+     103          40 :   void updateExtraCVForce(const std::string &name,double f) override {
+     104          40 :     *extraCVForce[name].template get<T*>()+=static_cast<T>(f);
+     105          40 :   }
+     106       12830 :   void MD2double(const TypesafePtr & m,double&d)const override {
+     107       12830 :     d=double(m.template get<T>());
+     108       12830 :   }
+     109        2365 :   void double2MD(const double&d,const TypesafePtr & m)const override {
+     110        2365 :     m.set(T(d));
+     111        2365 :   }
+     112           0 :   Vector getMDforces(const unsigned index)const override {
+     113             :     unsigned stride;
+     114             :     const T* ffx;
+     115             :     const T* ffy;
+     116             :     const T* ffz;
+     117             :     // node: index+1 because we are supposed to pass here the size of the array, which should be at least the element we are asking for + 1
+     118           0 :     getPointers(f,fx,fy,fz,index+1,ffx,ffy,ffz,stride);
+     119           0 :     Vector force(ffx[stride*index],ffy[stride*index],ffz[stride*index]);
+     120           0 :     return force/scalef;
+     121             :   }
+     122             :   void getBox(Tensor &) const override;
+     123             :   void getPositions(const std::vector<int>&index,std::vector<Vector>&positions) const override;
+     124             :   void getPositions(const std::set<AtomNumber>&index,const std::vector<unsigned>&i,std::vector<Vector>&positions) const override;
+     125             :   void getPositions(unsigned j,unsigned k,std::vector<Vector>&positions) const override;
+     126             :   void getLocalPositions(std::vector<Vector>&p) const override;
+     127             :   void getMasses(const std::vector<int>&index,std::vector<double>&) const override;
+     128             :   void getCharges(const std::vector<int>&index,std::vector<double>&) const override;
+     129             :   void updateVirial(const Tensor&) const override;
+     130             :   void updateForces(const std::vector<int>&index,const std::vector<Vector>&) override;
+     131             :   void updateForces(const std::set<AtomNumber>&index,const std::vector<unsigned>&i,const std::vector<Vector>&forces) override;
+     132             :   void rescaleForces(const std::vector<int>&index,double factor) override;
+     133             :   unsigned  getRealPrecision()const override;
+     134             : };
+     135             : 
+     136             : template <class T>
+     137         933 : void MDAtomsTyped<T>::setUnits(const Units& units,const Units& MDUnits) {
+     138         933 :   double lscale=units.getLength()/MDUnits.getLength();
+     139         933 :   double escale=units.getEnergy()/MDUnits.getEnergy();
+     140         933 :   double cscale=units.getCharge()/MDUnits.getCharge();
+     141         933 :   double mscale=units.getMass()/MDUnits.getMass();
+     142             : // scalep and scaleb are used to convert MD to plumed
+     143         933 :   scalep=1.0/lscale;
+     144         933 :   scaleb=1.0/lscale;
+     145             : // scalef and scalev are used to convert plumed to MD
+     146         933 :   scalef=escale/lscale;
+     147         933 :   scalev=escale;
+     148         933 :   scalec=1.0/cscale;
+     149         933 :   scalem=1.0/mscale;
+     150         933 : }
+     151             : 
+     152             : template <class T>
+     153       89489 : void MDAtomsTyped<T>::getBox(Tensor&box)const {
+     154       89489 :   auto b=this->box.template get<const T*>({3,3});
+     155     1114853 :   if(b) for(int i=0; i<3; i++)for(int j=0; j<3; j++) box(i,j)=b[3*i+j]*scaleb;
+     156        4042 :   else box.zero();
+     157       89489 : }
+     158             : 
+     159             : template <class T>
+     160           0 : void MDAtomsTyped<T>::getPositions(const std::vector<int>&index,std::vector<Vector>&positions)const {
+     161             :   unsigned stride;
+     162             :   const T* ppx;
+     163             :   const T* ppy;
+     164             :   const T* ppz;
+     165           0 :   getPointers(p,px,py,pz,index.size(),ppx,ppy,ppz,stride);
+     166           0 :   plumed_assert(index.size()==0 || (ppx && ppy && ppz));
+     167             : // cannot be parallelized with omp because access to positions is not ordered
+     168           0 :   for(unsigned i=0; i<index.size(); ++i) {
+     169           0 :     positions[index[i]][0]=ppx[stride*i]*scalep;
+     170           0 :     positions[index[i]][1]=ppy[stride*i]*scalep;
+     171           0 :     positions[index[i]][2]=ppz[stride*i]*scalep;
+     172             :   }
+     173           0 : }
+     174             : 
+     175             : template <class T>
+     176        2212 : void MDAtomsTyped<T>::getPositions(const std::set<AtomNumber>&index,const std::vector<unsigned>&i, std::vector<Vector>&positions)const {
+     177             :   unsigned stride;
+     178             :   const T* ppx;
+     179             :   const T* ppy;
+     180             :   const T* ppz;
+     181             : #ifndef NDEBUG
+     182             : // bounds are only checked in debug mode since they require this extra step that is potentially expensive
+     183             :   const unsigned maxel=(i.size()>0?*std::max_element(i.begin(),i.end())+1:0);
+     184             : #else
+     185             :   const unsigned maxel=0;
+     186             : #endif
+     187        2212 :   getPointers(p,px,py,pz,maxel,ppx,ppy,ppz,stride);
+     188        2212 :   plumed_assert(index.size()==0 || (ppx && ppy && ppz));
+     189             : // cannot be parallelized with omp because access to positions is not ordered
+     190             :   unsigned k=0;
+     191       33181 :   for(const auto & p : index) {
+     192       30969 :     positions[p.index()][0]=ppx[stride*i[k]]*scalep;
+     193       30969 :     positions[p.index()][1]=ppy[stride*i[k]]*scalep;
+     194       30969 :     positions[p.index()][2]=ppz[stride*i[k]]*scalep;
+     195       30969 :     k++;
+     196             :   }
+     197        2212 : }
+     198             : 
+     199             : template <class T>
+     200       42702 : void MDAtomsTyped<T>::getPositions(unsigned j,unsigned k,std::vector<Vector>&positions)const {
+     201             :   unsigned stride;
+     202             :   const T* ppx;
+     203             :   const T* ppy;
+     204             :   const T* ppz;
+     205       42702 :   getPointers(p,px,py,pz,k,ppx,ppy,ppz,stride);
+     206       42702 :   plumed_assert(k==j || (ppx && ppy && ppz));
+     207       42702 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(&positions[j],(k-j)))
+     208             :   for(unsigned i=j; i<k; ++i) {
+     209             :     positions[i][0]=ppx[stride*i]*scalep;
+     210             :     positions[i][1]=ppy[stride*i]*scalep;
+     211             :     positions[i][2]=ppz[stride*i]*scalep;
+     212             :   }
+     213       42702 : }
+     214             : 
+     215             : 
+     216             : template <class T>
+     217         450 : void MDAtomsTyped<T>::getLocalPositions(std::vector<Vector>&positions)const {
+     218             :   unsigned stride;
+     219             :   const T* ppx;
+     220             :   const T* ppy;
+     221             :   const T* ppz;
+     222         450 :   getPointers(p,px,py,pz,positions.size(),ppx,ppy,ppz,stride);
+     223         450 :   plumed_assert(positions.size()==0 || (ppx && ppy && ppz));
+     224         450 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(positions))
+     225             :   for(unsigned i=0; i<positions.size(); ++i) {
+     226             :     positions[i][0]=ppx[stride*i]*scalep;
+     227             :     positions[i][1]=ppy[stride*i]*scalep;
+     228             :     positions[i][2]=ppz[stride*i]*scalep;
+     229             :   }
+     230         450 : }
+     231             : 
+     232             : 
+     233             : template <class T>
+     234         784 : void MDAtomsTyped<T>::getMasses(const std::vector<int>&index,std::vector<double>&masses)const {
+     235         784 :   auto mm=m.get<const T*>(index.size());
+     236      480945 :   if(mm) for(unsigned i=0; i<index.size(); ++i) masses[index[i]]=scalem*mm[i];
+     237           0 :   else  for(unsigned i=0; i<index.size(); ++i) masses[index[i]]=0.0;
+     238         784 : }
+     239             : 
+     240             : template <class T>
+     241         784 : void MDAtomsTyped<T>::getCharges(const std::vector<int>&index,std::vector<double>&charges)const {
+     242         784 :   auto cc=c.get<const T*>(index.size());
+     243      479358 :   if(cc) for(unsigned i=0; i<index.size(); ++i) charges[index[i]]=scalec*cc[i];
+     244        1587 :   else  for(unsigned i=0; i<index.size(); ++i) charges[index[i]]=0.0;
+     245         784 : }
+     246             : 
+     247             : template <class T>
+     248       31465 : void MDAtomsTyped<T>::updateVirial(const Tensor&virial)const {
+     249       31465 :   auto v=this->virial.template get<T*>({3,3});
+     250      409045 :   if(v) for(int i=0; i<3; i++)for(int j=0; j<3; j++) v[3*i+j]+=T(virial(i,j)*scalev);
+     251       31465 : }
+     252             : 
+     253             : template <class T>
+     254        2098 : void MDAtomsTyped<T>::updateForces(const std::set<AtomNumber>&index,const std::vector<unsigned>&i,const std::vector<Vector>&forces) {
+     255             :   unsigned stride;
+     256             :   T* ffx;
+     257             :   T* ffy;
+     258             :   T* ffz;
+     259             : #ifndef NDEBUG
+     260             : // bounds are only checked in debug mode since they require this extra step that is potentially expensive
+     261             :   const unsigned maxel=(i.size()>0?*std::max_element(i.begin(),i.end())+1:0);
+     262             : #else
+     263             :   const unsigned maxel=0;
+     264             : #endif
+     265        2098 :   getPointers(f,fx,fy,fz,maxel,ffx,ffy,ffz,stride);
+     266        2098 :   plumed_assert(index.size()==0 || (ffx && ffy && ffz));
+     267             :   unsigned k=0;
+     268       27541 :   for(const auto & p : index) {
+     269       25443 :     ffx[stride*i[k]]+=scalef*T(forces[p.index()][0]);
+     270       25443 :     ffy[stride*i[k]]+=scalef*T(forces[p.index()][1]);
+     271       25443 :     ffz[stride*i[k]]+=scalef*T(forces[p.index()][2]);
+     272       25443 :     k++;
+     273             :   }
+     274        2098 : }
+     275             : 
+     276             : template <class T>
+     277       43934 : void MDAtomsTyped<T>::updateForces(const std::vector<int>&index,const std::vector<Vector>&forces) {
+     278             :   unsigned stride;
+     279             :   T* ffx;
+     280             :   T* ffy;
+     281             :   T* ffz;
+     282       43934 :   getPointers(f,fx,fy,fz,index.size(),ffx,ffy,ffz,stride);
+     283       43934 :   plumed_assert(index.size()==0 || (ffx && ffy && ffz));
+     284       43934 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(ffx,stride*index.size()))
+     285             :   for(unsigned i=0; i<index.size(); ++i) {
+     286             :     ffx[stride*i]+=scalef*T(forces[index[i]][0]);
+     287             :     ffy[stride*i]+=scalef*T(forces[index[i]][1]);
+     288             :     ffz[stride*i]+=scalef*T(forces[index[i]][2]);
+     289             :   }
+     290       43934 : }
+     291             : 
+     292             : template <class T>
+     293          50 : void MDAtomsTyped<T>::rescaleForces(const std::vector<int>&index,double factor) {
+     294             :   unsigned stride;
+     295             :   T* ffx;
+     296             :   T* ffy;
+     297             :   T* ffz;
+     298          50 :   getPointers(f,fx,fy,fz,index.size(),ffx,ffy,ffz,stride);
+     299          50 :   plumed_assert(index.size()==0 || (ffx && ffy && ffz));
+     300          50 :   auto v=virial.get<T*>({3,3});
+     301          50 :   if(v) for(unsigned i=0; i<3; i++)for(unsigned j=0; j<3; j++) v[3*i+j]*=T(factor);
+     302          50 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(ffx,stride*index.size()))
+     303             :   for(unsigned i=0; i<index.size(); ++i) {
+     304             :     ffx[stride*i]*=T(factor);
+     305             :     ffy[stride*i]*=T(factor);
+     306             :     ffz[stride*i]*=T(factor);
+     307             :   }
+     308          50 : }
+     309             : 
+     310             : template <class T>
+     311        1688 : unsigned MDAtomsTyped<T>::getRealPrecision()const {
+     312        1688 :   return sizeof(T);
+     313             : }
+     314             : 
+     315             : template <class T>
+     316       47474 : void MDAtomsTyped<T>::setp(const TypesafePtr & pp) {
+     317       47474 :   pp.get<const T*>(); // just check type and discard pointer
+     318       47474 :   p=pp.copy();
+     319       47474 :   px=TypesafePtr();
+     320       47474 :   py=TypesafePtr();
+     321       47474 :   pz=TypesafePtr();
+     322       47474 : }
+     323             : 
+     324             : template <class T>
+     325       43333 : void MDAtomsTyped<T>::setBox(const TypesafePtr & pp) {
+     326       43333 :   pp.get<const T*>({3,3}); // just check type and size and discard pointer
+     327       43333 :   box=pp.copy();
+     328       43333 : }
+     329             : 
+     330             : 
+     331             : template <class T>
+     332       47474 : void MDAtomsTyped<T>::setf(const TypesafePtr & ff) {
+     333       47474 :   ff.get<T*>(); // just check type and discard pointer
+     334       47474 :   f=ff.copy();
+     335       47474 :   fx=TypesafePtr();
+     336       47474 :   fy=TypesafePtr();
+     337       47474 :   fz=TypesafePtr();
+     338       47474 : }
+     339             : 
+     340             : template <class T>
+     341           3 : void MDAtomsTyped<T>::setp(const TypesafePtr & pp,int i) {
+     342           3 :   p=TypesafePtr();
+     343           3 :   pp.get<const T*>(); // just check type and discard pointer
+     344           3 :   if(i==0)px=pp.copy();
+     345           3 :   if(i==1)py=pp.copy();
+     346           3 :   if(i==2)pz=pp.copy();
+     347           3 : }
+     348             : 
+     349             : template <class T>
+     350       37675 : void MDAtomsTyped<T>::setVirial(const TypesafePtr & pp) {
+     351       37675 :   pp.get<T*>({3,3}); // just check type and size and discard pointer
+     352       37673 :   virial=pp.copy();
+     353       37673 : }
+     354             : 
+     355             : 
+     356             : template <class T>
+     357           3 : void MDAtomsTyped<T>::setf(const TypesafePtr & ff,int i) {
+     358           3 :   f=TypesafePtr();;
+     359           3 :   ff.get<T*>(); // just check type and discard pointer
+     360           3 :   if(i==0)fx=ff.copy();
+     361           3 :   if(i==1)fy=ff.copy();
+     362           3 :   if(i==2)fz=ff.copy();
+     363           3 : }
+     364             : 
+     365             : template <class T>
+     366       47475 : void MDAtomsTyped<T>::setm(const TypesafePtr & m) {
+     367       47475 :   m.get<const T*>(); // just check type and discard pointer
+     368       47475 :   this->m=m.copy();
+     369       47475 : }
+     370             : 
+     371             : template <class T>
+     372       37570 : void MDAtomsTyped<T>::setc(const TypesafePtr & c) {
+     373       37570 :   c.get<const T*>(); // just check type and discard pointer
+     374       37570 :   this->c=c.copy();
+     375       37570 : }
+     376             : 
+     377      405175 : std::unique_ptr<MDAtomsBase> MDAtomsBase::create(unsigned p) {
+     378      405175 :   if(p==sizeof(double)) {
+     379      405174 :     return Tools::make_unique<MDAtomsTyped<double>>();
+     380           1 :   } else if (p==sizeof(float)) {
+     381           1 :     return Tools::make_unique<MDAtomsTyped<float>>();
+     382             :   }
+     383           0 :   plumed_error() << "Cannot create an MD interface with sizeof(real)==" << p;
+     384             : }
+     385             : 
+     386             : }
+     387             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..cf044261c3 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + 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:59765790.9 %
Date:2024-06-10 08:19:14Functions:343694.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10PlumedMain4exitEi0
_ZN4PLMD10PlumedMain9justApplyEv0
_ZN4PLMD10PlumedMain14readInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD10PlumedMain4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD10PlumedMain19performCalcNoForcesEv10
_ZN4PLMDL9testThrowEPKc26
_ZN4PLMD10PlumedMain4stopEv65
_ZN4PLMD10PlumedMain5fopenEPKcS2_73
_ZN4PLMD10PlumedMain6fcloseEP8_IO_FILE91
_ZN4PLMD10PlumedMain13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE353
_ZNK4PLMD10PlumedMain7getWorkEv450
_ZN4PLMD10PlumedMain25runJobsAtEndOfCalculationEv721
_ZN4PLMD10PlumedMain13readInputFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE791
_ZN4PLMD10PlumedMain13readInputFileERNS_5IFileE792
_ZN4PLMD10PlumedMain4initEv914
_ZN4PLMD10PlumedMain6fflushEv1447
_ZN4PLMD10PlumedMain19performCalcNoUpdateEv2134
_ZNK4PLMD10PlumedMain7getBiasEv2805
_ZN4PLMD10PlumedMain4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3576
_ZN4PLMD10PlumedMain10insertFileERNS_8FileBaseE4317
_ZN4PLMD10PlumedMain9eraseFileERNS_8FileBaseE4607
_ZN4PLMD10PlumedMain6getLogEv14105
_ZN4PLMD10PlumedMain14readInputWordsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE14110
_ZN4PLMD10PlumedMain4calcEv245716
_ZN4PLMD10PlumedMain11performCalcEv245726
_ZN4PLMD10PlumedMain6updateEv245805
_ZN4PLMD10PlumedMain11prepareCalcEv247786
_ZN4PLMD10PlumedMain17backwardPropagateEv247860
_ZN4PLMD10PlumedMain9shareDataEv247870
_ZN4PLMD10PlumedMain13justCalculateEv247984
_ZN4PLMD10PlumedMain8waitDataEv247984
_ZN4PLMD10PlumedMain19prepareDependenciesEv248113
_ZN4PLMD10PlumedMainD0Ev403674
_ZN4PLMD10PlumedMainC2Ev404395
_ZN4PLMD10PlumedMainD2Ev404395
_ZN4PLMD10PlumedMain3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1040740
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/PlumedMain.cpp.func.html b/coverage/core/PlumedMain.cpp.func.html new file mode 100644 index 0000000000..983c085998 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + 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:59765790.9 %
Date:2024-06-10 08:19:14Functions:343694.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10PlumedMain10insertFileERNS_8FileBaseE4317
_ZN4PLMD10PlumedMain11performCalcEv245726
_ZN4PLMD10PlumedMain11prepareCalcEv247786
_ZN4PLMD10PlumedMain13justCalculateEv247984
_ZN4PLMD10PlumedMain13readInputFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE791
_ZN4PLMD10PlumedMain13readInputFileERNS_5IFileE792
_ZN4PLMD10PlumedMain13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE353
_ZN4PLMD10PlumedMain14readInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD10PlumedMain14readInputWordsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE14110
_ZN4PLMD10PlumedMain17backwardPropagateEv247860
_ZN4PLMD10PlumedMain19performCalcNoForcesEv10
_ZN4PLMD10PlumedMain19performCalcNoUpdateEv2134
_ZN4PLMD10PlumedMain19prepareDependenciesEv248113
_ZN4PLMD10PlumedMain25runJobsAtEndOfCalculationEv721
_ZN4PLMD10PlumedMain3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1040740
_ZN4PLMD10PlumedMain4calcEv245716
_ZN4PLMD10PlumedMain4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3576
_ZN4PLMD10PlumedMain4exitEi0
_ZN4PLMD10PlumedMain4initEv914
_ZN4PLMD10PlumedMain4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD10PlumedMain4stopEv65
_ZN4PLMD10PlumedMain5fopenEPKcS2_73
_ZN4PLMD10PlumedMain6fcloseEP8_IO_FILE91
_ZN4PLMD10PlumedMain6fflushEv1447
_ZN4PLMD10PlumedMain6getLogEv14105
_ZN4PLMD10PlumedMain6updateEv245805
_ZN4PLMD10PlumedMain8waitDataEv247984
_ZN4PLMD10PlumedMain9eraseFileERNS_8FileBaseE4607
_ZN4PLMD10PlumedMain9justApplyEv0
_ZN4PLMD10PlumedMain9shareDataEv247870
_ZN4PLMD10PlumedMainC2Ev404395
_ZN4PLMD10PlumedMainD0Ev403674
_ZN4PLMD10PlumedMainD2Ev404395
_ZN4PLMDL9testThrowEPKc26
_ZNK4PLMD10PlumedMain7getBiasEv2805
_ZNK4PLMD10PlumedMain7getWorkEv450
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/PlumedMain.cpp.gcov.html b/coverage/core/PlumedMain.cpp.gcov.html new file mode 100644 index 0000000000..129e08ebc6 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.gcov.html @@ -0,0 +1,1140 @@ + + + + + + + + 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:59765790.9 %
Date:2024-06-10 08:19:14Functions:343694.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             : #include "PlumedMain.h"
+      23             : #include "ActionAtomistic.h"
+      24             : #include "ActionPilot.h"
+      25             : #include "ActionRegister.h"
+      26             : #include "ActionSet.h"
+      27             : #include "ActionWithValue.h"
+      28             : #include "ActionWithVirtualAtom.h"
+      29             : #include "Atoms.h"
+      30             : #include "CLToolMain.h"
+      31             : #include "ExchangePatterns.h"
+      32             : #include "GREX.h"
+      33             : #include "config/Config.h"
+      34             : #include "tools/Citations.h"
+      35             : #include "tools/Communicator.h"
+      36             : #include "tools/DLLoader.h"
+      37             : #include "tools/Exception.h"
+      38             : #include "tools/IFile.h"
+      39             : #include "tools/Log.h"
+      40             : #include "tools/OpenMP.h"
+      41             : #include "tools/Tools.h"
+      42             : #include "tools/Stopwatch.h"
+      43             : #include "tools/TypesafePtr.h"
+      44             : #include "lepton/Exception.h"
+      45             : #include "DataFetchingObject.h"
+      46             : #include <cstdlib>
+      47             : #include <cstdio>
+      48             : #include <cstring>
+      49             : #include <set>
+      50             : #include <unordered_map>
+      51             : #include <exception>
+      52             : #include <stdexcept>
+      53             : #include <ios>
+      54             : #include <new>
+      55             : #include <typeinfo>
+      56             : #include <iostream>
+      57             : #include <algorithm>
+      58             : #ifdef __PLUMED_LIBCXX11
+      59             : #include <system_error>
+      60             : #include <future>
+      61             : #include <memory>
+      62             : #include <functional>
+      63             : #endif
+      64             : 
+      65             : 
+      66             : namespace PLMD {
+      67             : 
+      68             : /// Small utility just used in this file to throw arbitrary exceptions
+      69          26 : [[noreturn]] static void testThrow(const char* what) {
+      70          52 :   auto words=Tools::getWords(what);
+      71          26 :   plumed_assert(words.size()>0);
+      72             : #define __PLUMED_THROW_NOMSG(type) if(words[0]==#type) throw type()
+      73             : #define __PLUMED_THROW_MSG(type) if(words[0]==#type) throw type(what)
+      74          27 :   __PLUMED_THROW_MSG(PLMD::ExceptionError);
+      75          26 :   __PLUMED_THROW_MSG(PLMD::ExceptionDebug);
+      76          25 :   __PLUMED_THROW_MSG(PLMD::Exception);
+      77          24 :   __PLUMED_THROW_MSG(PLMD::lepton::Exception);
+      78          22 :   __PLUMED_THROW_NOMSG(std::bad_exception);
+      79             : #ifdef __PLUMED_LIBCXX11
+      80          21 :   __PLUMED_THROW_NOMSG(std::bad_array_new_length);
+      81             : #endif
+      82          20 :   __PLUMED_THROW_NOMSG(std::bad_alloc);
+      83             : #ifdef __PLUMED_LIBCXX11
+      84          19 :   __PLUMED_THROW_NOMSG(std::bad_function_call);
+      85          18 :   __PLUMED_THROW_NOMSG(std::bad_weak_ptr);
+      86             : #endif
+      87          17 :   __PLUMED_THROW_NOMSG(std::bad_cast);
+      88          16 :   __PLUMED_THROW_NOMSG(std::bad_typeid);
+      89          15 :   __PLUMED_THROW_MSG(std::underflow_error);
+      90          14 :   __PLUMED_THROW_MSG(std::overflow_error);
+      91          13 :   __PLUMED_THROW_MSG(std::range_error);
+      92          12 :   __PLUMED_THROW_MSG(std::runtime_error);
+      93          11 :   __PLUMED_THROW_MSG(std::out_of_range);
+      94          10 :   __PLUMED_THROW_MSG(std::length_error);
+      95           9 :   __PLUMED_THROW_MSG(std::domain_error);
+      96           8 :   __PLUMED_THROW_MSG(std::invalid_argument);
+      97           7 :   __PLUMED_THROW_MSG(std::logic_error);
+      98             : 
+      99             : #ifdef __PLUMED_LIBCXX11
+     100           6 :   if(words[0]=="std::system_error") {
+     101           4 :     plumed_assert(words.size()>2);
+     102             :     int error_code;
+     103           4 :     Tools::convert(words[2],error_code);
+     104           4 :     if(words[1]=="std::generic_category") throw std::system_error(error_code,std::generic_category(),what);
+     105           3 :     if(words[1]=="std::system_category") throw std::system_error(error_code,std::system_category(),what);
+     106           2 :     if(words[1]=="std::iostream_category") throw std::system_error(error_code,std::iostream_category(),what);
+     107           1 :     if(words[1]=="std::future_category") throw std::system_error(error_code,std::future_category(),what);
+     108             :   }
+     109             : #endif
+     110             : 
+     111           2 :   if(words[0]=="std::ios_base::failure") {
+     112             : #ifdef __PLUMED_LIBCXX11
+     113           1 :     int error_code=0;
+     114           1 :     if(words.size()>2) Tools::convert(words[2],error_code);
+     115           1 :     if(words.size()>1 && words[1]=="std::generic_category") throw std::ios_base::failure(what,std::error_code(error_code,std::generic_category()));
+     116           1 :     if(words.size()>1 && words[1]=="std::system_category") throw std::ios_base::failure(what,std::error_code(error_code,std::system_category()));
+     117           1 :     if(words.size()>1 && words[1]=="std::iostream_category") throw std::ios_base::failure(what,std::error_code(error_code,std::iostream_category()));
+     118           1 :     if(words.size()>1 && words[1]=="std::future_category") throw std::ios_base::failure(what,std::error_code(error_code,std::future_category()));
+     119             : #endif
+     120           2 :     throw std::ios_base::failure(what);
+     121             :   }
+     122             : 
+     123           2 :   plumed_error() << "unknown exception " << what;
+     124          26 : }
+     125             : 
+     126             : #if 0
+     127             : // this is temporarily commented out since it makes
+     128             : // multithread calculations fail
+     129             : namespace {
+     130             : class Register {
+     131             :   std::vector<PlumedMain*> instances;
+     132             : public:
+     133             :   void add(PlumedMain* instance) {
+     134             :     instances.push_back(instance);
+     135             :   }
+     136             :   void remove(PlumedMain* instance) {
+     137             :     auto it = std::find(instances.begin(), instances.end(), instance);
+     138             :     if(it==instances.end()) {
+     139             :       std::cerr<<"WARNING: internal inconsistency in allocated PlumedMain instances\n";
+     140             :     } else {
+     141             :       instances.erase(it);
+     142             :     }
+     143             :   }
+     144             :   ~Register() {
+     145             :     if(instances.size()>0) std::cerr<<"PLUMED instances was not properly deallocated in your code: "<<instances.size()<<"\n";
+     146             :   }
+     147             : };
+     148             : 
+     149             : static Register myregister;
+     150             : 
+     151             : }
+     152             : #endif
+     153             : 
+     154      404395 : PlumedMain::PlumedMain():
+     155      404395 :   initialized(false),
+     156             : // automatically write on log in destructor
+     157      404395 :   stopwatch_fwd(log),
+     158      404395 :   step(0),
+     159      404395 :   active(false),
+     160      404395 :   mydatafetcher(DataFetchingObject::create(sizeof(double),*this)),
+     161      404395 :   endPlumed(false),
+     162      404395 :   atoms_fwd(*this),
+     163      404395 :   actionSet_fwd(*this),
+     164      404395 :   bias(0.0),
+     165      404395 :   work(0.0),
+     166      404395 :   exchangeStep(false),
+     167      404395 :   restart(false),
+     168      404395 :   doCheckPoint(false),
+     169      404395 :   stopNow(false),
+     170      404395 :   novirial(false),
+     171      808790 :   detailedTimers(false)
+     172             : {
+     173      404395 :   log.link(comm);
+     174      404395 :   log.setLinePrefix("PLUMED: ");
+     175             :   //myregister.add(this);
+     176      404395 : }
+     177             : 
+     178             : // destructor needed to delete forward declarated objects
+     179      808069 : PlumedMain::~PlumedMain() {
+     180             :   //myregister.remove(this);
+     181     1212464 : }
+     182             : 
+     183             : /////////////////////////////////////////////////////////////
+     184             : //  MAIN INTERPRETER
+     185             : 
+     186             : #define CHECK_INIT(ini,word) plumed_massert(ini,"cmd(\"" + word +"\") should be only used after plumed initialization")
+     187             : #define CHECK_NOTINIT(ini,word) plumed_massert(!(ini),"cmd(\"" + word +"\") should be only used before plumed initialization")
+     188             : #define CHECK_NOTNULL(val,word) plumed_massert(val,"NULL pointer received in cmd(\"" + word + "\")");
+     189             : 
+     190             : 
+     191     1040740 : void PlumedMain::cmd(const std::string & word,const TypesafePtr & val) {
+     192             : 
+     193             : // Enumerate all possible commands:
+     194             :   enum {
+     195             : #include "PlumedMainEnum.inc"
+     196             :   };
+     197             : 
+     198             : // Static object (initialized once) containing the map of commands:
+     199             :   const static std::unordered_map<std::string, int> word_map = {
+     200             : #include "PlumedMainMap.inc"
+     201     1306698 :   };
+     202             : 
+     203             :   try {
+     204             : 
+     205     1040740 :     auto ss=stopwatch.startPause();
+     206             : 
+     207     1040740 :     std::vector<std::string> words=Tools::getWords(word);
+     208     1040740 :     unsigned nw=words.size();
+     209     1040740 :     if(nw==0) {
+     210             :       // do nothing
+     211             :     } else {
+     212             :       int iword=-1;
+     213             :       double d;
+     214             :       const auto it=word_map.find(words[0]);
+     215     1040740 :       if(it!=word_map.end()) iword=it->second;
+     216     1040733 :       switch(iword) {
+     217       43333 :       case cmd_setBox:
+     218       43333 :         CHECK_INIT(initialized,word);
+     219       43333 :         CHECK_NOTNULL(val,word);
+     220       43333 :         atoms.setBox(val);
+     221             :         break;
+     222       47474 :       case cmd_setPositions:
+     223       47474 :         CHECK_INIT(initialized,word);
+     224       47474 :         atoms.setPositions(val);
+     225             :         break;
+     226       47478 :       case cmd_setMasses:
+     227       47478 :         CHECK_INIT(initialized,word);
+     228       47478 :         atoms.setMasses(val);
+     229             :         break;
+     230       37570 :       case cmd_setCharges:
+     231       37570 :         CHECK_INIT(initialized,word);
+     232       37570 :         atoms.setCharges(val);
+     233             :         break;
+     234           1 :       case cmd_setPositionsX:
+     235           1 :         CHECK_INIT(initialized,word);
+     236           1 :         atoms.setPositions(val,0);
+     237             :         break;
+     238           1 :       case cmd_setPositionsY:
+     239           1 :         CHECK_INIT(initialized,word);
+     240           1 :         atoms.setPositions(val,1);
+     241             :         break;
+     242           1 :       case cmd_setPositionsZ:
+     243           1 :         CHECK_INIT(initialized,word);
+     244           1 :         atoms.setPositions(val,2);
+     245             :         break;
+     246       37675 :       case cmd_setVirial:
+     247       37675 :         CHECK_INIT(initialized,word);
+     248       37675 :         CHECK_NOTNULL(val,word);
+     249       37675 :         atoms.setVirial(val);
+     250             :         break;
+     251        9792 :       case cmd_setEnergy:
+     252        9792 :         CHECK_INIT(initialized,word);
+     253        9792 :         CHECK_NOTNULL(val,word);
+     254        9792 :         atoms.setEnergy(val);
+     255             :         break;
+     256       47474 :       case cmd_setForces:
+     257       47474 :         CHECK_INIT(initialized,word);
+     258       47474 :         atoms.setForces(val);
+     259             :         break;
+     260           1 :       case cmd_setForcesX:
+     261           1 :         CHECK_INIT(initialized,word);
+     262           1 :         atoms.setForces(val,0);
+     263             :         break;
+     264           1 :       case cmd_setForcesY:
+     265           1 :         CHECK_INIT(initialized,word);
+     266           1 :         atoms.setForces(val,1);
+     267             :         break;
+     268           1 :       case cmd_setForcesZ:
+     269           1 :         CHECK_INIT(initialized,word);
+     270           1 :         atoms.setForces(val,2);
+     271             :         break;
+     272      245716 :       case cmd_calc:
+     273      245716 :         CHECK_INIT(initialized,word);
+     274      245716 :         calc();
+     275             :         break;
+     276          99 :       case cmd_prepareDependencies:
+     277          99 :         CHECK_INIT(initialized,word);
+     278          99 :         prepareDependencies();
+     279             :         break;
+     280          84 :       case cmd_shareData:
+     281          84 :         CHECK_INIT(initialized,word);
+     282          84 :         shareData();
+     283             :         break;
+     284        2070 :       case cmd_prepareCalc:
+     285        2070 :         CHECK_INIT(initialized,word);
+     286        2070 :         prepareCalc();
+     287             :         break;
+     288          10 :       case cmd_performCalc:
+     289          10 :         CHECK_INIT(initialized,word);
+     290          10 :         performCalc();
+     291             :         break;
+     292        2134 :       case cmd_performCalcNoUpdate:
+     293        2134 :         CHECK_INIT(initialized,word);
+     294        2134 :         performCalcNoUpdate();
+     295             :         break;
+     296          10 :       case cmd_performCalcNoForces:
+     297          10 :         CHECK_INIT(initialized,word);
+     298          10 :         performCalcNoForces();
+     299             :         break;
+     300          79 :       case cmd_update:
+     301          79 :         CHECK_INIT(initialized,word);
+     302          79 :         update();
+     303             :         break;
+     304       10028 :       case cmd_setStep:
+     305       10028 :         CHECK_INIT(initialized,word);
+     306       10034 :         CHECK_NOTNULL(val,word);
+     307       10025 :         step=val.get<int>();
+     308       10025 :         atoms.startStep();
+     309             :         break;
+     310      237805 :       case cmd_setStepLong:
+     311      237805 :         CHECK_INIT(initialized,word);
+     312      237805 :         CHECK_NOTNULL(val,word);
+     313      237805 :         step=val.get<long int>();
+     314      237805 :         atoms.startStep();
+     315             :         break;
+     316             :       // words used less frequently:
+     317        1140 :       case cmd_setAtomsNlocal:
+     318        1140 :         CHECK_INIT(initialized,word);
+     319        1140 :         CHECK_NOTNULL(val,word);
+     320        1140 :         atoms.setAtomsNlocal(val.get<int>());
+     321             :         break;
+     322         988 :       case cmd_setAtomsGatindex:
+     323         988 :         CHECK_INIT(initialized,word);
+     324         988 :         atoms.setAtomsGatindex(val,false);
+     325             :         break;
+     326           0 :       case cmd_setAtomsFGatindex:
+     327           0 :         CHECK_INIT(initialized,word);
+     328           0 :         atoms.setAtomsGatindex(val,true);
+     329             :         break;
+     330         152 :       case cmd_setAtomsContiguous:
+     331         152 :         CHECK_INIT(initialized,word);
+     332         152 :         CHECK_NOTNULL(val,word);
+     333         152 :         atoms.setAtomsContiguous(val.get<int>());
+     334             :         break;
+     335         116 :       case cmd_createFullList:
+     336         116 :         CHECK_INIT(initialized,word);
+     337         116 :         CHECK_NOTNULL(val,word);
+     338         116 :         atoms.createFullList(val);
+     339             :         break;
+     340         116 :       case cmd_getFullList:
+     341         116 :         CHECK_INIT(initialized,word);
+     342         116 :         CHECK_NOTNULL(val,word);
+     343         116 :         atoms.getFullList(val);
+     344             :         break;
+     345         116 :       case cmd_clearFullList:
+     346         116 :         CHECK_INIT(initialized,word);
+     347         116 :         atoms.clearFullList();
+     348             :         break;
+     349             :       /* ADDED WITH API==6 */
+     350          64 :       case cmd_getDataRank:
+     351          64 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     352         128 :         if( nw==2 ) DataFetchingObject::get_rank( actionSet, words[1], "", val);
+     353           0 :         else DataFetchingObject::get_rank( actionSet, words[1], words[2], val);
+     354             :         break;
+     355             :       /* ADDED WITH API==6 */
+     356           0 :       case cmd_getDataShape:
+     357           0 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     358           0 :         if( nw==2 ) DataFetchingObject::get_shape( actionSet, words[1], "", val );
+     359           0 :         else DataFetchingObject::get_shape( actionSet, words[1], words[2], val );
+     360             :         break;
+     361             :       /* ADDED WITH API==6 */
+     362          64 :       case cmd_setMemoryForData:
+     363          64 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     364         128 :         if( nw==2 ) mydatafetcher->setData( words[1], "", val );
+     365           0 :         else mydatafetcher->setData( words[1], words[2], val );
+     366             :         break;
+     367             :       /* ADDED WITH API==6 */
+     368             :       case cmd_setErrorHandler:
+     369             :       {
+     370           0 :         if(val) error_handler=*static_cast<const plumed_error_handler*>(val.get<const void*>());
+     371           0 :         else error_handler.handler=NULL;
+     372             :       }
+     373             :       break;
+     374           0 :       case cmd_read:
+     375           0 :         CHECK_INIT(initialized,word);
+     376           0 :         if(val)readInputFile(val.get<const char*>());
+     377           0 :         else   readInputFile("plumed.dat");
+     378             :         break;
+     379         269 :       case cmd_readInputLine:
+     380         269 :         CHECK_INIT(initialized,word);
+     381         269 :         CHECK_NOTNULL(val,word);
+     382         269 :         readInputLine(val.get<const char*>());
+     383         230 :         break;
+     384           1 :       case cmd_readInputLines:
+     385           1 :         CHECK_INIT(initialized,word);
+     386           1 :         CHECK_NOTNULL(val,word);
+     387           1 :         readInputLines(val.get<const char*>());
+     388           1 :         break;
+     389           1 :       case cmd_clear:
+     390           1 :         CHECK_INIT(initialized,word);
+     391           1 :         actionSet.clearDelete();
+     392             :         break;
+     393             :       case cmd_getApiVersion:
+     394          21 :         CHECK_NOTNULL(val,word);
+     395          21 :         val.set(int(9));
+     396             :         break;
+     397             :       // commands which can be used only before initialization:
+     398         914 :       case cmd_init:
+     399         914 :         CHECK_NOTINIT(initialized,word);
+     400         914 :         init();
+     401             :         break;
+     402         781 :       case cmd_setRealPrecision:
+     403         781 :         CHECK_NOTINIT(initialized,word);
+     404         781 :         CHECK_NOTNULL(val,word);
+     405         781 :         atoms.setRealPrecision(val.get<int>());
+     406        1560 :         mydatafetcher=DataFetchingObject::create(val.get<int>(),*this);
+     407         780 :         break;
+     408         718 :       case cmd_setMDLengthUnits:
+     409         718 :         CHECK_NOTINIT(initialized,word);
+     410         718 :         CHECK_NOTNULL(val,word);
+     411         718 :         atoms.MD2double(val,d);
+     412         718 :         atoms.setMDLengthUnits(d);
+     413             :         break;
+     414         718 :       case cmd_setMDChargeUnits:
+     415         718 :         CHECK_NOTINIT(initialized,word);
+     416         718 :         CHECK_NOTNULL(val,word);
+     417         718 :         atoms.MD2double(val,d);
+     418         718 :         atoms.setMDChargeUnits(d);
+     419             :         break;
+     420         718 :       case cmd_setMDMassUnits:
+     421         718 :         CHECK_NOTINIT(initialized,word);
+     422         718 :         CHECK_NOTNULL(val,word);
+     423         718 :         atoms.MD2double(val,d);
+     424         718 :         atoms.setMDMassUnits(d);
+     425             :         break;
+     426          45 :       case cmd_setMDEnergyUnits:
+     427          45 :         CHECK_NOTINIT(initialized,word);
+     428          45 :         CHECK_NOTNULL(val,word);
+     429          45 :         atoms.MD2double(val,d);
+     430          45 :         atoms.setMDEnergyUnits(d);
+     431             :         break;
+     432           6 :       case cmd_setMDTimeUnits:
+     433           6 :         CHECK_NOTINIT(initialized,word);
+     434           6 :         CHECK_NOTNULL(val,word);
+     435           6 :         atoms.MD2double(val,d);
+     436           6 :         atoms.setMDTimeUnits(d);
+     437             :         break;
+     438           0 :       case cmd_setNaturalUnits:
+     439             :         // set the boltzman constant for MD in natural units (kb=1)
+     440             :         // only needed in LJ codes if the MD is passing temperatures to plumed (so, not yet...)
+     441             :         // use as cmd("setNaturalUnits")
+     442           0 :         CHECK_NOTINIT(initialized,word);
+     443           0 :         atoms.setMDNaturalUnits(true);
+     444             :         break;
+     445          52 :       case cmd_setNoVirial:
+     446          52 :         CHECK_NOTINIT(initialized,word);
+     447          52 :         novirial=true;
+     448          52 :         break;
+     449         773 :       case cmd_setPlumedDat:
+     450         773 :         CHECK_NOTINIT(initialized,word);
+     451         773 :         CHECK_NOTNULL(val,word);
+     452         773 :         plumedDat=val.get<const char*>();
+     453             :         break;
+     454         337 :       case cmd_setMPIComm:
+     455         337 :         CHECK_NOTINIT(initialized,word);
+     456         337 :         comm.Set_comm(val);
+     457         337 :         atoms.setDomainDecomposition(comm);
+     458             :         break;
+     459           0 :       case cmd_setMPIFComm:
+     460           0 :         CHECK_NOTINIT(initialized,word);
+     461           0 :         comm.Set_fcomm(val);
+     462           0 :         atoms.setDomainDecomposition(comm);
+     463             :         break;
+     464           0 :       case cmd_setMPImultiSimComm:
+     465           0 :         CHECK_NOTINIT(initialized,word);
+     466           0 :         multi_sim_comm.Set_comm(val);
+     467             :         break;
+     468         897 :       case cmd_setNatoms:
+     469         897 :         CHECK_NOTINIT(initialized,word);
+     470         897 :         CHECK_NOTNULL(val,word);
+     471         897 :         atoms.setNatoms(val.get<int>());
+     472             :         break;
+     473         774 :       case cmd_setTimestep:
+     474         774 :         CHECK_NOTINIT(initialized,word);
+     475         774 :         CHECK_NOTNULL(val,word);
+     476         774 :         atoms.setTimeStep(val);
+     477             :         break;
+     478             :       /* ADDED WITH API==2 */
+     479          59 :       case cmd_setKbT:
+     480          59 :         CHECK_NOTINIT(initialized,word);
+     481          59 :         CHECK_NOTNULL(val,word);
+     482          59 :         atoms.setKbT(val);
+     483             :         break;
+     484             :       /* ADDED WITH API==3 */
+     485           8 :       case cmd_setRestart:
+     486           8 :         CHECK_NOTINIT(initialized,word);
+     487           8 :         CHECK_NOTNULL(val,word);
+     488           8 :         if(val.get<int>()!=0) restart=true;
+     489             :         break;
+     490             :       /* ADDED WITH API==4 */
+     491           0 :       case cmd_doCheckPoint:
+     492           0 :         CHECK_INIT(initialized,word);
+     493           0 :         CHECK_NOTNULL(val,word);
+     494           0 :         doCheckPoint = false;
+     495           0 :         if(val.get<int>()!=0) doCheckPoint = true;
+     496             :         break;
+     497             :       /* ADDED WITH API==6 */
+     498             :       case cmd_setNumOMPthreads:
+     499           0 :         CHECK_NOTNULL(val,word);
+     500             :         {
+     501           0 :           auto nt=val.get<unsigned>();
+     502             :           if(nt==0) nt=1;
+     503           0 :           OpenMP::setNumThreads(nt);
+     504             :         }
+     505             :         break;
+     506             :       /* ADDED WITH API==6 */
+     507             :       /* only used for testing */
+     508             :       case cmd_throw:
+     509          26 :         CHECK_NOTNULL(val,word);
+     510          26 :         testThrow(val.get<const char*>());
+     511             :       /* STOP API */
+     512         771 :       case cmd_setMDEngine:
+     513         771 :         CHECK_NOTINIT(initialized,word);
+     514         771 :         CHECK_NOTNULL(val,word);
+     515         771 :         MDEngine=val.get<const char*>();
+     516             :         break;
+     517         758 :       case cmd_setLog:
+     518         758 :         CHECK_NOTINIT(initialized,word);
+     519         758 :         log.link(val.get<FILE*>());
+     520             :         break;
+     521          52 :       case cmd_setLogFile:
+     522          52 :         CHECK_NOTINIT(initialized,word);
+     523          52 :         CHECK_NOTNULL(val,word);
+     524         138 :         log.open(val.get<const char*>());
+     525          52 :         break;
+     526             :       // other commands that should be used after initialization:
+     527      245643 :       case cmd_setStopFlag:
+     528      245643 :         CHECK_INIT(initialized,word);
+     529      245643 :         CHECK_NOTNULL(val,word);
+     530      245643 :         val.get<int*>(); // just check type and discard pointer
+     531      245642 :         stopFlag=val.copy();
+     532      245642 :         break;
+     533           0 :       case cmd_getExchangesFlag:
+     534           0 :         CHECK_INIT(initialized,word);
+     535           0 :         CHECK_NOTNULL(val,word);
+     536           0 :         exchangePatterns.getFlag(*val.get<int*>()); // note: getFlag changes the value of the reference!
+     537             :         break;
+     538           0 :       case cmd_setExchangesSeed:
+     539           0 :         CHECK_INIT(initialized,word);
+     540           0 :         CHECK_NOTNULL(val,word);
+     541           0 :         exchangePatterns.setSeed(val.get<int>());
+     542             :         break;
+     543           0 :       case cmd_setNumberOfReplicas:
+     544           0 :         CHECK_INIT(initialized,word);
+     545           0 :         CHECK_NOTNULL(val,word);
+     546           0 :         exchangePatterns.setNofR(val.get<int>());
+     547             :         break;
+     548           0 :       case cmd_getExchangesList:
+     549           0 :         CHECK_INIT(initialized,word);
+     550           0 :         CHECK_NOTNULL(val,word);
+     551           0 :         exchangePatterns.getList(val.get<int*>());
+     552           0 :         break;
+     553         721 :       case cmd_runFinalJobs:
+     554         721 :         CHECK_INIT(initialized,word);
+     555         721 :         runJobsAtEndOfCalculation();
+     556             :         break;
+     557          96 :       case cmd_isEnergyNeeded:
+     558          96 :         CHECK_INIT(initialized,word);
+     559          96 :         CHECK_NOTNULL(val,word);
+     560          96 :         if(atoms.isEnergyNeeded()) val.set(int(1));
+     561          96 :         else                       val.set(int(0));
+     562             :         break;
+     563        2172 :       case cmd_getBias:
+     564        2172 :         CHECK_INIT(initialized,word);
+     565        2172 :         CHECK_NOTNULL(val,word);
+     566        2172 :         atoms.double2MD(getBias()/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy()),val);
+     567        2172 :         break;
+     568             :       case cmd_checkAction:
+     569           2 :         CHECK_NOTNULL(val,word);
+     570           2 :         plumed_assert(nw==2);
+     571           3 :         val.set(int(actionRegister().check(words[1]) ? 1:0));
+     572           2 :         break;
+     573             :       case cmd_setExtraCV:
+     574          20 :         CHECK_NOTNULL(val,word);
+     575          20 :         plumed_assert(nw==2);
+     576          20 :         atoms.setExtraCV(words[1],val);
+     577             :         break;
+     578             :       case cmd_setExtraCVForce:
+     579          20 :         CHECK_NOTNULL(val,word);
+     580          20 :         plumed_assert(nw==2);
+     581          20 :         atoms.setExtraCVForce(words[1],val);
+     582             :         break;
+     583        1077 :       case cmd_GREX:
+     584        1077 :         if(!grex) grex=Tools::make_unique<GREX>(*this);
+     585        1077 :         plumed_massert(grex,"error allocating grex");
+     586             :         {
+     587        1077 :           std::string kk=words[1];
+     588        1248 :           for(unsigned i=2; i<words.size(); i++) kk+=" "+words[i];
+     589        2154 :           grex->cmd(kk.c_str(),val);
+     590             :         }
+     591        1077 :         break;
+     592       10668 :       case cmd_CLTool:
+     593       10668 :         CHECK_NOTINIT(initialized,word);
+     594       10668 :         if(!cltool) cltool=Tools::make_unique<CLToolMain>();
+     595             :         {
+     596       10668 :           std::string kk=words[1];
+     597       10668 :           for(unsigned i=2; i<words.size(); i++) kk+=" "+words[i];
+     598       21336 :           cltool->cmd(kk.c_str(),val);
+     599             :         }
+     600       10668 :         break;
+     601             :       /* ADDED WITH API==7 */
+     602             :       case cmd_convert:
+     603             :       {
+     604             :         double v;
+     605          22 :         plumed_assert(words.size()==2);
+     606          22 :         if(Tools::convertNoexcept(words[1],v)) atoms.double2MD(v,val);
+     607             :       }
+     608          22 :       break;
+     609           7 :       default:
+     610          21 :         plumed_merror("cannot interpret cmd(\"" + word + "\"). check plumed developers manual to see the available commands.");
+     611             :         break;
+     612             :       }
+     613             :     }
+     614             : 
+     615     1040912 :   } catch (const std::exception &e) {
+     616          86 :     if(log.isOpen()) {
+     617          51 :       log<<"\n\n################################################################################\n\n";
+     618          51 :       log<<e.what();
+     619          51 :       log<<"\n\n################################################################################\n\n";
+     620          51 :       log.flush();
+     621             :     }
+     622          86 :     throw;
+     623          86 :   }
+     624     1040654 : }
+     625             : 
+     626             : ////////////////////////////////////////////////////////////////////////
+     627             : 
+     628         914 : void PlumedMain::init() {
+     629             : // check that initialization just happens once
+     630         914 :   initialized=true;
+     631         914 :   atoms.init();
+     632         914 :   if(!log.isOpen()) log.link(stdout);
+     633         914 :   log<<"PLUMED is starting\n";
+     634        2742 :   log<<"Version: "<<config::getVersionLong()<<" (git: "<<config::getVersionGit()<<") "
+     635        3656 :      <<"compiled on " <<config::getCompilationDate() << " at " << config::getCompilationTime() << "\n";
+     636         914 :   log<<"Please cite these papers when using PLUMED ";
+     637        1828 :   log<<cite("The PLUMED consortium, Nat. Methods 16, 670 (2019)");
+     638        1828 :   log<<cite("Tribello, Bonomi, Branduardi, Camilloni, and Bussi, Comput. Phys. Commun. 185, 604 (2014)");
+     639         914 :   log<<"\n";
+     640         914 :   log<<"For further information see the PLUMED web page at http://www.plumed.org\n";
+     641         914 :   log<<"Root: "<<config::getPlumedRoot()<<"\n";
+     642        1828 :   log<<"For installed feature, see "<<config::getPlumedRoot() + "/src/config/config.txt\n";
+     643         914 :   log.printf("Molecular dynamics engine: %s\n",MDEngine.c_str());
+     644         914 :   log.printf("Precision of reals: %d\n",atoms.getRealPrecision());
+     645        1604 :   log.printf("Running over %d %s\n",comm.Get_size(),(comm.Get_size()>1?"nodes":"node"));
+     646         914 :   log<<"Number of threads: "<<OpenMP::getNumThreads()<<"\n";
+     647         914 :   log<<"Cache line size: "<<OpenMP::getCachelineSize()<<"\n";
+     648         914 :   log.printf("Number of atoms: %d\n",atoms.getNatoms());
+     649         914 :   if(grex) log.printf("GROMACS-like replica exchange is on\n");
+     650         914 :   log.printf("File suffix: %s\n",getSuffix().c_str());
+     651         914 :   if(plumedDat.length()>0) {
+     652         773 :     readInputFile(plumedDat);
+     653             :     plumedDat="";
+     654             :   }
+     655         914 :   atoms.updateUnits();
+     656         914 :   log.printf("Timestep: %f\n",atoms.getTimeStep());
+     657         914 :   if(atoms.getKbT()>0.0)
+     658          53 :     log.printf("KbT: %f\n",atoms.getKbT());
+     659             :   else {
+     660         861 :     log.printf("KbT has not been set by the MD engine\n");
+     661         861 :     log.printf("It should be set by hand where needed\n");
+     662             :   }
+     663         914 :   log<<"Relevant bibliography:\n";
+     664         914 :   log<<citations;
+     665         914 :   log<<"Please read and cite where appropriate!\n";
+     666         914 :   log<<"Finished setup\n";
+     667         914 : }
+     668             : 
+     669         791 : void PlumedMain::readInputFile(const std::string & str) {
+     670         791 :   plumed_assert(initialized);
+     671         791 :   log<<"FILE: "<<str<<"\n";
+     672         791 :   IFile ifile;
+     673         791 :   ifile.link(*this);
+     674         791 :   ifile.open(str);
+     675         791 :   ifile.allowNoEOL();
+     676         791 :   readInputFile(ifile);
+     677         791 :   log<<"END FILE: "<<str<<"\n";
+     678         791 :   log.flush();
+     679             : 
+     680         791 : }
+     681             : 
+     682         792 : void PlumedMain::readInputFile(IFile & ifile) {
+     683             :   std::vector<std::string> words;
+     684       14523 :   while(Tools::getParsedLine(ifile,words) && !endPlumed) readInputWords(words);
+     685         792 :   endPlumed=false;
+     686         792 :   pilots=actionSet.select<ActionPilot*>();
+     687         792 : }
+     688             : 
+     689         353 : void PlumedMain::readInputLine(const std::string & str) {
+     690         353 :   plumed_assert(initialized);
+     691         353 :   if(str.empty()) return;
+     692         353 :   std::vector<std::string> words=Tools::getWords(str);
+     693         353 :   citations.clear();
+     694         353 :   readInputWords(words);
+     695         314 :   if(!citations.empty()) {
+     696           2 :     log<<"Relevant bibliography:\n";
+     697           2 :     log<<citations;
+     698           2 :     log<<"Please read and cite where appropriate!\n";
+     699             :   }
+     700         353 : }
+     701             : 
+     702           1 : void PlumedMain::readInputLines(const std::string & str) {
+     703           1 :   plumed_assert(initialized);
+     704           1 :   if(str.empty()) return;
+     705             : 
+     706           1 :   log<<"FILE: (temporary)\n";
+     707             : 
+     708             :   // Open a temporary file
+     709           1 :   auto fp=std::tmpfile();
+     710           1 :   plumed_assert(fp);
+     711             : 
+     712             :   // make sure file is closed (and thus deleted) also if an exception occurs
+     713           1 :   auto deleter=[](FILE* fp) { std::fclose(fp); };
+     714             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     715             : 
+     716           1 :   auto ret=std::fputs(str.c_str(),fp);
+     717           1 :   plumed_assert(ret!=EOF);
+     718             : 
+     719           1 :   std::rewind(fp);
+     720             : 
+     721           1 :   IFile ifile;
+     722           1 :   ifile.link(*this);
+     723           1 :   ifile.link(fp);
+     724           1 :   ifile.allowNoEOL();
+     725             : 
+     726           1 :   readInputFile(ifile);
+     727           1 :   log<<"END FILE: (temporary)\n";
+     728           1 : }
+     729             : 
+     730       14110 : void PlumedMain::readInputWords(const std::vector<std::string> & words) {
+     731       14110 :   plumed_assert(initialized);
+     732       14110 :   if(words.empty())return;
+     733       14110 :   else if(words[0]=="_SET_SUFFIX") {
+     734           3 :     plumed_assert(words.size()==2);
+     735             :     setSuffix(words[1]);
+     736             :   } else {
+     737       14107 :     std::vector<std::string> interpreted(words);
+     738       14107 :     Tools::interpretLabel(interpreted);
+     739       28177 :     auto action=actionRegister().create(ActionOptions(*this,interpreted));
+     740       14070 :     if(!action) {
+     741             :       std::string msg;
+     742             :       msg ="ERROR\nI cannot understand line:";
+     743          10 :       for(unsigned i=0; i<interpreted.size(); ++i) msg+=" "+interpreted[i];
+     744             :       msg+="\nMaybe a missing space or a typo?";
+     745           2 :       log << msg;
+     746           2 :       log.flush();
+     747           4 :       plumed_merror(msg);
+     748             :     }
+     749       14068 :     action->checkRead();
+     750       14068 :     actionSet.emplace_back(std::move(action));
+     751       14109 :   };
+     752             : 
+     753       28142 :   pilots=actionSet.select<ActionPilot*>();
+     754             : }
+     755             : 
+     756             : ////////////////////////////////////////////////////////////////////////
+     757             : 
+     758           0 : void PlumedMain::exit(int c) {
+     759           0 :   comm.Abort(c);
+     760           0 : }
+     761             : 
+     762       14105 : Log& PlumedMain::getLog() {
+     763       14105 :   return log;
+     764             : }
+     765             : 
+     766      245716 : void PlumedMain::calc() {
+     767      245716 :   prepareCalc();
+     768      245716 :   performCalc();
+     769      245716 : }
+     770             : 
+     771      247786 : void PlumedMain::prepareCalc() {
+     772      247786 :   prepareDependencies();
+     773      247786 :   shareData();
+     774      247786 : }
+     775             : 
+     776             : //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+     777             : // here we have the main steps in "calc()"
+     778             : // they can be called individually, but the standard thing is to
+     779             : // traverse them in this order:
+     780      248113 : void PlumedMain::prepareDependencies() {
+     781             : 
+     782             : // Stopwatch is stopped when sw goes out of scope
+     783      248113 :   auto sw=stopwatch.startStop("1 Prepare dependencies");
+     784             : 
+     785             : // activate all the actions which are on step
+     786             : // activation is recursive and enables also the dependencies
+     787             : // before doing that, the prepare() method is called to see if there is some
+     788             : // new/changed dependency (up to now, only useful for dependences on virtual atoms,
+     789             : // which can be dynamically changed).
+     790             : 
+     791             : // First switch off all actions
+     792     2071737 :   for(const auto & p : actionSet) {
+     793     1823624 :     p->deactivate();
+     794             :   }
+     795             : 
+     796             : // for optimization, an "active" flag remains false if no action at all is active
+     797      248113 :   active=mydatafetcher->activate();
+     798     1587111 :   for(unsigned i=0; i<pilots.size(); ++i) {
+     799     1338998 :     if(pilots[i]->onStep()) {
+     800     1269461 :       pilots[i]->activate();
+     801     1269461 :       active=true;
+     802             :     }
+     803             :   };
+     804             : 
+     805             : // also, if one of them is the total energy, tell to atoms that energy should be collected
+     806     2071737 :   for(const auto & p : actionSet) {
+     807     1823624 :     if(p->isActive()) {
+     808     1642537 :       if(p->checkNeedsGradients()) p->setOption("GRADIENTS");
+     809             :     }
+     810             :   }
+     811             : 
+     812      248113 : }
+     813             : 
+     814      247870 : void PlumedMain::shareData() {
+     815             : // atom positions are shared (but only if there is something to do)
+     816      247870 :   if(!active)return;
+     817             : // Stopwatch is stopped when sw goes out of scope
+     818      246382 :   auto sw=stopwatch.startStop("2 Sharing data");
+     819      246382 :   if(atoms.getNatoms()>0) atoms.share();
+     820      246382 : }
+     821             : 
+     822        2134 : void PlumedMain::performCalcNoUpdate() {
+     823        2134 :   waitData();
+     824        2134 :   justCalculate();
+     825        2134 :   backwardPropagate();
+     826        2134 : }
+     827             : 
+     828          10 : void PlumedMain::performCalcNoForces() {
+     829          10 :   waitData();
+     830          10 :   justCalculate();
+     831          10 : }
+     832             : 
+     833      245726 : void PlumedMain::performCalc() {
+     834      245726 :   waitData();
+     835      245726 :   justCalculate();
+     836      245726 :   backwardPropagate();
+     837      245726 :   update();
+     838      245726 :   mydatafetcher->finishDataGrab();
+     839      245726 : }
+     840             : 
+     841      247984 : void PlumedMain::waitData() {
+     842      247984 :   if(!active)return;
+     843             : // Stopwatch is stopped when sw goes out of scope
+     844      246496 :   auto sw=stopwatch.startStop("3 Waiting for data");
+     845      246496 :   if(atoms.getNatoms()>0) atoms.wait();
+     846      246496 : }
+     847             : 
+     848      247984 : void PlumedMain::justCalculate() {
+     849      247984 :   if(!active)return;
+     850             : // Stopwatch is stopped when sw goes out of scope
+     851      246496 :   auto sw=stopwatch.startStop("4 Calculating (forward loop)");
+     852      246496 :   bias=0.0;
+     853      246496 :   work=0.0;
+     854             : 
+     855      246496 :   int iaction=0;
+     856             : // calculate the active actions in order (assuming *backward* dependence)
+     857     2060664 :   for(const auto & pp : actionSet) {
+     858             :     Action* p(pp.get());
+     859     1814168 :     if(p->isActive()) {
+     860             : // Stopwatch is stopped when sw goes out of scope.
+     861             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+     862     1641587 :       Stopwatch::Handler sw;
+     863     1641587 :       if(detailedTimers) {
+     864             :         std::string actionNumberLabel;
+     865        1690 :         Tools::convert(iaction,actionNumberLabel);
+     866        1690 :         const unsigned m=actionSet.size();
+     867        5070 :         unsigned k=0; unsigned n=1; while(n<m) { n*=10; k++; }
+     868        1690 :         const int pad=k-actionNumberLabel.length();
+     869        2815 :         for(int i=0; i<pad; i++) actionNumberLabel=" "+actionNumberLabel;
+     870        1690 :         sw=stopwatch.startStop("4A "+actionNumberLabel+" "+p->getLabel());
+     871             :       }
+     872     1641587 :       ActionWithValue*av=dynamic_cast<ActionWithValue*>(p);
+     873     1641587 :       ActionAtomistic*aa=dynamic_cast<ActionAtomistic*>(p);
+     874             :       {
+     875     1641587 :         if(av) av->clearInputForces();
+     876     1641587 :         if(av) av->clearDerivatives();
+     877             :       }
+     878             :       {
+     879     1641587 :         if(aa) aa->clearOutputForces();
+     880     1641587 :         if(aa) if(aa->isActive()) aa->retrieveAtoms();
+     881             :       }
+     882     1641587 :       if(p->checkNumericalDerivatives()) p->calculateNumericalDerivatives();
+     883     1641020 :       else p->calculate();
+     884             :       // This retrieves components called bias
+     885     1641587 :       if(av) {
+     886     1389822 :         bias+=av->getOutputQuantity("bias");
+     887     1389822 :         work+=av->getOutputQuantity("work");
+     888     1389822 :         av->setGradientsIfNeeded();
+     889             :       }
+     890     1641587 :       ActionWithVirtualAtom*avv=dynamic_cast<ActionWithVirtualAtom*>(p);
+     891     1641587 :       if(avv)avv->setGradientsIfNeeded();
+     892     1641587 :     }
+     893     1814168 :     iaction++;
+     894             :   }
+     895      246496 : }
+     896             : 
+     897           0 : void PlumedMain::justApply() {
+     898           0 :   backwardPropagate();
+     899           0 :   update();
+     900           0 : }
+     901             : 
+     902      247860 : void PlumedMain::backwardPropagate() {
+     903      247860 :   if(!active)return;
+     904      246372 :   int iaction=0;
+     905             : // Stopwatch is stopped when sw goes out of scope
+     906      246372 :   auto sw=stopwatch.startStop("5 Applying (backward loop)");
+     907             : // apply them in reverse order
+     908     2059606 :   for(auto pp=actionSet.rbegin(); pp!=actionSet.rend(); ++pp) {
+     909             :     const auto & p(pp->get());
+     910     1813234 :     if(p->isActive()) {
+     911             : 
+     912             : // Stopwatch is stopped when sw goes out of scope.
+     913             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+     914     1640833 :       Stopwatch::Handler sw;
+     915     1640833 :       if(detailedTimers) {
+     916             :         std::string actionNumberLabel;
+     917        1690 :         Tools::convert(iaction,actionNumberLabel);
+     918        1690 :         const unsigned m=actionSet.size();
+     919        5070 :         unsigned k=0; unsigned n=1; while(n<m) { n*=10; k++; }
+     920        1690 :         const int pad=k-actionNumberLabel.length();
+     921        2815 :         for(int i=0; i<pad; i++) actionNumberLabel=" "+actionNumberLabel;
+     922        1690 :         sw=stopwatch.startStop("5A "+actionNumberLabel+" "+p->getLabel());
+     923             :       }
+     924             : 
+     925     1640833 :       p->apply();
+     926     1640833 :       ActionAtomistic*a=dynamic_cast<ActionAtomistic*>(p);
+     927             : // still ActionAtomistic has a special treatment, since they may need to add forces on atoms
+     928     1640833 :       if(a) a->applyForces();
+     929             : 
+     930     1640833 :     }
+     931     1813234 :     iaction++;
+     932             :   }
+     933             : 
+     934             : // Stopwatch is stopped when sw goes out of scope.
+     935             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+     936      246372 :   Stopwatch::Handler sw1;
+     937      246485 :   if(detailedTimers) sw1=stopwatch.startStop("5B Update forces");
+     938             : // this is updating the MD copy of the forces
+     939      246372 :   if(atoms.getNatoms()>0) atoms.updateForces();
+     940      246372 : }
+     941             : 
+     942      245805 : void PlumedMain::update() {
+     943      245805 :   if(!active)return;
+     944             : 
+     945             : // Stopwatch is stopped when sw goes out of scope
+     946      244317 :   auto sw=stopwatch.startStop("6 Update");
+     947             : 
+     948             : // update step (for statistics, etc)
+     949      244317 :   updateFlags.push(true);
+     950     2051084 :   for(const auto & p : actionSet) {
+     951     1806767 :     p->beforeUpdate();
+     952     3440763 :     if(p->isActive() && p->checkUpdate() && updateFlagsTop()) p->update();
+     953             :   }
+     954      488638 :   while(!updateFlags.empty()) updateFlags.pop();
+     955             :   if(!updateFlags.empty()) plumed_merror("non matching changes in the update flags");
+     956             : // Check that no action has told the calculation to stop
+     957      244317 :   if(stopNow) {
+     958          65 :     if(stopFlag) stopFlag.set(int(1));
+     959           0 :     else plumed_merror("your md code cannot handle plumed stop events - add a call to plumed.comm(stopFlag,stopCondition)");
+     960             :   }
+     961             : 
+     962             : // flush by default every 10000 steps
+     963             : // hopefully will not affect performance
+     964             : // also if receive checkpointing signal
+     965      244317 :   if(step%10000==0||doCheckPoint) {
+     966         886 :     fflush();
+     967         886 :     log.flush();
+     968       15368 :     for(const auto & p : actionSet) p->fflush();
+     969             :   }
+     970      244317 : }
+     971             : 
+     972           2 : void PlumedMain::load(const std::string& ss) {
+     973           2 :   if(DLLoader::installed()) {
+     974           2 :     std::string s=ss;
+     975           2 :     size_t n=s.find_last_of(".");
+     976           3 :     std::string extension="";
+     977           2 :     std::string base=s;
+     978           4 :     if(n!=std::string::npos && n<s.length()-1) extension=s.substr(n+1);
+     979           4 :     if(n!=std::string::npos && n<s.length())   base=s.substr(0,n);
+     980           2 :     if(extension=="cpp") {
+     981             : // full path command, including environment setup
+     982             : // this will work even if plumed is not in the execution path or if it has been
+     983             : // installed with a name different from "plumed"
+     984           4 :       std::string cmd=config::getEnvCommand()+" \""+config::getPlumedRoot()+"\"/scripts/mklib.sh "+s;
+     985           2 :       log<<"Executing: "<<cmd;
+     986           2 :       if(comm.Get_size()>0) log<<" (only on master node)";
+     987           2 :       log<<"\n";
+     988           2 :       if(comm.Get_rank()==0) {
+     989           2 :         int ret=std::system(cmd.c_str());
+     990           3 :         if(ret!=0) plumed_error() <<"An error happened while executing command "<<cmd<<"\n";
+     991             :       }
+     992           1 :       comm.Barrier();
+     993           2 :       base="./"+base;
+     994             :     }
+     995           2 :     s=base+"."+config::getSoExt();
+     996           1 :     void *p=dlloader.load(s);
+     997           1 :     if(!p) {
+     998           0 :       plumed_error()<<"I cannot load library " << ss << " " << dlloader.error();
+     999             :     }
+    1000           2 :     log<<"Loading shared library "<<s.c_str()<<"\n";
+    1001           1 :     log<<"Here is the new list of available actions\n";
+    1002           1 :     log<<actionRegister();
+    1003           0 :   } else plumed_error()<<"While loading library "<< ss << " loading was not enabled, please check if dlopen was found at configure time";
+    1004           1 : }
+    1005             : 
+    1006        2805 : double PlumedMain::getBias() const {
+    1007        2805 :   return bias;
+    1008             : }
+    1009             : 
+    1010         450 : double PlumedMain::getWork() const {
+    1011         450 :   return work;
+    1012             : }
+    1013             : 
+    1014          73 : FILE* PlumedMain::fopen(const char *path, const char *mode) {
+    1015          73 :   std::string mmode(mode);
+    1016          73 :   std::string ppath(path);
+    1017          73 :   std::string suffix(getSuffix());
+    1018          73 :   std::string ppathsuf=ppath+suffix;
+    1019          73 :   FILE*fp=std::fopen(const_cast<char*>(ppathsuf.c_str()),const_cast<char*>(mmode.c_str()));
+    1020          73 :   if(!fp) fp=std::fopen(const_cast<char*>(ppath.c_str()),const_cast<char*>(mmode.c_str()));
+    1021          73 :   plumed_massert(fp,"file " + ppath + " cannot be found");
+    1022          73 :   return fp;
+    1023             : }
+    1024             : 
+    1025          91 : int PlumedMain::fclose(FILE*fp) {
+    1026          91 :   return std::fclose(fp);
+    1027             : }
+    1028             : 
+    1029        3576 : std::string PlumedMain::cite(const std::string&item) {
+    1030        3576 :   return citations.cite(item);
+    1031             : }
+    1032             : 
+    1033        1447 : void PlumedMain::fflush() {
+    1034        4578 :   for(const auto  & p : files) {
+    1035        3131 :     p->flush();
+    1036             :   }
+    1037        1447 : }
+    1038             : 
+    1039        4317 : void PlumedMain::insertFile(FileBase&f) {
+    1040        4317 :   files.insert(&f);
+    1041        4317 : }
+    1042             : 
+    1043        4607 : void PlumedMain::eraseFile(FileBase&f) {
+    1044        4607 :   files.erase(&f);
+    1045        4607 : }
+    1046             : 
+    1047          65 : void PlumedMain::stop() {
+    1048          65 :   stopNow=true;
+    1049          65 : }
+    1050             : 
+    1051         721 : void PlumedMain::runJobsAtEndOfCalculation() {
+    1052       14277 :   for(const auto & p : actionSet) {
+    1053       13556 :     p->runFinalJobs();
+    1054             :   }
+    1055         721 : }
+    1056             : 
+    1057             : #ifdef __PLUMED_HAS_PYTHON
+    1058             : // This is here to stop cppcheck throwing an error
+    1059             : #endif
+    1060             : 
+    1061             : }
+    1062             : 
+    1063             : //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..354e93fbce --- /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:151693.8 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/PlumedMain.h.func.html b/coverage/core/PlumedMain.h.func.html new file mode 100644 index 0000000000..d7d62fbe3b --- /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:151693.8 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/PlumedMain.h.gcov.html b/coverage/core/PlumedMain.h.gcov.html new file mode 100644 index 0000000000..1eb5b6318a --- /dev/null +++ b/coverage/core/PlumedMain.h.gcov.html @@ -0,0 +1,580 @@ + + + + + + + + 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:151693.8 %
Date:2024-06-10 08:19:14Functions: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             : 
+      35             : // !!!!!!!!!!!!!!!!!!!!!!    DANGER   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
+      36             : // THE FOLLOWING ARE DEFINITIONS WHICH ARE NECESSARY FOR DYNAMIC LOADING OF THE PLUMED KERNEL:
+      37             : // This section should be consistent with the Plumed.h file.
+      38             : // Since the Plumed.h file may be included in host MD codes, **NEVER** MODIFY THE CODE DOWN HERE
+      39             : 
+      40             : /* Generic function pointer */
+      41             : typedef void (*plumed_function_pointer)(void);
+      42             : 
+      43             : /* Holder for function pointer */
+      44             : typedef struct {
+      45             :   plumed_function_pointer p;
+      46             : } plumed_function_holder;
+      47             : 
+      48             : // END OF DANGER
+      49             : ////////////////////////////////////////////////////////////
+      50             : 
+      51             : namespace PLMD {
+      52             : 
+      53             : 
+      54             : 
+      55             : class ActionAtomistic;
+      56             : class ActionPilot;
+      57             : class Log;
+      58             : class Atoms;
+      59             : class ActionSet;
+      60             : class DLLoader;
+      61             : class Communicator;
+      62             : class Stopwatch;
+      63             : class Citations;
+      64             : class ExchangePatterns;
+      65             : class FileBase;
+      66             : class DataFetchingObject;
+      67             : class TypesafePtr;
+      68             : class IFile;
+      69             : 
+      70             : /**
+      71             : Main plumed object.
+      72             : In MD engines this object is not manipulated directly but it is wrapped in
+      73             : plumed or PLMD::Plumed objects. Its main method is cmd(),
+      74             : which defines completely the external plumed interface.
+      75             : It does not contain any static data.
+      76             : */
+      77             : class PlumedMain:
+      78             :   public WithCmd
+      79             : {
+      80             : /// Pointers to files opened in actions associated to this object.
+      81             : /// Notice that with the current implementation this should be at the top of this
+      82             : /// structure. Indeed, this should be destroyed *after* all the actions allocated
+      83             : /// in this PlumedMain object have been destroyed.
+      84             :   std::set<FileBase*> files;
+      85             : /// Forward declaration.
+      86             :   ForwardDecl<Communicator> comm_fwd;
+      87             : public:
+      88             : /// Communicator for plumed.
+      89             : /// Includes all the processors used by plumed.
+      90             :   Communicator&comm=*comm_fwd;
+      91             : 
+      92             : private:
+      93             : /// Forward declaration.
+      94             :   ForwardDecl<Communicator> multi_sim_comm_fwd;
+      95             : public:
+      96             :   Communicator&multi_sim_comm=*multi_sim_comm_fwd;
+      97             : 
+      98             : private:
+      99             : /// Error handler.
+     100             : /// Pointer to a function that is called an exception thrown within
+     101             : /// the library is about to leave the library.
+     102             : /// Can be used to remap exceptions in case the plumed wrapper was compiled
+     103             : /// with a different version of the C++ standard library.
+     104             : /// Should only be called from \ref plumed_plumedmain_cmd().
+     105             :   typedef struct {
+     106             :     void* ptr;
+     107             :     void(*handler)(void* ptr,int code,const char*);
+     108             :   } plumed_error_handler;
+     109             : 
+     110             :   plumed_error_handler error_handler= {NULL,NULL};
+     111             : 
+     112             : /// Forward declaration.
+     113             :   ForwardDecl<DLLoader> dlloader_fwd;
+     114             :   DLLoader& dlloader=*dlloader_fwd;
+     115             : 
+     116             :   std::unique_ptr<WithCmd> cltool;
+     117             : 
+     118             :   std::unique_ptr<WithCmd> grex;
+     119             : /// Flag to avoid double initialization
+     120             :   bool  initialized;
+     121             : /// Name of MD engine
+     122             :   std::string MDEngine;
+     123             : 
+     124             : /// Forward declaration.
+     125             :   ForwardDecl<Log> log_fwd;
+     126             : /// Log stream
+     127             :   Log& log=*log_fwd;
+     128             : 
+     129             : /// Forward declaration.
+     130             : /// Should be placed after log since its constructor takes a log reference as an argument.
+     131             :   ForwardDecl<Stopwatch> stopwatch_fwd;
+     132             :   Stopwatch& stopwatch=*stopwatch_fwd;
+     133             : 
+     134             : /// Forward declaration.
+     135             :   ForwardDecl<Citations> citations_fwd;
+     136             : /// tools/Citations.holder
+     137             :   Citations& citations=*citations_fwd;
+     138             : 
+     139             : /// Present step number.
+     140             :   long int step;
+     141             : 
+     142             : /// Condition for plumed to be active.
+     143             : /// At every step, PlumedMain is checking if there are Action's requiring some work.
+     144             : /// If at least one Action requires some work, this variable is set to true.
+     145             :   bool active;
+     146             : 
+     147             : /// Name of the input file
+     148             :   std::string plumedDat;
+     149             : 
+     150             : /// Object containing data we would like to grab and pass back
+     151             :   std::unique_ptr<DataFetchingObject> mydatafetcher;
+     152             : 
+     153             : /// End of input file.
+     154             : /// Set to true to terminate reading
+     155             :   bool endPlumed;
+     156             : 
+     157             : /// Forward declaration.
+     158             :   ForwardDecl<Atoms> atoms_fwd;
+     159             : /// Object containing information about atoms (such as positions,...).
+     160             :   Atoms&    atoms=*atoms_fwd;           // atomic coordinates
+     161             : 
+     162             : /// Forward declaration.
+     163             :   ForwardDecl<ActionSet> actionSet_fwd;
+     164             : /// Set of actions found in plumed.dat file
+     165             :   ActionSet& actionSet=*actionSet_fwd;
+     166             : 
+     167             : /// Set of Pilot actions.
+     168             : /// These are the action the, if they are Pilot::onStep(), can trigger execution
+     169             :   std::vector<ActionPilot*> pilots;
+     170             : 
+     171             : /// Suffix string for file opening, useful for multiple simulations in the same directory
+     172             :   std::string suffix;
+     173             : 
+     174             : /// The total bias (=total energy of the restraints)
+     175             :   double bias;
+     176             : 
+     177             : /// The total work.
+     178             : /// This computed by accumulating the change in external potentials.
+     179             :   double work;
+     180             : 
+     181             : /// Forward declaration.
+     182             :   ForwardDecl<ExchangePatterns> exchangePatterns_fwd;
+     183             : /// Class of possible exchange patterns, used for BIASEXCHANGE but also for future parallel tempering
+     184             :   ExchangePatterns& exchangePatterns=*exchangePatterns_fwd;
+     185             : 
+     186             : /// Set to true if on an exchange step
+     187             :   bool exchangeStep;
+     188             : 
+     189             : /// Flag for restart
+     190             :   bool restart;
+     191             : 
+     192             : /// Flag for checkpointig
+     193             :   bool doCheckPoint;
+     194             : 
+     195             : 
+     196             : private:
+     197             : /// Forward declaration.
+     198             :   ForwardDecl<TypesafePtr> stopFlag_fwd;
+     199             : public:
+     200             : /// Stuff to make plumed stop the MD code cleanly
+     201             :   TypesafePtr& stopFlag=*stopFlag_fwd;
+     202             :   bool stopNow;
+     203             : 
+     204             : /// Stack for update flags.
+     205             : /// Store information used in class \ref generic::UpdateIf
+     206             :   std::stack<bool> updateFlags;
+     207             : 
+     208             : public:
+     209             : /// Flag to switch off virial calculation (for debug and MD codes with no barostat)
+     210             :   bool novirial;
+     211             : 
+     212             : /// Flag to switch on detailed timers
+     213             :   bool detailedTimers;
+     214             : 
+     215             : /// Generic map string -> double
+     216             : /// intended to pass information across Actions
+     217             :   std::map<std::string,double> passMap;
+     218             : 
+     219             : /// Add a citation, returning a string containing the reference number, something like "[10]"
+     220             :   std::string cite(const std::string&);
+     221             : 
+     222             : /// Get number of threads that can be used by openmp
+     223             :   unsigned getNumThreads()const;
+     224             : 
+     225             : /// Get a reasonable number of threads so as to access to an array of size s located at x
+     226             :   template<typename T>
+     227             :   unsigned getGoodNumThreads(const T*x,unsigned s)const;
+     228             : 
+     229             : /// Get a reasonable number of threads so as to access to vector v;
+     230             :   template<typename T>
+     231             :   unsigned getGoodNumThreads(const std::vector<T> & v)const;
+     232             : 
+     233             : public:
+     234             :   PlumedMain();
+     235             : // this is to access to WithCmd versions of cmd (allowing overloading of a virtual method)
+     236             :   using WithCmd::cmd;
+     237             :   /**
+     238             :    cmd method, accessible with standard Plumed.h interface.
+     239             :    \param key The name of the command to be executed.
+     240             :    \param val The argument of the command to be executed.
+     241             :    It is called as plumed_cmd() or as PLMD::Plumed::cmd()
+     242             :    It is the interpreter for plumed commands. It basically contains the definition of the plumed interface.
+     243             :    If you want to add a new functionality to the interface between plumed
+     244             :    and an MD engine, this is the right place
+     245             :    Notice that this interface should always keep retro-compatibility
+     246             :   */
+     247             :   void cmd(const std::string&key,const TypesafePtr & val=nullptr) override;
+     248             :   ~PlumedMain();
+     249             :   /**
+     250             :     Read an input file.
+     251             :     \param str name of the file
+     252             :   */
+     253             :   void readInputFile(const std::string & str);
+     254             :   /**
+     255             :     Read an input file.
+     256             :     \param ifile
+     257             :   */
+     258             :   void readInputFile(IFile & ifile);
+     259             :   /**
+     260             :     Read an input string.
+     261             :     \param str name of the string
+     262             :   */
+     263             :   void readInputWords(const std::vector<std::string> &  str);
+     264             : 
+     265             :   /**
+     266             :     Read an input string.
+     267             :     \param str name of the string
+     268             :     At variance with readInputWords(), this is splitting the string into words
+     269             :   */
+     270             :   void readInputLine(const std::string & str);
+     271             : 
+     272             :   /**
+     273             :     Read an input buffer.
+     274             :     \param str name of the string
+     275             :     Same as readInputFile, but first write str on a temporary file and then read
+     276             :     that files. At variance with readInputLine, it can take care of comments and
+     277             :     continuation lines.
+     278             :   */
+     279             :   void readInputLines(const std::string & str);
+     280             : 
+     281             :   /**
+     282             :     Initialize the object.
+     283             :     Should be called once.
+     284             :   */
+     285             :   void init();
+     286             :   /**
+     287             :     Prepare the calculation.
+     288             :     Here it is checked which are the active Actions and communication of the relevant atoms is initiated.
+     289             :     Shortcut for prepareDependencies() + shareData()
+     290             :   */
+     291             :   void prepareCalc();
+     292             :   /**
+     293             :     Prepare the list of active Actions and needed atoms.
+     294             :     Scan the Actions to see which are active and which are not, so as to prepare a list of
+     295             :     the atoms needed at this step.
+     296             :   */
+     297             :   void prepareDependencies();
+     298             :   /**
+     299             :     Share the needed atoms.
+     300             :     In asynchronous implementations, this method sends the required atoms to all the plumed processes,
+     301             :     without waiting for the communication to complete.
+     302             :   */
+     303             :   void shareData();
+     304             :   /**
+     305             :     Perform the calculation.
+     306             :     Shortcut for waitData() + justCalculate() + justApply().
+     307             :     Equivalently: waitData() + justCalculate() + backwardPropagate() + update().
+     308             :   */
+     309             :   void performCalc();
+     310             :   /**
+     311             :     Perform the calculation without update()
+     312             :     Shortcut for: waitData() + justCalculate() + backwardPropagate()
+     313             :   */
+     314             :   void performCalcNoUpdate();
+     315             :   /**
+     316             :     Perform the calculation without backpropagation nor update()
+     317             :     Shortcut for: waitData() + justCalculate()
+     318             :   */
+     319             :   void performCalcNoForces();
+     320             :   /**
+     321             :     Complete PLUMED calculation.
+     322             :     Shortcut for prepareCalc() + performCalc()
+     323             :   */
+     324             :   void calc();
+     325             :   /**
+     326             :     Scatters the needed atoms.
+     327             :     In asynchronous implementations, this method waits for the communications started in shareData()
+     328             :     to be completed. Otherwise, just send around needed atoms.
+     329             :   */
+     330             :   void waitData();
+     331             :   /**
+     332             :     Perform the forward loop on active actions.
+     333             :   */
+     334             :   void justCalculate();
+     335             :   /**
+     336             :     Backward propagate and update.
+     337             :     Shortcut for backwardPropagate() + update()
+     338             :     I leave it here for backward compatibility
+     339             :   */
+     340             :   void justApply();
+     341             :   /**
+     342             :     Perform the backward loop on active actions.
+     343             :     Needed to apply the forces back.
+     344             :   */
+     345             :   void backwardPropagate();
+     346             :   /**
+     347             :     Call the update() method.
+     348             :   */
+     349             :   void update();
+     350             :   /**
+     351             :     If there are calculations that need to be done at the very end of the calculations this
+     352             :     makes sures they are done
+     353             :   */
+     354             :   void runJobsAtEndOfCalculation();
+     355             : /// Reference to atoms object
+     356             :   Atoms& getAtoms();
+     357             : /// Reference to the list of Action's
+     358             :   const ActionSet & getActionSet()const;
+     359             : /// Referenge to the log stream
+     360             :   Log & getLog();
+     361             : /// Return the number of the step
+     362     4500265 :   long int getStep()const {return step;}
+     363             : /// Stop the run
+     364             :   void exit(int c=0);
+     365             : /// Load a shared library
+     366             :   void load(const std::string&);
+     367             : /// Get the suffix string
+     368             :   const std::string & getSuffix()const;
+     369             : /// Set the suffix string
+     370             :   void setSuffix(const std::string&);
+     371             : /// get the value of the bias
+     372             :   double getBias()const;
+     373             : /// get the value of the work
+     374             :   double getWork()const;
+     375             : /// Opens a file.
+     376             : /// Similar to plain fopen, but, if it finds an error in opening the file, it also tries with
+     377             : /// path+suffix.  This trick is useful for multiple replica simulations.
+     378             :   FILE* fopen(const char *path, const char *mode);
+     379             : /// Closes a file opened with PlumedMain::fopen()
+     380             :   int fclose(FILE*fp);
+     381             : /// Insert a file
+     382             :   void insertFile(FileBase&);
+     383             : /// Erase a file
+     384             :   void eraseFile(FileBase&);
+     385             : /// Flush all files
+     386             :   void fflush();
+     387             : /// Check if restarting
+     388             :   bool getRestart()const;
+     389             : /// Set restart flag
+     390          56 :   void setRestart(bool f) {restart=f;}
+     391             : /// Check if checkpointing
+     392             :   bool getCPT()const;
+     393             : /// Set exchangeStep flag
+     394             :   void setExchangeStep(bool f);
+     395             : /// Get exchangeStep flag
+     396             :   bool getExchangeStep()const;
+     397             : /// Stop the calculation cleanly (both the MD code and plumed)
+     398             :   void stop();
+     399             : /// Enforce active flag.
+     400             : /// This is a (bit dirty) hack to solve a bug. When there is no active ActionPilot,
+     401             : /// several shortcuts are used. However, these shortcuts can block GREX module.
+     402             : /// This function allows to enforce active plumed when doing exchanges,
+     403             : /// thus fixing the bug.
+     404             :   void resetActive(bool active);
+     405             : 
+     406             : /// Access to exchange patterns
+     407           0 :   ExchangePatterns& getExchangePatterns() {return exchangePatterns;}
+     408             : 
+     409             : /// Push a state to update flags
+     410             :   void updateFlagsPush(bool);
+     411             : /// Pop a state from update flags
+     412             :   void updateFlagsPop();
+     413             : /// Get top of update flags
+     414             :   bool updateFlagsTop();
+     415             : /// Set end of input file
+     416             :   void setEndPlumed();
+     417             : /// Call error handler.
+     418             : /// Should only be called from \ref plumed_plumedmain_cmd().
+     419             : /// If the error handler was not set, returns false.
+     420             :   bool callErrorHandler(int code,const char* msg)const;
+     421             : };
+     422             : 
+     423             : /////
+     424             : // FAST INLINE METHODS:
+     425             : 
+     426             : inline
+     427             : const ActionSet & PlumedMain::getActionSet()const {
+     428     1108407 :   return actionSet;
+     429             : }
+     430             : 
+     431             : inline
+     432             : Atoms& PlumedMain::getAtoms() {
+     433     3190877 :   return atoms;
+     434             : }
+     435             : 
+     436             : inline
+     437             : const std::string & PlumedMain::getSuffix()const {
+     438        4631 :   return suffix;
+     439             : }
+     440             : 
+     441             : inline
+     442             : void PlumedMain::setSuffix(const std::string&s) {
+     443         411 :   suffix=s;
+     444         411 : }
+     445             : 
+     446             : inline
+     447             : bool PlumedMain::getRestart()const {
+     448       14161 :   return restart;
+     449             : }
+     450             : 
+     451             : inline
+     452             : bool PlumedMain::getCPT()const {
+     453       14105 :   return doCheckPoint;
+     454             : }
+     455             : 
+     456             : inline
+     457             : void PlumedMain::setExchangeStep(bool s) {
+     458         228 :   exchangeStep=s;
+     459             : }
+     460             : 
+     461             : inline
+     462             : bool PlumedMain::getExchangeStep()const {
+     463       28109 :   return exchangeStep;
+     464             : }
+     465             : 
+     466             : inline
+     467             : void PlumedMain::resetActive(bool active) {
+     468         114 :   this->active=active;
+     469             : }
+     470             : 
+     471             : inline
+     472             : void PlumedMain::updateFlagsPush(bool on) {
+     473             :   updateFlags.push(on);
+     474             : }
+     475             : 
+     476             : inline
+     477             : void PlumedMain::updateFlagsPop() {
+     478             :   updateFlags.pop();
+     479          12 : }
+     480             : 
+     481             : inline
+     482             : bool PlumedMain::updateFlagsTop() {
+     483     1634003 :   return updateFlags.top();
+     484             : }
+     485             : 
+     486             : inline
+     487             : void PlumedMain::setEndPlumed() {
+     488         259 :   endPlumed=true;
+     489             : }
+     490             : 
+     491             : inline
+     492             : bool PlumedMain::callErrorHandler(int code,const char* msg)const {
+     493             :   if(error_handler.handler) {
+     494             :     error_handler.handler(error_handler.ptr,code,msg);
+     495             :     return true;
+     496             :   } else return false;
+     497             : }
+     498             : 
+     499             : 
+     500             : }
+     501             : 
+     502             : #endif
+     503             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b670bf62ec --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:10214371.3 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZL13typesafeDebugPKc16plumed_safeptr_x0
plumed_plumedmain_cmd_nothrow0
plumed_plumedmain_cmd_safe93
plumed_plumedmain_cmd357
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev3473
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev3473
plumed_plumedmain_cmd_safe_nothrow12408
_ZL19getenvTypesafeDebugv12501
plumed_plumedmain_create403572
plumed_plumedmain_finalize403572
plumed_symbol_table_init407021
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/PlumedMainInitializer.cpp.func.html b/coverage/core/PlumedMainInitializer.cpp.func.html new file mode 100644 index 0000000000..c16e186a14 --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:10214371.3 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZL13typesafeDebugPKc16plumed_safeptr_x0
_ZL19getenvTypesafeDebugv12501
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev3473
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev3473
plumed_plumedmain_cmd357
plumed_plumedmain_cmd_nothrow0
plumed_plumedmain_cmd_safe93
plumed_plumedmain_cmd_safe_nothrow12408
plumed_plumedmain_create403572
plumed_plumedmain_finalize403572
plumed_symbol_table_init407021
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/PlumedMainInitializer.cpp.gcov.html b/coverage/core/PlumedMainInitializer.cpp.gcov.html new file mode 100644 index 0000000000..4f3ab45b5b --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.gcov.html @@ -0,0 +1,389 @@ + + + + + + + + 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:10214371.3 %
Date:2024-06-10 08:19:14Functions:91181.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 "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             : #ifdef __PLUMED_LIBCXX11
+      38             : #include <system_error>
+      39             : #include <future>
+      40             : #include <memory>
+      41             : #include <functional>
+      42             : #endif
+      43             : #include "tools/TypesafePtr.h"
+      44             : 
+      45             : 
+      46       12501 : static bool getenvTypesafeDebug() noexcept {
+      47       12501 :   static const auto* res=std::getenv("PLUMED_TYPESAFE_DEBUG");
+      48       12501 :   return res;
+      49             : }
+      50             : 
+      51           0 : static void typesafeDebug(const char*key,plumed_safeptr_x safe) noexcept {
+      52           0 :   std::fprintf(stderr,"+++ PLUMED_TYPESAFE_DEBUG %s %p %zu",key,safe.ptr,safe.nelem);
+      53           0 :   const size_t* shape=safe.shape;
+      54           0 :   if(shape) {
+      55           0 :     std::fprintf(stderr," (");
+      56           0 :     while(*shape!=0) {
+      57           0 :       std::fprintf(stderr," %zu",*shape);
+      58           0 :       shape++;
+      59             :     }
+      60           0 :     std::fprintf(stderr," )");
+      61             :   }
+      62           0 :   std::fprintf(stderr," %zx %p\n",safe.flags,safe.opt);
+      63           0 : }
+      64             : 
+      65             : // create should never throw
+      66             : // in case of a problem, it logs the error and return a null pointer
+      67             : // when loaded by an interface >=2.5, this will result in a non valid plumed object.
+      68             : // earlier interfaces will just give a segfault or a failed assertion.
+      69      403572 : extern "C" void*plumed_plumedmain_create() {
+      70             :   try {
+      71      403572 :     return new PLMD::PlumedMain;
+      72           0 :   } catch(const std::exception & e) {
+      73           0 :     std::cerr<<"+++ an error happened while creating a plumed object\n";
+      74           0 :     std::cerr<<e.what()<<std::endl;
+      75             :     return nullptr;
+      76           0 :   } catch(...) {
+      77           0 :     std::cerr<<"+++ an unknown error happened while creating a plumed object"<<std::endl;
+      78             :     return nullptr;
+      79           0 :   }
+      80             : }
+      81             : 
+      82         357 : extern "C" void plumed_plumedmain_cmd(void*plumed,const char*key,const void*val) {
+      83         357 :   plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+      84             :   auto p=static_cast<PLMD::PlumedMain*>(plumed);
+      85         714 :   p->cmd(key,PLMD::TypesafePtr::unchecked(val));
+      86         357 : }
+      87             : 
+      88             : extern "C" {
+      89          93 :   static void plumed_plumedmain_cmd_safe(void*plumed,const char*key,plumed_safeptr_x safe) {
+      90          93 :     plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+      91             :     auto p=static_cast<PLMD::PlumedMain*>(plumed);
+      92          93 :     if(getenvTypesafeDebug()) typesafeDebug(key,safe);
+      93         186 :     p->cmd(key,PLMD::TypesafePtr::fromSafePtr(&safe));
+      94          93 :   }
+      95             : }
+      96             : 
+      97             : extern "C" {
+      98       12408 :   static void plumed_plumedmain_cmd_safe_nothrow(void*plumed,const char*key,plumed_safeptr_x safe,plumed_nothrow_handler_x nothrow) {
+      99             : // This is a workaround for a suboptimal choice in PLUMED <2.8
+     100             : // In particular, the only way to bypass the exception handling process was to call the plumed_plumedmain_cmd_safe
+     101             : // function directly.
+     102             : // With this modification, it is possible to just call the plumed_plumedmain_cmd_safe_nothrow function
+     103             : // passing a null error handler.
+     104       12408 :     if(!nothrow.handler) {
+     105           0 :       plumed_plumedmain_cmd_safe(plumed,key,safe);
+     106           0 :       return;
+     107             :     }
+     108             : // At library boundaries we translate exceptions to error codes.
+     109             : // This allows an exception to be catched also if the MD code
+     110             : // was linked against a different C++ library
+     111             :     try {
+     112       12408 :       plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+     113             :       auto p=static_cast<PLMD::PlumedMain*>(plumed);
+     114       12408 :       if(getenvTypesafeDebug()) typesafeDebug(key,safe);
+     115       24816 :       p->cmd(key,PLMD::TypesafePtr::fromSafePtr(&safe));
+     116          86 :     } catch(const PLMD::ExceptionTypeError & e) {
+     117           8 :       nothrow.handler(nothrow.ptr,20300,e.what(),nullptr);
+     118          62 :     } catch(const PLMD::ExceptionError & e) {
+     119          54 :       nothrow.handler(nothrow.ptr,20200,e.what(),nullptr);
+     120          55 :     } catch(const PLMD::ExceptionDebug & e) {
+     121           1 :       nothrow.handler(nothrow.ptr,20100,e.what(),nullptr);
+     122           2 :     } catch(const PLMD::Exception & e) {
+     123           1 :       nothrow.handler(nothrow.ptr,20000,e.what(),nullptr);
+     124           2 :     } catch(const PLMD::lepton::Exception & e) {
+     125           1 :       nothrow.handler(nothrow.ptr,19900,e.what(),nullptr);
+     126             :       // 11000 to 12000 are "bad exceptions". message will be copied without new allocations
+     127           2 :     } catch(const std::bad_exception & e) {
+     128           1 :       nothrow.handler(nothrow.ptr,11500,e.what(),nullptr);
+     129             : #ifdef __PLUMED_LIBCXX11
+     130           2 :     } catch(const std::bad_array_new_length & e) {
+     131           1 :       nothrow.handler(nothrow.ptr,11410,e.what(),nullptr);
+     132             : #endif
+     133           2 :     } catch(const std::bad_alloc & e) {
+     134           1 :       nothrow.handler(nothrow.ptr,11400,e.what(),nullptr);
+     135             : #ifdef __PLUMED_LIBCXX11
+     136           2 :     } catch(const std::bad_function_call & e) {
+     137           1 :       nothrow.handler(nothrow.ptr,11300,e.what(),nullptr);
+     138           2 :     } catch(const std::bad_weak_ptr & e) {
+     139           1 :       nothrow.handler(nothrow.ptr,11200,e.what(),nullptr);
+     140             : #endif
+     141           2 :     } catch(const std::bad_cast & e) {
+     142           1 :       nothrow.handler(nothrow.ptr,11100,e.what(),nullptr);
+     143           2 :     } catch(const std::bad_typeid & e) {
+     144           1 :       nothrow.handler(nothrow.ptr,11000,e.what(),nullptr);
+     145             :       // not implemented yet: std::regex_error
+     146             :       // we do not allow regex yet due to portability problems with gcc 4.8
+     147             :       // as soon as we transition to using <regex> it should be straightforward to add
+     148           2 :     } catch(const std::ios_base::failure & e) {
+     149             : #ifdef __PLUMED_LIBCXX11
+     150           1 :       int value=e.code().value();
+     151           1 :       const void* opt[3]= {"c",&value,nullptr}; // "c" passes the error code. nullptr terminates the optional part.
+     152           1 :       if(e.code().category()==std::generic_category()) nothrow.handler(nothrow.ptr,10230,e.what(),opt);
+     153           1 :       else if(e.code().category()==std::system_category()) nothrow.handler(nothrow.ptr,10231,e.what(),opt);
+     154           1 :       else if(e.code().category()==std::iostream_category()) nothrow.handler(nothrow.ptr,10232,e.what(),opt);
+     155           0 :       else if(e.code().category()==std::future_category()) nothrow.handler(nothrow.ptr,10233,e.what(),opt);
+     156             :       else
+     157             : #endif
+     158             :         // 10239 represents std::ios_base::failure with default constructur
+     159           0 :         nothrow.handler(nothrow.ptr,10239,e.what(),nullptr);
+     160             : #ifdef __PLUMED_LIBCXX11
+     161           5 :     } catch(const std::system_error & e) {
+     162           4 :       int value=e.code().value();
+     163           4 :       const void* opt[3]= {"c",&value,nullptr}; // "c" passes the error code. nullptr terminates the optional part.
+     164           4 :       if(e.code().category()==std::generic_category()) nothrow.handler(nothrow.ptr,10220,e.what(),opt);
+     165           3 :       else if(e.code().category()==std::system_category()) nothrow.handler(nothrow.ptr,10221,e.what(),opt);
+     166           2 :       else if(e.code().category()==std::iostream_category()) nothrow.handler(nothrow.ptr,10222,e.what(),opt);
+     167           1 :       else if(e.code().category()==std::future_category()) nothrow.handler(nothrow.ptr,10223,e.what(),opt);
+     168             :       // fallback to generic runtime_error
+     169           0 :       else nothrow.handler(nothrow.ptr,10200,e.what(),nullptr);
+     170             : #endif
+     171           5 :     } catch(const std::underflow_error &e) {
+     172           1 :       nothrow.handler(nothrow.ptr,10215,e.what(),nullptr);
+     173           2 :     } catch(const std::overflow_error &e) {
+     174           1 :       nothrow.handler(nothrow.ptr,10210,e.what(),nullptr);
+     175           2 :     } catch(const std::range_error &e) {
+     176           1 :       nothrow.handler(nothrow.ptr,10205,e.what(),nullptr);
+     177           2 :     } catch(const std::runtime_error & e) {
+     178           1 :       nothrow.handler(nothrow.ptr,10200,e.what(),nullptr);
+     179             :       // not implemented yet: std::future_error
+     180             :       // not clear how useful it would be.
+     181           2 :     } catch(const std::out_of_range & e) {
+     182           1 :       nothrow.handler(nothrow.ptr,10120,e.what(),nullptr);
+     183           2 :     } catch(const std::length_error & e) {
+     184           1 :       nothrow.handler(nothrow.ptr,10115,e.what(),nullptr);
+     185           2 :     } catch(const std::domain_error & e) {
+     186           1 :       nothrow.handler(nothrow.ptr,10110,e.what(),nullptr);
+     187           2 :     } catch(const std::invalid_argument & e) {
+     188           1 :       nothrow.handler(nothrow.ptr,10105,e.what(),nullptr);
+     189           2 :     } catch(const std::logic_error & e) {
+     190           1 :       nothrow.handler(nothrow.ptr,10100,e.what(),nullptr);
+     191             :       // generic exception. message will be copied without new allocations
+     192             :       // reports all non caught exceptions that are derived from std::exception
+     193             :       // for instance, boost exceptions would end up here
+     194           1 :     } catch(const std::exception & e) {
+     195           0 :       nothrow.handler(nothrow.ptr,10000,e.what(),nullptr);
+     196           0 :     } catch(...) {
+     197             :       // if exception cannot be translated, we throw a bad_exception
+     198           0 :       nothrow.handler(nothrow.ptr,11500,"plumed could not translate exception",nullptr);
+     199           0 :       throw;
+     200           0 :     }
+     201             :   }
+     202             : }
+     203             : 
+     204             : extern "C" {
+     205           0 :   static void plumed_plumedmain_cmd_nothrow(void*plumed,const char*key,const void*val,plumed_nothrow_handler_x nothrow) {
+     206             :     plumed_safeptr_x safe;
+     207           0 :     plumed_assert(nothrow.handler) << "Accepting a null pointer here would make the calling code non compatible with plumed 2.5 to 2.7";
+     208           0 :     safe.ptr=val;
+     209           0 :     safe.nelem=0;
+     210           0 :     safe.shape=NULL;
+     211           0 :     safe.flags=0;
+     212           0 :     safe.opt=NULL;
+     213           0 :     plumed_plumedmain_cmd_safe_nothrow(plumed,key,safe,nothrow);
+     214           0 :   }
+     215             : }
+     216             : 
+     217      403572 : extern "C" void plumed_plumedmain_finalize(void*plumed) {
+     218      403572 :   plumed_massert(plumed,"trying to deallocate a plumed object which is not initialized");
+     219             : // I think it is not possible to replace this delete with a smart pointer
+     220             : // since the ownership of this pointer is in a C structure. GB
+     221      403572 :   delete static_cast<PLMD::PlumedMain*>(plumed);
+     222      403572 : }
+     223             : 
+     224             : // values here should be consistent with those in plumed_symbol_table_init !!!!
+     225             : plumed_symbol_table_type_x plumed_symbol_table= {
+     226             :   3,
+     227             :   {plumed_plumedmain_create,plumed_plumedmain_cmd,plumed_plumedmain_finalize},
+     228             :   plumed_plumedmain_cmd_nothrow,
+     229             :   plumed_plumedmain_cmd_safe,
+     230             :   plumed_plumedmain_cmd_safe_nothrow
+     231             : };
+     232             : 
+     233             : // values here should be consistent with those above !!!!
+     234      407021 : extern "C" void plumed_symbol_table_init() {
+     235      407021 :   plumed_symbol_table.version=3;
+     236      407021 :   plumed_symbol_table.functions.create=plumed_plumedmain_create;
+     237      407021 :   plumed_symbol_table.functions.cmd=plumed_plumedmain_cmd;
+     238      407021 :   plumed_symbol_table.functions.finalize=plumed_plumedmain_finalize;
+     239      407021 :   plumed_symbol_table.cmd_nothrow=plumed_plumedmain_cmd_nothrow;
+     240      407021 :   plumed_symbol_table.cmd_safe=plumed_plumedmain_cmd_safe;
+     241      407021 :   plumed_symbol_table.cmd_safe_nothrow=plumed_plumedmain_cmd_safe_nothrow;
+     242      407021 : }
+     243             : 
+     244             : namespace PLMD {
+     245             : 
+     246             : #define plumed_convert_fptr(ptr,fptr) { ptr=NULL; std::memcpy(&ptr,&fptr,(sizeof(fptr)>sizeof(ptr)?sizeof(ptr):sizeof(fptr))); }
+     247             : 
+     248             : /// Static object which registers Plumed.
+     249             : /// This is a static object which, during its construction at startup,
+     250             : /// registers the pointers to plumed_plumedmain_create, plumed_plumedmain_cmd and plumed_plumedmain_finalize
+     251             : /// to the plumed_kernel_register function.
+     252             : /// Registration is only required with plumed loader <=2.4, but we do it anyway in order to maintain
+     253             : /// backward compatibility. Notice that as of plumed 2.5 the plumed_kernel_register is found
+     254             : /// using dlsym, in order to allow the libplumedKernel library to be loadable also when
+     255             : /// the plumed_kernel_register symbol is not available.
+     256             : namespace {
+     257             : class PlumedMainInitializer {
+     258             :   const bool debug;
+     259             : public:
+     260        3473 :   PlumedMainInitializer():
+     261        3473 :     debug(std::getenv("PLUMED_LOAD_DEBUG"))
+     262             :   {
+     263             : // make sure static plumed_function_pointers is initialized here
+     264        3473 :     plumed_symbol_table_init();
+     265        3473 :     if(debug) std::fprintf(stderr,"+++ Initializing PLUMED with plumed_symbol_table version %i at %p\n",plumed_symbol_table.version,(void*)&plumed_symbol_table);
+     266             : #if defined(__PLUMED_HAS_DLOPEN)
+     267        3473 :     if(std::getenv("PLUMED_LOAD_SKIP_REGISTRATION")) {
+     268           0 :       if(debug) std::fprintf(stderr,"+++ Skipping registration +++\n");
+     269           0 :       return;
+     270             :     }
+     271             :     typedef plumed_plumedmain_function_holder_x* (*plumed_kernel_register_type_x)(const plumed_plumedmain_function_holder_x*);
+     272             :     plumed_kernel_register_type_x plumed_kernel_register=nullptr;
+     273             :     void* handle=nullptr;
+     274             : #if defined(__PLUMED_HAS_RTLD_DEFAULT)
+     275        3473 :     if(debug) std::fprintf(stderr,"+++ Registering functions. Looking in RTLD_DEFAULT +++\n");
+     276        3473 :     void* dls=dlsym(RTLD_DEFAULT,"plumed_kernel_register");
+     277             : #else
+     278             :     handle=dlopen(NULL,RTLD_LOCAL);
+     279             :     if(debug) std::fprintf(stderr,"+++ Registering functions. dlopen handle at %p +++\n",handle);
+     280             :     void* dls=dlsym(handle,"plumed_kernel_register");
+     281             : #endif
+     282        3473 :     *(void **)(&plumed_kernel_register)=dls;
+     283        3473 :     if(debug) {
+     284           0 :       if(plumed_kernel_register) {
+     285           0 :         std::fprintf(stderr,"+++ plumed_kernel_register found at %p +++\n",dls);
+     286             :       }
+     287           0 :       else std::fprintf(stderr,"+++ plumed_kernel_register not found +++\n");
+     288             :     }
+     289             :     void*createp;
+     290             :     void*cmdp;
+     291             :     void*finalizep;
+     292             :     plumed_convert_fptr(createp,plumed_symbol_table.functions.create);
+     293             :     plumed_convert_fptr(cmdp,plumed_symbol_table.functions.cmd);
+     294             :     plumed_convert_fptr(finalizep,plumed_symbol_table.functions.finalize);
+     295        3473 :     if(plumed_kernel_register && debug) std::fprintf(stderr,"+++ Registering functions at %p (%p,%p,%p) +++\n",
+     296             :           (void*)&plumed_symbol_table.functions,createp,cmdp,finalizep);
+     297        3473 :     if(plumed_kernel_register) (*plumed_kernel_register)(&plumed_symbol_table.functions);
+     298             : // Notice that handle could be null in the following cases:
+     299             : // - if we use RTLD_DEFAULT
+     300             : // - on Linux if we don't use RTLD_DEFAULT, since dlopen(NULL,RTLD_LOCAL) returns a null pointer.
+     301             :     if(handle) dlclose(handle);
+     302             : #endif
+     303             :   }
+     304        3473 :   ~PlumedMainInitializer() {
+     305        3473 :     if(debug) std::fprintf(stderr,"+++ Finalizing PLUMED with plumed_symbol_table at %p\n",(void*)&plumed_symbol_table);
+     306        3473 :   }
+     307             : } PlumedMainInitializerRegisterMe;
+     308             : }
+     309             : 
+     310             : }
+     311             : 
+     312             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..17e3b3d916 --- /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-06-10 08:19:14Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10TargetDist4readERKNS_3PDBESt6vectorIPNS_5ValueESaIS6_EE0
_ZN4PLMD10TargetDist4readERKSt6vectorIdSaIdEES1_IPNS_5ValueESaIS7_EE0
_ZN4PLMD10TargetDist9calculateERSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/TargetDist.cpp.func.html b/coverage/core/TargetDist.cpp.func.html new file mode 100644 index 0000000000..d5c5d162fd --- /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-06-10 08:19:14Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10TargetDist4readERKNS_3PDBESt6vectorIPNS_5ValueESaIS6_EE0
_ZN4PLMD10TargetDist4readERKSt6vectorIdSaIdEES1_IPNS_5ValueESaIS7_EE0
_ZN4PLMD10TargetDist9calculateERSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/TargetDist.cpp.gcov.html b/coverage/core/TargetDist.cpp.gcov.html new file mode 100644 index 0000000000..ea0509d492 --- /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-06-10 08:19:14Functions: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, 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, 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.15
+
+ + + 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 0000000000..27e8b0e047 --- /dev/null +++ b/coverage/core/Value.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + 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:10311986.6 %
Date:2024-06-10 08:19:14Functions:131681.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD5Value12setGradientsEv183
_ZN4PLMD5Value10projectionERKS0_S2_261
_ZN4PLMD5Value15getPntrToActionEv4718
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_27933
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb48350
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE964774
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1151479
_ZN4PLMD5Value16setupPeriodicityEv1183328
_ZNK4PLMD5Value10isPeriodicEv1664039
_ZN4PLMD5Value14setNotPeriodicEv3527960
_ZN4PLMD5ValueC2Ev3561022
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Value.cpp.func.html b/coverage/core/Value.cpp.func.html new file mode 100644 index 0000000000..d22c9a971d --- /dev/null +++ b/coverage/core/Value.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + 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:10311986.6 %
Date:2024-06-10 08:19:14Functions:131681.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3addERKNS_5ValueEPS0_0
_ZN4PLMD4copyERKNS_5ValueEPS0_0
_ZN4PLMD4copyERKNS_5ValueERS0_0
_ZN4PLMD5Value10projectionERKS0_S2_261
_ZN4PLMD5Value12setGradientsEv183
_ZN4PLMD5Value14setNotPeriodicEv3527960
_ZN4PLMD5Value15getPntrToActionEv4718
_ZN4PLMD5Value16setupPeriodicityEv1183328
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1151479
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb48350
_ZN4PLMD5ValueC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE18
_ZN4PLMD5ValueC2Ev3561022
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE964774
_ZNK4PLMD5Value10isPeriodicEv1664039
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_27933
_ZNK4PLMD5Value9getDomainERdS1_34
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Value.cpp.gcov.html b/coverage/core/Value.cpp.gcov.html new file mode 100644 index 0000000000..42fcf16e72 --- /dev/null +++ b/coverage/core/Value.cpp.gcov.html @@ -0,0 +1,277 @@ + + + + + + + + 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:10311986.6 %
Date:2024-06-10 08:19:14Functions:131681.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             : #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 "Atoms.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 :   value(0.0),
+      37     3561022 :   inputForce(0.0),
+      38     3561022 :   hasForce(false),
+      39     3561022 :   hasDeriv(true),
+      40     3561022 :   periodicity(unset),
+      41     3561022 :   min(0.0),
+      42     3561022 :   max(0.0),
+      43     3561022 :   max_minus_min(0.0),
+      44     3561022 :   inv_max_minus_min(0.0)
+      45             : {
+      46     3561022 : }
+      47             : 
+      48          18 : Value::Value(const std::string& name):
+      49          18 :   action(NULL),
+      50          18 :   value_set(false),
+      51          18 :   value(0.0),
+      52          18 :   inputForce(0.0),
+      53          18 :   hasForce(false),
+      54          18 :   name(name),
+      55          18 :   hasDeriv(true),
+      56          18 :   periodicity(unset),
+      57          18 :   min(0.0),
+      58          18 :   max(0.0),
+      59          18 :   max_minus_min(0.0),
+      60          18 :   inv_max_minus_min(0.0)
+      61             : {
+      62          18 : }
+      63             : 
+      64       48350 : Value::Value(ActionWithValue* av, const std::string& name, const bool withderiv):
+      65       48350 :   action(av),
+      66       48350 :   value_set(false),
+      67       48350 :   value(0.0),
+      68       48350 :   inputForce(0.0),
+      69       48350 :   hasForce(false),
+      70       48350 :   name(name),
+      71       48350 :   hasDeriv(withderiv),
+      72       48350 :   periodicity(unset),
+      73       48350 :   min(0.0),
+      74       48350 :   max(0.0),
+      75       48350 :   max_minus_min(0.0),
+      76       48350 :   inv_max_minus_min(0.0)
+      77             : {
+      78       48350 : }
+      79             : 
+      80     1183328 : void Value::setupPeriodicity() {
+      81     1183328 :   if( min==0 && max==0 ) {
+      82       31849 :     periodicity=notperiodic;
+      83             :   } else {
+      84     1151479 :     periodicity=periodic;
+      85     1151479 :     max_minus_min=max-min;
+      86     1151479 :     plumed_massert(max_minus_min>0, "your function has a very strange domain?");
+      87     1151479 :     inv_max_minus_min=1.0/max_minus_min;
+      88             :   }
+      89     1183328 : }
+      90             : 
+      91     1664039 : bool Value::isPeriodic()const {
+      92     1664039 :   plumed_massert(periodicity!=unset,"periodicity should be set");
+      93     1664039 :   return periodicity==periodic;
+      94             : }
+      95             : 
+      96      964774 : bool Value::applyForce(std::vector<double>& forces ) const {
+      97      964774 :   if( !hasForce ) return false;
+      98             :   plumed_dbg_massert( derivatives.size()==forces.size()," forces array has wrong size" );
+      99      115220 :   const unsigned N=derivatives.size();
+     100    48882393 :   for(unsigned i=0; i<N; ++i) forces[i]=inputForce*derivatives[i];
+     101             :   return true;
+     102             : }
+     103             : 
+     104     3527960 : void Value::setNotPeriodic() {
+     105     3527960 :   min=0; max=0; periodicity=notperiodic;
+     106     3527960 : }
+     107             : 
+     108     1151479 : void Value::setDomain(const std::string& pmin,const std::string& pmax) {
+     109     1151479 :   str_min=pmin;
+     110     1151479 :   if( !Tools::convertNoexcept(str_min,min) ) action->error("could not convert period string " + str_min + " to real");
+     111     1151479 :   str_max=pmax;
+     112     1151479 :   if( !Tools::convertNoexcept(str_max,max) ) action->error("could not convert period string " + str_max + " to read");
+     113     1151479 :   setupPeriodicity();
+     114     1151479 : }
+     115             : 
+     116       27933 : void Value::getDomain(std::string&minout,std::string&maxout) const {
+     117       27933 :   plumed_massert(periodicity==periodic,"function should be periodic");
+     118       27933 :   minout=str_min;
+     119       27933 :   maxout=str_max;
+     120       27933 : }
+     121             : 
+     122          34 : void Value::getDomain(double&minout,double&maxout) const {
+     123          34 :   plumed_massert(periodicity==periodic,"function should be periodic");
+     124          34 :   minout=min;
+     125          34 :   maxout=max;
+     126          34 : }
+     127             : 
+     128         183 : void Value::setGradients() {
+     129             :   // Can't do gradients if we don't have derivatives
+     130         183 :   if( !hasDeriv ) return;
+     131             :   gradients.clear();
+     132         183 :   ActionAtomistic*aa=dynamic_cast<ActionAtomistic*>(action);
+     133         183 :   ActionWithArguments*aw=dynamic_cast<ActionWithArguments*>(action);
+     134         183 :   if(aa) {
+     135         100 :     Atoms&atoms((aa->plumed).getAtoms());
+     136        8092 :     for(unsigned j=0; j<aa->getNumberOfAtoms(); ++j) {
+     137        7992 :       AtomNumber an=aa->getAbsoluteIndex(j);
+     138        7992 :       if(atoms.isVirtualAtom(an)) {
+     139             :         const ActionWithVirtualAtom* a=atoms.getVirtualAtomsAction(an);
+     140          33 :         for(const auto & p : a->getGradients()) {
+     141             : // controllare l'ordine del matmul:
+     142          30 :           gradients[p.first]+=matmul(Vector(derivatives[3*j],derivatives[3*j+1],derivatives[3*j+2]),p.second);
+     143             :         }
+     144             :       } else {
+     145       31956 :         for(unsigned i=0; i<3; i++) gradients[an][i]+=derivatives[3*j+i];
+     146             :       }
+     147             :     }
+     148          83 :   } else if(aw) {
+     149          83 :     std::vector<Value*> values=aw->getArguments();
+     150         249 :     for(unsigned j=0; j<derivatives.size(); j++) {
+     151        8174 :       for(const auto & p : values[j]->gradients) {
+     152        8008 :         AtomNumber iatom=p.first;
+     153        8008 :         gradients[iatom]+=p.second*derivatives[j];
+     154             :       }
+     155             :     }
+     156           0 :   } else plumed_error();
+     157             : }
+     158             : 
+     159         261 : double Value::projection(const Value& v1,const Value&v2) {
+     160             :   double proj=0.0;
+     161             :   const std::map<AtomNumber,Vector> & grad1(v1.gradients);
+     162             :   const std::map<AtomNumber,Vector> & grad2(v2.gradients);
+     163       16167 :   for(const auto & p1 : grad1) {
+     164       15906 :     AtomNumber a=p1.first;
+     165             :     const auto p2=grad2.find(a);
+     166       15906 :     if(p2!=grad2.end()) {
+     167        8224 :       proj+=dotProduct(p1.second,(*p2).second);
+     168             :     }
+     169             :   }
+     170         261 :   return proj;
+     171             : }
+     172             : 
+     173        4718 : ActionWithValue* Value::getPntrToAction() {
+     174        4718 :   plumed_assert( action!=NULL );
+     175        4718 :   return action;
+     176             : }
+     177             : 
+     178           0 : void copy( const Value& val1, Value& val2 ) {
+     179           0 :   unsigned nder=val1.getNumberOfDerivatives();
+     180           0 :   if( nder!=val2.getNumberOfDerivatives() ) { val2.resizeDerivatives( nder ); }
+     181             :   val2.clearDerivatives();
+     182           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2.addDerivative( i, val1.getDerivative(i) );
+     183             :   val2.set( val1.get() );
+     184           0 : }
+     185             : 
+     186           0 : void copy( const Value& val1, Value* val2 ) {
+     187           0 :   unsigned nder=val1.getNumberOfDerivatives();
+     188           0 :   if( nder!=val2->getNumberOfDerivatives() ) { val2->resizeDerivatives( nder ); }
+     189             :   val2->clearDerivatives();
+     190           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2->addDerivative( i, val1.getDerivative(i) );
+     191             :   val2->set( val1.get() );
+     192           0 : }
+     193             : 
+     194           0 : void add( const Value& val1, Value* val2 ) {
+     195           0 :   plumed_assert( val1.getNumberOfDerivatives()==val2->getNumberOfDerivatives() );
+     196           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2->addDerivative( i, val1.getDerivative(i) );
+     197           0 :   val2->set( val1.get() + val2->get() );
+     198           0 : }
+     199             : 
+     200             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..4813e4393c --- /dev/null +++ b/coverage/core/Value.h.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + 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:414395.3 %
Date:2024-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value9chainRuleEd434
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZNK4PLMD5Value22getNumberOfDerivativesEv329575
_ZN4PLMD5Value16applyPeriodicityEv44362184
_ZNK4PLMD5Value10differenceEdd155957917
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Value.h.func.html b/coverage/core/Value.h.func.html new file mode 100644 index 0000000000..1417fd9db1 --- /dev/null +++ b/coverage/core/Value.h.func.html @@ -0,0 +1,93 @@ + + + + + + + + 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:414395.3 %
Date:2024-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value16applyPeriodicityEv44362184
_ZN4PLMD5Value9chainRuleEd434
_ZNK4PLMD5Value10differenceEdd155957917
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZNK4PLMD5Value22getNumberOfDerivativesEv329575
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/Value.h.gcov.html b/coverage/core/Value.h.gcov.html new file mode 100644 index 0000000000..b9d5d09d10 --- /dev/null +++ b/coverage/core/Value.h.gcov.html @@ -0,0 +1,393 @@ + + + + + + + + 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:414395.3 %
Date:2024-06-10 08:19:14Functions: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             : #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             : 
+      37             : /// \ingroup TOOLBOX
+      38             : /// A class for holding the value of a function together with its derivatives.
+      39             : /// Typically, an  object of type PLMD::ActionWithValue will contain one
+      40             : /// object of type PLUMD::Value that will be named after the label.  If the
+      41             : /// PLMD::ActionWithValue is part of a class that calculates multiple components
+      42             : /// then the class will contain multiple that will be called label.component-name
+      43             : /// This class is used to pass information between different PLMD::Action
+      44             : /// objects.  However, if you find a use for a tempory PLMD::Value in some method
+      45             : /// you are implementing please feel free to use it.
+      46             : class Value {
+      47             :   friend class ActionWithValue;
+      48             : /// This copies the contents of a value into a second value (just the derivatives and value)
+      49             :   friend void copy( const Value& val1, Value& val2 );
+      50             : /// This copies the contents of a value into a second value (but second value is a pointer)
+      51             :   friend void copy( const Value& val, Value* val2 );
+      52             : /// This adds some derivatives onto the value
+      53             :   friend void add( const Value& val1, Value* valout );
+      54             : /// This calculates val1*val2 and sorts out the derivatives
+      55             :   friend void product( const Value& val1, const Value& val2, Value& valout );
+      56             : /// This calculates va1/val2 and sorts out the derivatives
+      57             :   friend void quotient( const Value& val1, const Value& val2, Value* valout );
+      58             : private:
+      59             : /// The action in which this quantity is calculated
+      60             :   ActionWithValue* action;
+      61             : /// Had the value been set
+      62             :   bool value_set;
+      63             : /// The value of the quantity
+      64             :   double value;
+      65             : /// The force acting on this quantity
+      66             :   double inputForce;
+      67             : /// A flag telling us we have a force acting on this quantity
+      68             :   bool hasForce;
+      69             : /// The derivatives of the quantity stored in value
+      70             :   std::vector<double> derivatives;
+      71             :   std::map<AtomNumber,Vector> gradients;
+      72             : /// The name of this quantiy
+      73             :   std::string name;
+      74             : /// Does this quanity have derivatives
+      75             :   bool hasDeriv;
+      76             : /// Is this quantity periodic
+      77             :   enum {unset,periodic,notperiodic} periodicity;
+      78             : /// Various quantities that describe the domain of this value
+      79             :   std::string str_min, str_max;
+      80             :   double min,max;
+      81             :   double max_minus_min;
+      82             :   double inv_max_minus_min;
+      83             : /// Complete the setup of the periodicity
+      84             :   void setupPeriodicity();
+      85             : // bring value within PBCs
+      86             :   void applyPeriodicity();
+      87             : public:
+      88             : /// A constructor that can be used to make Vectors of values
+      89             :   Value();
+      90             : /// A constructor that can be used to make Vectors of named values
+      91             :   explicit Value(const std::string& name);
+      92             : /// A constructor that is used throughout the code to setup the value poiters
+      93             :   Value(ActionWithValue* av, const std::string& name, const bool withderiv);
+      94             : /// Set the value of the function
+      95             :   void set(double);
+      96             : /// Add something to the value of the function
+      97             :   void add(double);
+      98             : /// Get the value of the function
+      99             :   double get() const;
+     100             : /// Find out if the value has been set
+     101             :   bool valueHasBeenSet() const;
+     102             : /// Check if the value is periodic
+     103             :   bool isPeriodic() const;
+     104             : /// Set the function not periodic
+     105             :   void setNotPeriodic();
+     106             : /// Set the domain of the function
+     107             :   void setDomain(const std::string&, const std::string&);
+     108             : /// Get the domain of the quantity
+     109             :   void getDomain(std::string&,std::string&) const;
+     110             : /// Get the domain of the quantity
+     111             :   void getDomain(double&,double&) const;
+     112             : /// Get the name of the quantity
+     113             :   const std::string& getName() const;
+     114             : /// Check whether or not this particular quantity has derivatives
+     115             :   bool hasDerivatives()const;
+     116             : /// Get the number of derivatives that this particular value has
+     117             :   unsigned getNumberOfDerivatives() const;
+     118             : /// Set the number of derivatives
+     119             :   void resizeDerivatives(int n);
+     120             : /// Set all the derivatives to zero
+     121             :   void clearDerivatives();
+     122             : /// Add some derivative to the ith component of the derivatives array
+     123             :   void addDerivative(unsigned i,double d);
+     124             : /// Set the value of the ith component of the derivatives array
+     125             :   void setDerivative(unsigned i, double d);
+     126             : /// Apply the chain rule to the derivatives
+     127             :   void chainRule(double df);
+     128             : /// Get the derivative with respect to component n
+     129             :   double getDerivative(const unsigned n) const;
+     130             : /// Clear the input force on the variable
+     131             :   void clearInputForce();
+     132             : /// Add some force on this value
+     133             :   void  addForce(double f);
+     134             : /// Get the value of the force on this colvar
+     135             :   double getForce() const ;
+     136             : /// Apply the forces to the derivatives using the chain rule (if there are no forces this routine returns false)
+     137             :   bool applyForce( std::vector<double>& forces ) const ;
+     138             : /// Calculate the difference between the instantaneous value of the function and some other point: other_point-inst_val
+     139             :   double difference(double)const;
+     140             : /// Calculate the difference between two values of this function: d2 -d1
+     141             :   double difference(double d1,double d2)const;
+     142             : /// This returns the pointer to the action where this value is calculated
+     143             :   ActionWithValue* getPntrToAction();
+     144             : /// Bring back one value into the correct pbc if needed, else give back the value
+     145             :   double bringBackInPbc(double d1)const;
+     146             : /// Get the difference between max and minimum of domain
+     147             :   double getMaxMinusMin()const;
+     148             : /// This sets up the gradients
+     149             :   void setGradients();
+     150             :   static double projection(const Value&,const Value&);
+     151             : };
+     152             : 
+     153             : void copy( const Value& val1, Value& val2 );
+     154             : void copy( const Value& val1, Value* val2 );
+     155             : void add( const Value& val1, Value* valout );
+     156             : 
+     157             : inline
+     158    44362184 : void Value::applyPeriodicity() {
+     159    44362184 :   if(periodicity==periodic) {
+     160    30706139 :     value=min+difference(min,value);
+     161    30706139 :     if(value<min)value+=max_minus_min;
+     162             :   }
+     163    44362184 : }
+     164             : 
+     165             : inline
+     166             : void product( const Value& val1, const Value& val2, Value& valout ) {
+     167             :   plumed_assert( val1.derivatives.size()==val2.derivatives.size() );
+     168             :   if( valout.derivatives.size()!=val1.derivatives.size() ) valout.resizeDerivatives( val1.derivatives.size() );
+     169             :   valout.value_set=false;
+     170             :   valout.clearDerivatives();
+     171             :   double u=val1.value;
+     172             :   double v=val2.value;
+     173             :   for(unsigned i=0; i<val1.derivatives.size(); ++i) {
+     174             :     valout.addDerivative(i, u*val2.derivatives[i] + v*val1.derivatives[i] );
+     175             :   }
+     176             :   valout.set( u*v );
+     177             : }
+     178             : 
+     179             : inline
+     180             : void quotient( const Value& val1, const Value& val2, Value* valout ) {
+     181             :   plumed_assert( val1.derivatives.size()==val2.derivatives.size() );
+     182             :   if( valout->derivatives.size()!=val1.derivatives.size() ) valout->resizeDerivatives( val1.derivatives.size() );
+     183             :   valout->value_set=false;
+     184             :   valout->clearDerivatives();
+     185             :   double u=val1.get();
+     186             :   double v=val2.get();
+     187             :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) {
+     188             :     valout->addDerivative(i, v*val1.getDerivative(i) - u*val2.getDerivative(i) );
+     189             :   }
+     190             :   valout->chainRule( 1/(v*v) ); valout->set( u / v );
+     191             : }
+     192             : 
+     193             : inline
+     194             : void Value::set(double v) {
+     195    44351474 :   value_set=true;
+     196    44351474 :   value=v;
+     197    44162711 :   applyPeriodicity();
+     198    42537046 : }
+     199             : 
+     200             : inline
+     201             : void Value::add(double v) {
+     202             :   value_set=true;
+     203             :   value+=v;
+     204             :   applyPeriodicity();
+     205             : }
+     206             : 
+     207             : inline
+     208             : double Value::get()const {
+     209     3224161 :   return value;
+     210             : }
+     211             : 
+     212             : inline
+     213             : bool Value::valueHasBeenSet() const {
+     214           0 :   return value_set;
+     215             : }
+     216             : 
+     217             : inline
+     218             : const std::string& Value::getName()const {
+     219     8263238 :   return name;
+     220             : }
+     221             : 
+     222             : inline
+     223      329575 : unsigned Value::getNumberOfDerivatives() const {
+     224      329575 :   plumed_massert(hasDeriv,"the derivatives array for this value has zero size");
+     225      329575 :   return derivatives.size();
+     226             : }
+     227             : 
+     228             : inline
+     229             : double Value::getDerivative(const unsigned n) const {
+     230             :   plumed_dbg_massert(n<derivatives.size(),"you are asking for a derivative that is out of bounds");
+     231    19967312 :   return derivatives[n];
+     232             : }
+     233             : 
+     234             : inline
+     235             : bool Value::hasDerivatives() const {
+     236       13272 :   return hasDeriv;
+     237             : }
+     238             : 
+     239             : inline
+     240             : void Value::resizeDerivatives(int n) {
+     241  4102750470 :   if(hasDeriv) derivatives.resize(n);
+     242             : }
+     243             : 
+     244             : inline
+     245             : void Value::addDerivative(unsigned i,double d) {
+     246             :   plumed_dbg_massert(i<derivatives.size(),"derivative is out of bounds");
+     247    22368600 :   derivatives[i]+=d;
+     248          10 : }
+     249             : 
+     250             : inline
+     251             : void Value::setDerivative(unsigned i, double d) {
+     252             :   plumed_dbg_massert(i<derivatives.size(),"derivative is out of bounds");
+     253       63116 :   derivatives[i]=d;
+     254             : }
+     255             : 
+     256             : inline
+     257         434 : void Value::chainRule(double df) {
+     258       18368 :   for(unsigned i=0; i<derivatives.size(); ++i) derivatives[i]*=df;
+     259         434 : }
+     260             : 
+     261             : inline
+     262             : void Value::clearInputForce() {
+     263     2081053 :   hasForce=false;
+     264     2081053 :   inputForce=0.0;
+     265             : }
+     266             : 
+     267             : inline
+     268             : void Value::clearDerivatives() {
+     269        2523 :   value_set=false;
+     270             :   std::fill(derivatives.begin(), derivatives.end(), 0);
+     271             : }
+     272             : 
+     273             : inline
+     274             : void Value::addForce(double f) {
+     275             :   plumed_dbg_massert(hasDerivatives(),"forces can only be added to values with derivatives");
+     276      188450 :   hasForce=true;
+     277      188450 :   inputForce+=f;
+     278        2623 : }
+     279             : 
+     280             : inline
+     281             : double Value::getForce() const {
+     282        4823 :   return inputForce;
+     283             : }
+     284             : /// d2-d1
+     285             : inline
+     286   155957917 : double Value::difference(double d1,double d2)const {
+     287   155957917 :   if(periodicity==notperiodic) {
+     288    90589150 :     return d2-d1;
+     289    65368767 :   } else if(periodicity==periodic) {
+     290    65368767 :     double s=(d2-d1)*inv_max_minus_min;
+     291             :     // remember: pbc brings the difference in a range of -0.5:0.5
+     292    65368767 :     s=Tools::pbc(s);
+     293    65368767 :     return s*max_minus_min;
+     294           0 :   } else plumed_merror("periodicity should be set to compute differences");
+     295             : }
+     296             : 
+     297             : inline
+     298        3173 : double Value::bringBackInPbc(double d1)const {
+     299        3173 :   return min+max_minus_min/2.+difference(min+max_minus_min/2., d1);
+     300             : }
+     301             : 
+     302             : inline
+     303             : double Value::difference(double d)const {
+     304   119526971 :   return difference(get(),d);
+     305             : }
+     306             : 
+     307             : inline
+     308             : double Value::getMaxMinusMin()const {
+     309             :   plumed_dbg_assert( periodicity==periodic );
+     310         518 :   return max_minus_min;
+     311             : }
+     312             : 
+     313             : }
+     314             : 
+     315             : #endif
+     316             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..fcdc6b249c --- /dev/null +++ b/coverage/core/WithCmd.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + 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:33100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrEmPKm226212
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/WithCmd.h.func.html b/coverage/core/WithCmd.h.func.html new file mode 100644 index 0000000000..06a1b50b08 --- /dev/null +++ b/coverage/core/WithCmd.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + 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:33100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrEmPKm226212
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/WithCmd.h.gcov.html b/coverage/core/WithCmd.h.gcov.html new file mode 100644 index 0000000000..9f7a7f4b45 --- /dev/null +++ b/coverage/core/WithCmd.h.gcov.html @@ -0,0 +1,130 @@ + + + + + + + + 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:33100.0 %
Date:2024-06-10 08:19:14Functions: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             : #ifndef __PLUMED_core_WithCmd_h
+      23             : #define __PLUMED_core_WithCmd_h
+      24             : 
+      25             : #include "tools/TypesafePtr.h"
+      26             : #include <string>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : /// Base for classes with cmd() method.
+      31             : /// This is an abstract base class for classes with
+      32             : /// cmd() method.
+      33             : class WithCmd {
+      34             : public:
+      35             :   virtual void cmd(const std::string& key,const TypesafePtr & val=nullptr)=0;
+      36             :   void cmd(const std::string& key,const TypesafePtr & val,const std::size_t* shape) {
+      37             :     cmd(key,TypesafePtr::setNelemAndShape(val,0,shape));
+      38             :   }
+      39      226212 :   void cmd(const std::string& key,const TypesafePtr & val,std::size_t nelem, const std::size_t* shape=nullptr) {
+      40      226212 :     cmd(key,TypesafePtr::setNelemAndShape(val,nelem,shape));
+      41      226212 :   }
+      42             :   virtual ~WithCmd();
+      43             : };
+      44             : 
+      45             : inline
+      46             : WithCmd::~WithCmd() {
+      47             : // do nothing
+      48             : // here just to allow inheriting from this class properly
+      49             : }
+      50             : 
+      51             : }
+      52             : 
+      53             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/index-sort-f.html b/coverage/core/index-sort-f.html new file mode 100644 index 0000000000..c556931e89 --- /dev/null +++ b/coverage/core/index-sort-f.html @@ -0,0 +1,524 @@ + + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:3026353785.6 %
Date:2024-06-10 08:19:14Functions:40750980.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
ActionShortcut.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
TargetDist.cpp +
0.0%
+
0.0 %0 / 270.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
MDAtoms.cpp +
91.3%91.3%
+
91.3 %158 / 17349.2 %30 / 61
DataFetchingObject.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
ActionSetup.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
ActionShortcut.cpp +
77.8%77.8%
+
77.8 %21 / 2766.7 %4 / 6
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %46 / 4675.0 %9 / 12
GenericMolInfo.cpp +
81.6%81.6%
+
81.6 %151 / 18576.5 %13 / 17
ActionAtomistic.cpp +
91.8%91.8%
+
91.8 %168 / 18377.3 %17 / 22
CLTool.h +
70.6%70.6%
+
70.6 %24 / 3478.6 %11 / 14
Action.cpp +
78.1%78.1%
+
78.1 %121 / 15580.6 %25 / 31
DataFetchingObject.cpp +
68.1%68.1%
+
68.1 %47 / 6981.2 %13 / 16
Value.cpp +
86.6%86.6%
+
86.6 %103 / 11981.2 %13 / 16
PlumedMainInitializer.cpp +
71.3%71.3%
+
71.3 %102 / 14381.8 %9 / 11
ActionPilot.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
Colvar.cpp +
100.0%
+
100.0 %42 / 4283.3 %5 / 6
ActionWithValue.cpp +
89.5%89.5%
+
89.5 %111 / 12483.3 %25 / 30
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
ActionWithValue.h +
95.5%95.5%
+
95.5 %21 / 2285.7 %6 / 7
ActionSet.h +
100.0%
+
100.0 %18 / 1887.5 %21 / 24
CLToolRegister.cpp +
67.2%67.2%
+
67.2 %39 / 5890.0 %9 / 10
ActionRegister.cpp +
68.9%68.9%
+
68.9 %42 / 6190.0 %9 / 10
CLTool.cpp +
85.0%85.0%
+
85.0 %85 / 10090.0 %9 / 10
ActionWithArguments.cpp +
91.4%91.4%
+
91.4 %148 / 16291.7 %11 / 12
PlumedMain.cpp +
90.9%90.9%
+
90.9 %597 / 65794.4 %34 / 36
Atoms.cpp +
95.2%95.2%
+
95.2 %374 / 39394.5 %52 / 55
Action.h +
95.7%95.7%
+
95.7 %66 / 6996.2 %25 / 26
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
PlumedMain.h +
93.8%93.8%
+
93.8 %15 / 16-0 / 0
ActionWithVirtualAtom.h +
100.0%
+
100.0 %8 / 8-0 / 0
WithCmd.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
Atoms.h +
95.8%95.8%
+
95.8 %23 / 24100.0 %2 / 2
ActionSet.cpp +
100.0%
+
100.0 %10 / 10100.0 %3 / 3
ActionAtomistic.h +
100.0%
+
100.0 %32 / 32100.0 %4 / 4
Value.h +
95.3%95.3%
+
95.3 %41 / 43100.0 %5 / 5
CLToolMain.cpp +
80.7%80.7%
+
80.7 %109 / 135100.0 %5 / 5
ActionWithArguments.h +
100.0%
+
100.0 %15 / 15100.0 %5 / 5
GREX.cpp +
73.6%73.6%
+
73.6 %103 / 140100.0 %6 / 6
Colvar.h +
100.0%
+
100.0 %29 / 29100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/index-sort-l.html b/coverage/core/index-sort-l.html new file mode 100644 index 0000000000..8f77cc708f --- /dev/null +++ b/coverage/core/index-sort-l.html @@ -0,0 +1,524 @@ + + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:3026353785.6 %
Date:2024-06-10 08:19:14Functions:40750980.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionShortcut.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
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
ActionAnyorder.cpp +
50.0%50.0%
+
50.0 %3 / 633.3 %1 / 3
CLToolRegister.cpp +
67.2%67.2%
+
67.2 %39 / 5890.0 %9 / 10
DataFetchingObject.cpp +
68.1%68.1%
+
68.1 %47 / 6981.2 %13 / 16
ActionRegister.cpp +
68.9%68.9%
+
68.9 %42 / 6190.0 %9 / 10
CLTool.h +
70.6%70.6%
+
70.6 %24 / 3478.6 %11 / 14
PlumedMainInitializer.cpp +
71.3%71.3%
+
71.3 %102 / 14381.8 %9 / 11
GREX.cpp +
73.6%73.6%
+
73.6 %103 / 140100.0 %6 / 6
ActionShortcut.cpp +
77.8%77.8%
+
77.8 %21 / 2766.7 %4 / 6
Action.cpp +
78.1%78.1%
+
78.1 %121 / 15580.6 %25 / 31
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
CLToolMain.cpp +
80.7%80.7%
+
80.7 %109 / 135100.0 %5 / 5
GenericMolInfo.cpp +
81.6%81.6%
+
81.6 %151 / 18576.5 %13 / 17
CLTool.cpp +
85.0%85.0%
+
85.0 %85 / 10090.0 %9 / 10
Value.cpp +
86.6%86.6%
+
86.6 %103 / 11981.2 %13 / 16
ActionWithValue.cpp +
89.5%89.5%
+
89.5 %111 / 12483.3 %25 / 30
PlumedMain.cpp +
90.9%90.9%
+
90.9 %597 / 65794.4 %34 / 36
ActionWithArguments.cpp +
91.4%91.4%
+
91.4 %148 / 16291.7 %11 / 12
MDAtoms.cpp +
91.3%91.3%
+
91.3 %158 / 17349.2 %30 / 61
ActionAtomistic.cpp +
91.8%91.8%
+
91.8 %168 / 18377.3 %17 / 22
PlumedMain.h +
93.8%93.8%
+
93.8 %15 / 16-0 / 0
Atoms.cpp +
95.2%95.2%
+
95.2 %374 / 39394.5 %52 / 55
Value.h +
95.3%95.3%
+
95.3 %41 / 43100.0 %5 / 5
ActionWithValue.h +
95.5%95.5%
+
95.5 %21 / 2285.7 %6 / 7
Action.h +
95.7%95.7%
+
95.7 %66 / 6996.2 %25 / 26
Atoms.h +
95.8%95.8%
+
95.8 %23 / 24100.0 %2 / 2
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
DataFetchingObject.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
WithCmd.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
ActionWithVirtualAtom.h +
100.0%
+
100.0 %8 / 8-0 / 0
ActionSet.cpp +
100.0%
+
100.0 %10 / 10100.0 %3 / 3
ActionSetup.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
ActionPilot.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
ActionWithArguments.h +
100.0%
+
100.0 %15 / 15100.0 %5 / 5
ActionSet.h +
100.0%
+
100.0 %18 / 1887.5 %21 / 24
Colvar.h +
100.0%
+
100.0 %29 / 29100.0 %7 / 7
ActionAtomistic.h +
100.0%
+
100.0 %32 / 32100.0 %4 / 4
Colvar.cpp +
100.0%
+
100.0 %42 / 4283.3 %5 / 6
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %46 / 4675.0 %9 / 12
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/core/index.html b/coverage/core/index.html new file mode 100644 index 0000000000..e72a236df7 --- /dev/null +++ b/coverage/core/index.html @@ -0,0 +1,524 @@ + + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:3026353785.6 %
Date:2024-06-10 08:19:14Functions:40750980.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Action.cpp +
78.1%78.1%
+
78.1 %121 / 15580.6 %25 / 31
Action.h +
95.7%95.7%
+
95.7 %66 / 6996.2 %25 / 26
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 +
91.8%91.8%
+
91.8 %168 / 18377.3 %17 / 22
ActionAtomistic.h +
100.0%
+
100.0 %32 / 32100.0 %4 / 4
ActionPilot.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
ActionRegister.cpp +
68.9%68.9%
+
68.9 %42 / 6190.0 %9 / 10
ActionSet.cpp +
100.0%
+
100.0 %10 / 10100.0 %3 / 3
ActionSet.h +
100.0%
+
100.0 %18 / 1887.5 %21 / 24
ActionSetup.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
ActionSetup.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionShortcut.cpp +
77.8%77.8%
+
77.8 %21 / 2766.7 %4 / 6
ActionShortcut.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
ActionWithArguments.cpp +
91.4%91.4%
+
91.4 %148 / 16291.7 %11 / 12
ActionWithArguments.h +
100.0%
+
100.0 %15 / 15100.0 %5 / 5
ActionWithValue.cpp +
89.5%89.5%
+
89.5 %111 / 12483.3 %25 / 30
ActionWithValue.h +
95.5%95.5%
+
95.5 %21 / 2285.7 %6 / 7
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %46 / 4675.0 %9 / 12
ActionWithVirtualAtom.h +
100.0%
+
100.0 %8 / 8-0 / 0
Atoms.cpp +
95.2%95.2%
+
95.2 %374 / 39394.5 %52 / 55
Atoms.h +
95.8%95.8%
+
95.8 %23 / 24100.0 %2 / 2
CLTool.cpp +
85.0%85.0%
+
85.0 %85 / 10090.0 %9 / 10
CLTool.h +
70.6%70.6%
+
70.6 %24 / 3478.6 %11 / 14
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 %42 / 4283.3 %5 / 6
Colvar.h +
100.0%
+
100.0 %29 / 29100.0 %7 / 7
DataFetchingObject.cpp +
68.1%68.1%
+
68.1 %47 / 6981.2 %13 / 16
DataFetchingObject.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
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 +
73.6%73.6%
+
73.6 %103 / 140100.0 %6 / 6
GenericMolInfo.cpp +
81.6%81.6%
+
81.6 %151 / 18576.5 %13 / 17
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
MDAtoms.cpp +
91.3%91.3%
+
91.3 %158 / 17349.2 %30 / 61
PlumedMain.cpp +
90.9%90.9%
+
90.9 %597 / 65794.4 %34 / 36
PlumedMain.h +
93.8%93.8%
+
93.8 %15 / 16-0 / 0
PlumedMainInitializer.cpp +
71.3%71.3%
+
71.3 %102 / 14381.8 %9 / 11
TargetDist.cpp +
0.0%
+
0.0 %0 / 270.0 %0 / 3
Value.cpp +
86.6%86.6%
+
86.6 %103 / 11981.2 %13 / 16
Value.h +
95.3%95.3%
+
95.3 %41 / 43100.0 %5 / 5
WithCmd.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e6cda6c899 --- /dev/null +++ b/coverage/crystallization/BondOrientation.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:525791.2 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization15BondOrientationC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe506createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization15BondOrientationC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization15BondOrientation16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD15crystallization15BondOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE60
_ZNK4PLMD15crystallization15BondOrientation15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE150
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe50C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe50D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/BondOrientation.cpp.func.html b/coverage/crystallization/BondOrientation.cpp.func.html new file mode 100644 index 0000000000..8261c073ae --- /dev/null +++ b/coverage/crystallization/BondOrientation.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:525791.2 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe506createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe50C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe50D2Ev3473
_ZN4PLMD15crystallization15BondOrientation16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization15BondOrientationC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization15BondOrientationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization15BondOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE60
_ZNK4PLMD15crystallization15BondOrientation15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE150
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/BondOrientation.cpp.gcov.html b/coverage/crystallization/BondOrientation.cpp.gcov.html new file mode 100644 index 0000000000..f9fb60b5a0 --- /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:525791.2 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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       10423 : PLUMED_REGISTER_ACTION(BondOrientation,"BOND_DIRECTIONS")
+      51             : 
+      52           3 : void BondOrientation::registerKeywords( Keywords& keys ) {
+      53           3 :   VectorMultiColvar::registerKeywords( keys );
+      54           6 :   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           6 :   keys.reset_style("ATOMS","atoms");
+      60           6 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+      61           6 :   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           6 :   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           6 :   keys.add("compulsory","NN","12","The n parameter of the switching function ");
+      66           6 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      67           6 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      68           6 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      69           6 :   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           6 :   keys.use("VMEAN"); keys.use("VSUM");
+      73           3 : }
+      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.15
+
+ + + 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 0000000000..e9f2b30d97 --- /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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17CubicHarmonicBaseC2ERKNS_13ActionOptionsE6
_ZN4PLMD15crystallization17CubicHarmonicBase16registerKeywordsERNS_8KeywordsE9
_ZNK4PLMD15crystallization17CubicHarmonicBase7computeERKjRNS_11multicolvar13AtomValuePackE26142
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.cpp.func.html b/coverage/crystallization/CubicHarmonicBase.cpp.func.html new file mode 100644 index 0000000000..9b27a6237b --- /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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBase16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD15crystallization17CubicHarmonicBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17CubicHarmonicBaseC2ERKNS_13ActionOptionsE6
_ZNK4PLMD15crystallization17CubicHarmonicBase7computeERKjRNS_11multicolvar13AtomValuePackE26142
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.cpp.gcov.html b/coverage/crystallization/CubicHarmonicBase.cpp.gcov.html new file mode 100644 index 0000000000..90ca7df104 --- /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-06-10 08:19:14Functions: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           9 : void CubicHarmonicBase::registerKeywords( Keywords& keys ) {
+      34           9 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      35          27 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+      36          18 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      37          18 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      38          18 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      39          18 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      40          18 :   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          18 :   keys.add("compulsory","PHI","0.0","The Euler rotational angle phi");
+      44          18 :   keys.add("compulsory","THETA","0.0","The Euler rotational angle theta");
+      45          18 :   keys.add("compulsory","PSI","0.0","The Euler rotational angle psi");
+      46          18 :   keys.addFlag("UNORMALIZED",false,"calculate the sum of the components of the vector rather than the mean");
+      47             :   // Use actionWithDistributionKeywords
+      48          36 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+      49          36 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      50          27 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      51           9 : }
+      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.15
+
+ + + 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 0000000000..8138f58698 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBase10isPeriodicEv7
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.h.func.html b/coverage/crystallization/CubicHarmonicBase.h.func.html new file mode 100644 index 0000000000..52109d871e --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBase10isPeriodicEv7
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.h.gcov.html b/coverage/crystallization/CubicHarmonicBase.h.gcov.html new file mode 100644 index 0000000000..1a0c8b8192 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..0eb59efa9f --- /dev/null +++ b/coverage/crystallization/EnvironmentSimilarity.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:18419793.4 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization21EnvironmentSimilarityC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe1786createERKNS_13ActionOptionsE9
_ZN4PLMD15crystallization21EnvironmentSimilarity26parseReferenceEnvironmentsERSt6vectorIS2_INS_13VectorGenericILj3EEESaIS4_EESaIS6_EERd9
_ZN4PLMD15crystallization21EnvironmentSimilarityC1ERKNS_13ActionOptionsE9
_ZN4PLMD15crystallization21EnvironmentSimilarity16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD15crystallization21EnvironmentSimilarity11maxDistanceESt6vectorINS_13VectorGenericILj3EEESaIS4_EE13
_ZN4PLMD15crystallization21EnvironmentSimilarity10isPeriodicEv15
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe178C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe178D2Ev3473
_ZNK4PLMD15crystallization21EnvironmentSimilarity7computeERKjRNS_11multicolvar13AtomValuePackE30048
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/EnvironmentSimilarity.cpp.func.html b/coverage/crystallization/EnvironmentSimilarity.cpp.func.html new file mode 100644 index 0000000000..6b402fd778 --- /dev/null +++ b/coverage/crystallization/EnvironmentSimilarity.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:18419793.4 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe1786createERKNS_13ActionOptionsE9
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe178C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe178D2Ev3473
_ZN4PLMD15crystallization21EnvironmentSimilarity10isPeriodicEv15
_ZN4PLMD15crystallization21EnvironmentSimilarity11maxDistanceESt6vectorINS_13VectorGenericILj3EEESaIS4_EE13
_ZN4PLMD15crystallization21EnvironmentSimilarity16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD15crystallization21EnvironmentSimilarity26parseReferenceEnvironmentsERSt6vectorIS2_INS_13VectorGenericILj3EEESaIS4_EESaIS6_EERd9
_ZN4PLMD15crystallization21EnvironmentSimilarityC1ERKNS_13ActionOptionsE9
_ZN4PLMD15crystallization21EnvironmentSimilarityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization21EnvironmentSimilarity7computeERKjRNS_11multicolvar13AtomValuePackE30048
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html b/coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html new file mode 100644 index 0000000000..7b45c7c3c9 --- /dev/null +++ b/coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html @@ -0,0 +1,534 @@ + + + + + + + + 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:18419793.4 %
Date:2024-06-10 08:19:14Functions:91090.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             : 
+      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             : \par Examples
+     100             : 
+     101             : The following input calculates the ENVIRONMENTSIMILARITY kernel for 250 atoms in the system
+     102             : using the BCC atomic environment as target, and then calculates and prints the average value
+     103             :  for this quantity.
+     104             : 
+     105             : \plumedfile
+     106             : ENVIRONMENTSIMILARITY SPECIES=1-250 SIGMA=0.05 LATTICE_CONSTANTS=0.423 CRYSTAL_STRUCTURE=BCC MEAN LABEL=es
+     107             : 
+     108             : PRINT ARG=es.mean FILE=COLVAR
+     109             : \endplumedfile
+     110             : 
+     111             : The next example compares the environments of the 96 selected atoms with a user specified reference
+     112             : environment. The reference environment is contained in the env1.pdb file. Once the kernel is computed
+     113             :  the average and the number of atoms with a kernel larger than 0.5 are computed.
+     114             : 
+     115             : \plumedfile
+     116             : ENVIRONMENTSIMILARITY ...
+     117             :  SPECIES=1-288:3
+     118             :  SIGMA=0.05
+     119             :  CRYSTAL_STRUCTURE=CUSTOM
+     120             :  REFERENCE=env1.pdb
+     121             :  LABEL=es
+     122             :  MEAN
+     123             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     124             : ... ENVIRONMENTSIMILARITY
+     125             : 
+     126             : PRINT ARG=es.mean,es.morethan FILE=COLVAR
+     127             : \endplumedfile
+     128             : 
+     129             : The next example is similar to the one above but in this case 4 reference environments are specified.
+     130             :  Each reference environment is given in a separate pdb file.
+     131             : 
+     132             : \plumedfile
+     133             : ENVIRONMENTSIMILARITY ...
+     134             :  SPECIES=1-288:3
+     135             :  SIGMA=0.05
+     136             :  CRYSTAL_STRUCTURE=CUSTOM
+     137             :  REFERENCE_1=env1.pdb
+     138             :  REFERENCE_2=env2.pdb
+     139             :  REFERENCE_3=env3.pdb
+     140             :  REFERENCE_4=env4.pdb
+     141             :  LABEL=es
+     142             :  MEAN
+     143             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     144             : ... ENVIRONMENTSIMILARITY
+     145             : 
+     146             : PRINT ARG=es.mean,es.morethan FILE=COLVAR
+     147             : \endplumedfile
+     148             : 
+     149             : */
+     150             : //+ENDPLUMEDOC
+     151             : 
+     152             : 
+     153             : class EnvironmentSimilarity : public multicolvar::MultiColvarBase {
+     154             : private:
+     155             :   // All global variables end with underscore
+     156             :   // square of cutoff, square of broadening parameter
+     157             :   double rcut2_, sigmaSqr_;
+     158             :   // lambda parameter for softmax function
+     159             :   double lambda_;
+     160             :   // Array of Vectors to store the reference environments, i.e. the templates
+     161             :   std::vector<std::vector<Vector>> environments_;
+     162             : public:
+     163             :   static void registerKeywords( Keywords& keys );
+     164             :   explicit EnvironmentSimilarity(const ActionOptions&);
+     165             : // active methods:
+     166             :   virtual double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const ;
+     167             : // Returns the number of coordinates of the field
+     168          15 :   bool isPeriodic() { return false; }
+     169             : // Calculates maximum distance in an environment
+     170             :   double maxDistance(std::vector<Vector> environment);
+     171             :   // Parse everything connected to the definition of the reference environments
+     172             :   // First argument is the array of Vectors that stores the reference environments
+     173             :   // Second argument is the maximum distance in the ref environments and sets the
+     174             :   // cutoff for the cell lists
+     175             :   void parseReferenceEnvironments( std::vector<std::vector<Vector>>& environments, double& max_dist);
+     176             : };
+     177             : 
+     178       10437 : PLUMED_REGISTER_ACTION(EnvironmentSimilarity,"ENVIRONMENTSIMILARITY")
+     179             : 
+     180          10 : void EnvironmentSimilarity::registerKeywords( Keywords& keys ) {
+     181          10 :   MultiColvarBase::registerKeywords( keys );
+     182          30 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+     183          20 :   keys.add("compulsory","SIGMA","0.1","Broadening parameter");
+     184          30 :   keys.add("compulsory","CRYSTAL_STRUCTURE","FCC","Targeted crystal structure. Options are: "
+     185             :            "SC: simple cubic, "
+     186             :            "BCC: body center cubic, "
+     187             :            "FCC: face centered cubic, "
+     188             :            "HCP: hexagonal closed pack, "
+     189             :            "DIAMOND: cubic diamond, "
+     190             :            "CUSTOM: user defined "
+     191             :            " ");
+     192          30 :   keys.add("optional","LATTICE_CONSTANTS","Lattice constants. Two comma separated values for HCP, "
+     193             :            "one value for all other CRYSTAL_STRUCTURES.");
+     194          20 :   keys.add("compulsory","LAMBDA","100","Lambda parameter");
+     195          20 :   keys.add("optional","REFERENCE","PDB file with relative distances from central atom."
+     196             :            " Use this keyword if you are targeting a single reference environment.");
+     197          20 :   keys.add("numbered","REFERENCE_","PDB files with relative distances from central atom."
+     198             :            " Each file corresponds to one template."
+     199             :            " Use these keywords if you are targeting more than one reference environment.");
+     200             :   // Use actionWithDistributionKeywords
+     201          40 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+     202          40 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     203          30 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     204          10 : }
+     205             : 
+     206           9 : EnvironmentSimilarity::EnvironmentSimilarity(const ActionOptions&ao):
+     207             :   Action(ao),
+     208           9 :   MultiColvarBase(ao)
+     209             : {
+     210           9 :   log.printf("  Please read and cite ");
+     211          18 :   log << plumed.cite("Piaggi and Parrinello, J. Chem. Phys. 150 (24), 244119 (2019)");
+     212           9 :   log.printf("\n");
+     213             : 
+     214             :   // Parse everything connected to the definition of the reference environments
+     215             :   double max_dist_ref_vector;
+     216           9 :   parseReferenceEnvironments(environments_, max_dist_ref_vector);
+     217             : 
+     218             :   double sigma;
+     219           9 :   parse("SIGMA", sigma);
+     220           9 :   log.printf("  representing local density as a sum of Gaussians with standard deviation %f\n",sigma);
+     221           9 :   sigmaSqr_=sigma*sigma;
+     222             : 
+     223           9 :   lambda_=100;
+     224          18 :   parse("LAMBDA", lambda_);
+     225           9 :   if (environments_.size()>1) log.printf("  using a soft max function with lambda %f\n",lambda_);
+     226             : 
+     227             :   // Set the link cell cutoff
+     228           9 :   double rcut = max_dist_ref_vector + 3*sigma;
+     229           9 :   setLinkCellCutoff( rcut );
+     230           9 :   rcut2_ = rcut * rcut;
+     231             : 
+     232             :   // And setup the ActionWithVessel
+     233           9 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms ); checkRead();
+     234           9 : }
+     235             : 
+     236       30048 : double EnvironmentSimilarity::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     237       30048 :   if (environments_.size()==1) {
+     238             :     // One reference environment case
+     239      155464 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     240             :       Vector& distance=myatoms.getPosition(i);
+     241             :       double d2;
+     242      232452 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     243       77840 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     244      194068 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     245             :            d2>epsilon ) {
+     246             :         // Iterate over atoms in the reference environment
+     247      236856 :         for(unsigned k=0; k<environments_[0].size(); ++k) {
+     248      220400 :           Vector distanceFromRef=distance-environments_[0][k];
+     249      220400 :           double value = std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[0].size() ;
+     250             :           // CAREFUL! Off-diagonal virial is incorrect. Do not perform NPT simulations with flexible box angles.
+     251      220400 :           accumulateSymmetryFunction( 1, i, value, -(value/(2*sigmaSqr_))*distanceFromRef, (value/(2*sigmaSqr_))*Tensor(distance,distanceFromRef), myatoms );
+     252             :         }
+     253             :       }
+     254             :     }
+     255             :     return myatoms.getValue(1);
+     256             :   } else {
+     257             :     // More than one reference environment case
+     258       29196 :     std::vector<double> values(environments_.size()); //value for each template
+     259             :     // First time calculate sums
+     260     2808756 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     261             :       Vector& distance=myatoms.getPosition(i);
+     262             :       double d2;
+     263     4534472 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     264     1754912 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     265     3469608 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     266             :            d2>epsilon ) {
+     267             :         // Iterate over templates
+     268     1216388 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     269             :           // Iterate over atoms in the template
+     270     4893780 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     271     3921936 :             Vector distanceFromRef=distance-environments_[j][k];
+     272     3921936 :             values[j] += std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     273             :           }
+     274             :         }
+     275             :       }
+     276             :     }
+     277             :     double sum=0;
+     278      145188 :     for(unsigned j=0; j<environments_.size(); ++j) {
+     279      115992 :       values[j] = std::exp(lambda_*values[j]);
+     280      115992 :       sum += values[j];
+     281             :     }
+     282             :     // Second time find derivatives
+     283     2808756 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     284             :       Vector& distance=myatoms.getPosition(i);
+     285             :       double d2;
+     286     4534472 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     287     1754912 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     288     3469608 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     289             :            d2>epsilon ) {
+     290             :         // Iterate over reference environment
+     291     1216388 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     292             :           // Iterate over atoms in the reference environment
+     293     4893780 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     294     3921936 :             Vector distanceFromRef=distance-environments_[j][k];
+     295     3921936 :             double value = std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     296     3921936 :             accumulateSymmetryFunction( 1, i, value, -(values[j]/sum)*(value/(2*sigmaSqr_))*distanceFromRef, (values[j]/sum)*(value/(2*sigmaSqr_))*Tensor(distance,distanceFromRef), myatoms );
+     297             :           }
+     298             :         }
+     299             :       }
+     300             :     }
+     301       29196 :     if(sum==0) sum=std::numeric_limits<double>::min();
+     302       29196 :     return std::log(sum)/lambda_;
+     303             :   }
+     304             : }
+     305             : 
+     306          13 : double EnvironmentSimilarity::maxDistance( std::vector<Vector> environment ) {
+     307             :   double max_dist = 0.0;
+     308          65 :   for(unsigned i=0; i<environment.size(); ++i) {
+     309          52 :     double norm=environment[i].modulo();
+     310          52 :     if (norm>max_dist) max_dist=norm;
+     311             :   }
+     312          13 :   return max_dist;
+     313             : }
+     314             : 
+     315           9 : void EnvironmentSimilarity::parseReferenceEnvironments( std::vector<std::vector<Vector>>& environments, double& max_dist) {
+     316             :   std::vector<double> lattice_constants;
+     317          18 :   parseVector("LATTICE_CONSTANTS", lattice_constants);
+     318             :   std::string crystal_structure;
+     319          18 :   parse("CRYSTAL_STRUCTURE", crystal_structure);
+     320             :   // find crystal structure
+     321           9 :   if (crystal_structure == "FCC") {
+     322           1 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for FCC");
+     323           1 :     environments.resize(1);
+     324           1 :     environments[0].resize(12);
+     325           1 :     environments[0][0]  = Vector(+0.5,+0.5,+0.0)*lattice_constants[0];
+     326           1 :     environments[0][1]  = Vector(-0.5,-0.5,+0.0)*lattice_constants[0];
+     327           1 :     environments[0][2]  = Vector(+0.5,-0.5,+0.0)*lattice_constants[0];
+     328           1 :     environments[0][3]  = Vector(-0.5,+0.5,+0.0)*lattice_constants[0];
+     329           1 :     environments[0][4]  = Vector(+0.5,+0.0,+0.5)*lattice_constants[0];
+     330           1 :     environments[0][5]  = Vector(-0.5,+0.0,-0.5)*lattice_constants[0];
+     331           1 :     environments[0][6]  = Vector(-0.5,+0.0,+0.5)*lattice_constants[0];
+     332           1 :     environments[0][7]  = Vector(+0.5,+0.0,-0.5)*lattice_constants[0];
+     333           1 :     environments[0][8]  = Vector(+0.0,+0.5,+0.5)*lattice_constants[0];
+     334           1 :     environments[0][9]  = Vector(+0.0,-0.5,-0.5)*lattice_constants[0];
+     335           1 :     environments[0][10] = Vector(+0.0,-0.5,+0.5)*lattice_constants[0];
+     336           1 :     environments[0][11] = Vector(+0.0,+0.5,-0.5)*lattice_constants[0];
+     337           1 :     max_dist = std::sqrt(2)*lattice_constants[0]/2.;
+     338           8 :   } else if (crystal_structure == "SC") {
+     339           0 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for SC");
+     340           0 :     environments.resize(1);
+     341           0 :     environments[0].resize(6);
+     342           0 :     environments[0][0]  = Vector(+1.0,+0.0,+0.0)*lattice_constants[0];
+     343           0 :     environments[0][1]  = Vector(-1.0,+0.0,+0.0)*lattice_constants[0];
+     344           0 :     environments[0][2]  = Vector(+0.0,+1.0,+0.0)*lattice_constants[0];
+     345           0 :     environments[0][3]  = Vector(+0.0,-1.0,+0.0)*lattice_constants[0];
+     346           0 :     environments[0][4]  = Vector(+0.0,+0.0,+1.0)*lattice_constants[0];
+     347           0 :     environments[0][5]  = Vector(+0.0,+0.0,-1.0)*lattice_constants[0];
+     348           0 :     max_dist = lattice_constants[0];
+     349           8 :   } else if (crystal_structure == "BCC") {
+     350           2 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for BCC");
+     351           2 :     environments.resize(1);
+     352           2 :     environments[0].resize(14);
+     353           2 :     environments[0][0]  = Vector(+0.5,+0.5,+0.5)*lattice_constants[0];
+     354           2 :     environments[0][1]  = Vector(-0.5,-0.5,-0.5)*lattice_constants[0];
+     355           2 :     environments[0][2]  = Vector(-0.5,+0.5,+0.5)*lattice_constants[0];
+     356           2 :     environments[0][3]  = Vector(+0.5,-0.5,+0.5)*lattice_constants[0];
+     357           2 :     environments[0][4]  = Vector(+0.5,+0.5,-0.5)*lattice_constants[0];
+     358           2 :     environments[0][5]  = Vector(-0.5,-0.5,+0.5)*lattice_constants[0];
+     359           2 :     environments[0][6]  = Vector(+0.5,-0.5,-0.5)*lattice_constants[0];
+     360           2 :     environments[0][7]  = Vector(-0.5,+0.5,-0.5)*lattice_constants[0];
+     361           2 :     environments[0][8]  = Vector(+1.0,+0.0,+0.0)*lattice_constants[0];
+     362           2 :     environments[0][9]  = Vector(+0.0,+1.0,+0.0)*lattice_constants[0];
+     363           2 :     environments[0][10] = Vector(+0.0,+0.0,+1.0)*lattice_constants[0];
+     364           2 :     environments[0][11] = Vector(-1.0,+0.0,+0.0)*lattice_constants[0];
+     365           2 :     environments[0][12] = Vector(+0.0,-1.0,+0.0)*lattice_constants[0];
+     366           2 :     environments[0][13] = Vector(+0.0,+0.0,-1.0)*lattice_constants[0];
+     367           2 :     max_dist = lattice_constants[0];
+     368           6 :   } else if (crystal_structure == "HCP") {
+     369           1 :     if (lattice_constants.size() != 2) error("Number of LATTICE_CONSTANTS arguments must be two for HCP");
+     370           1 :     environments.resize(2);
+     371           1 :     environments[0].resize(12);
+     372           1 :     environments[1].resize(12);
+     373             :     double sqrt3=std::sqrt(3);
+     374           1 :     environments[0][0]  = Vector(+0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     375           1 :     environments[0][1]  = Vector(-0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     376           1 :     environments[0][2]  = Vector(+0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     377           1 :     environments[0][3]  = Vector(-0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     378           1 :     environments[0][4]  = Vector(+1.0,+0.0,+0.0)      *lattice_constants[0];
+     379           1 :     environments[0][5]  = Vector(-1.0,+0.0,+0.0)      *lattice_constants[0];
+     380           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];
+     381           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];
+     382           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];
+     383           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];
+     384           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];
+     385           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];
+     386           1 :     environments[1][0]  = Vector(+0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     387           1 :     environments[1][1]  = Vector(-0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     388           1 :     environments[1][2]  = Vector(+0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     389           1 :     environments[1][3]  = Vector(-0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     390           1 :     environments[1][4]  = Vector(+1.0,+0.0,+0.0)      *lattice_constants[0];
+     391           1 :     environments[1][5]  = Vector(-1.0,+0.0,+0.0)      *lattice_constants[0];
+     392           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];
+     393           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];
+     394           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];
+     395           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];
+     396           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];
+     397           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];
+     398           1 :     max_dist = lattice_constants[0];
+     399           5 :   } else if (crystal_structure == "DIAMOND") {
+     400           1 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for DIAMOND");
+     401           1 :     environments.resize(2);
+     402           1 :     environments[0].resize(4); environments[1].resize(4);
+     403           1 :     environments[0][0]  = Vector(+1.0,+1.0,+1.0)*lattice_constants[0]/4.0;
+     404           1 :     environments[0][1]  = Vector(-1.0,-1.0,+1.0)*lattice_constants[0]/4.0;
+     405           1 :     environments[0][2]  = Vector(+1.0,-1.0,-1.0)*lattice_constants[0]/4.0;
+     406           1 :     environments[0][3]  = Vector(-1.0,+1.0,-1.0)*lattice_constants[0]/4.0;
+     407           1 :     environments[1][0]  = Vector(+1.0,-1.0,+1.0)*lattice_constants[0]/4.0;
+     408           1 :     environments[1][1]  = Vector(-1.0,+1.0,+1.0)*lattice_constants[0]/4.0;
+     409           1 :     environments[1][2]  = Vector(+1.0,+1.0,-1.0)*lattice_constants[0]/4.0;
+     410           1 :     environments[1][3]  = Vector(-1.0,-1.0,-1.0)*lattice_constants[0]/4.0;
+     411           1 :     max_dist = std::sqrt(3)*lattice_constants[0]/4.0;
+     412           4 :   } else if (crystal_structure == "CUSTOM") {
+     413             :     std::string reffile;
+     414           8 :     parse("REFERENCE",reffile);
+     415           4 :     if (!reffile.empty()) {
+     416             :       // Case with one reference environment
+     417           1 :       environments.resize(1);
+     418           1 :       PDB pdb;
+     419           2 :       if( !pdb.read(reffile,plumed.getAtoms().usingNaturalUnits(),0.1/plumed.getAtoms().getUnits().getLength()) )
+     420           0 :         error("missing input file " + reffile );
+     421           1 :       unsigned natoms=pdb.getPositions().size(); environments[0].resize( natoms );
+     422           5 :       for(unsigned i=0; i<natoms; ++i) environments[0][i]=pdb.getPositions()[i];
+     423           1 :       max_dist=maxDistance(environments[0]);
+     424           1 :       log.printf("  reading %d reference vectors from %s \n", natoms, reffile.c_str() );
+     425           1 :     } else {
+     426             :       // Case with several reference environments
+     427           3 :       max_dist=0;
+     428          12 :       for(unsigned int i=1;; i++) {
+     429          30 :         if(!parseNumbered("REFERENCE_",i,reffile) ) {break;}
+     430          12 :         PDB pdb;
+     431          24 :         if( !pdb.read(reffile,plumed.getAtoms().usingNaturalUnits(),0.1/plumed.getAtoms().getUnits().getLength()) )
+     432           0 :           error("missing input file " + reffile );
+     433          12 :         unsigned natoms=pdb.getPositions().size();   std::vector<Vector> environment; environment.resize( natoms );
+     434          60 :         for(unsigned i=0; i<natoms; ++i) environment[i]=pdb.getPositions()[i];
+     435          12 :         environments.push_back(environment);
+     436          12 :         double norm = maxDistance(environment);
+     437          12 :         if (norm>max_dist) max_dist=norm;
+     438          12 :         log.printf("  Reference environment %d : reading %d reference vectors from %s \n", i, natoms, reffile.c_str() );
+     439          12 :       }
+     440             :     }
+     441           4 :     if (environments.size()==0) error("No environments have been found! Please specify a PDB file in the REFERENCE "
+     442             :                                         "or in the REFERENCE_1, REFERENCE_2, etc keywords");
+     443           4 :     log.printf("  Number of reference environments is %lu\n",environments.size() );
+     444           4 :     log.printf("  Number of vectors per reference environment is %lu\n",environments[0].size() );
+     445             :   } else {
+     446           0 :     error("CRYSTAL_STRUCTURE=" + crystal_structure + " does not match any structures in the database");
+     447             :   }
+     448             : 
+     449           9 :   log.printf("  targeting the %s crystal structure",crystal_structure.c_str());
+     450           9 :   if (lattice_constants.size()>0) log.printf(" with lattice constants %f\n",lattice_constants[0]);
+     451           4 :   else log.printf("\n");
+     452             : 
+     453           9 :   log.printf("  maximum distance in the reference environment is %f\n",max_dist);
+     454           9 : }
+     455             : 
+     456             : }
+     457             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..735eca308f --- /dev/null +++ b/coverage/crystallization/Fccubic.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2929100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization7FccubicC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe846createERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization7FccubicC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization7Fccubic16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe84C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe84D2Ev3473
_ZNK4PLMD15crystallization7Fccubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_320614
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Fccubic.cpp.func.html b/coverage/crystallization/Fccubic.cpp.func.html new file mode 100644 index 0000000000..a36186c996 --- /dev/null +++ b/coverage/crystallization/Fccubic.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2929100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe846createERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe84C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe84D2Ev3473
_ZN4PLMD15crystallization7Fccubic16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD15crystallization7FccubicC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization7FccubicC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization7Fccubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_320614
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Fccubic.cpp.gcov.html b/coverage/crystallization/Fccubic.cpp.gcov.html new file mode 100644 index 0000000000..23d2ccae6f --- /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:2929100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10427 : PLUMED_REGISTER_ACTION(Fccubic,"FCCUBIC")
+      85             : 
+      86           5 : void Fccubic::registerKeywords( Keywords& keys ) {
+      87           5 :   CubicHarmonicBase::registerKeywords( keys );
+      88          10 :   keys.add("compulsory","ALPHA","3.0","The alpha parameter of the angular function");
+      89           5 : }
+      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.15
+
+ + + 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 0000000000..0100298329 --- /dev/null +++ b/coverage/crystallization/Gradient.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:517171.8 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization8GradientC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe626createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization8GradientC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization8Gradient16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization8Gradient12setupRegionsEv232
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe62C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe62D2Ev3473
_ZNK4PLMD15crystallization8Gradient19calculateAllVolumesERKjRNS_10MultiValueE11600
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Gradient.cpp.func.html b/coverage/crystallization/Gradient.cpp.func.html new file mode 100644 index 0000000000..2ac1d3739c --- /dev/null +++ b/coverage/crystallization/Gradient.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:517171.8 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe626createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe62C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe62D2Ev3473
_ZN4PLMD15crystallization8Gradient12setupRegionsEv232
_ZN4PLMD15crystallization8Gradient16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization8GradientC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization8GradientC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization8Gradient19calculateAllVolumesERKjRNS_10MultiValueE11600
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Gradient.cpp.gcov.html b/coverage/crystallization/Gradient.cpp.gcov.html new file mode 100644 index 0000000000..d7da0a106a --- /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:517171.8 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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       10423 : PLUMED_REGISTER_ACTION(Gradient,"GRADIENT")
+      63             : 
+      64           3 : void Gradient::registerKeywords( Keywords& keys ) {
+      65           3 :   VolumeGradientBase::registerKeywords( keys );
+      66           6 :   keys.add("atoms","ORIGIN","we will use the position of this atom as the origin in our calculation");
+      67           6 :   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           6 :   keys.add("compulsory","NBINS","number of bins to use in each direction for the calculation of the gradient");
+      69           6 :   keys.add("compulsory","SIGMA","1.0","the width of the function to be used for kernel density estimation");
+      70           6 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      71           3 : }
+      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.15
+
+ + + 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 0000000000..e60b684201 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15crystallization8Gradient21getNumberOfQuantitiesEv12064
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Gradient.h.func.html b/coverage/crystallization/Gradient.h.func.html new file mode 100644 index 0000000000..ab4f7051db --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15crystallization8Gradient21getNumberOfQuantitiesEv12064
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Gradient.h.gcov.html b/coverage/crystallization/Gradient.h.gcov.html new file mode 100644 index 0000000000..001d136cc2 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..23f5ffcdd1 --- /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:809584.2 %
Date:2024-06-10 08:19:14Functions: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_124GradientVesselRegisterMeC2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeD2Ev3473
_ZN4PLMD15crystallization14GradientVessel14reserveKeywordERNS_8KeywordsE3473
_ZNK4PLMD15crystallization14GradientVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE11600
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/GradientVessel.cpp.func.html b/coverage/crystallization/GradientVessel.cpp.func.html new file mode 100644 index 0000000000..8b6a4f2131 --- /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:809584.2 %
Date:2024-06-10 08:19:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE2
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeC2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeD2Ev3473
_ZN4PLMD15crystallization14GradientVessel14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD15crystallization14GradientVessel16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization14GradientVessel16value_descriptorB5cxx11Ev2
_ZN4PLMD15crystallization14GradientVessel6finishERKSt6vectorIdSaIdEE232
_ZN4PLMD15crystallization14GradientVessel6resizeEv4
_ZN4PLMD15crystallization14GradientVesselC2ERKNS_10vesselbase13VesselOptionsE2
_ZNK4PLMD15crystallization14GradientVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE11600
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/GradientVessel.cpp.gcov.html b/coverage/crystallization/GradientVessel.cpp.gcov.html new file mode 100644 index 0000000000..8372088c11 --- /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:809584.2 %
Date:2024-06-10 08:19:14Functions: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       10421 : PLUMED_REGISTER_VESSEL(GradientVessel,"GRADIENT")
+      48             : 
+      49           2 : void GradientVessel::registerKeywords( Keywords& keys ) {
+      50           2 :   vesselbase::FunctionVessel::registerKeywords(keys);
+      51           2 : }
+      52             : 
+      53        3473 : void GradientVessel::reserveKeyword( Keywords& keys ) {
+      54        6946 :   keys.reserve("vessel","GRADIENT","calculate the gradient");
+      55        6946 :   keys.addOutputComponent("gradient","GRADIENT","the gradient");
+      56        3473 : }
+      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             :   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             :   setOutputValue( diff2 );
+     189         232 : }
+     190             : 
+     191             : }
+     192             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e3998e8809 --- /dev/null +++ b/coverage/crystallization/InterMolecularTorsions.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:146322.2 %
Date:2024-06-10 08:19:14Functions:31030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe966createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization22InterMolecularTorsions10isPeriodicEv0
_ZN4PLMD15crystallization22InterMolecularTorsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_0
_ZN4PLMD15crystallization22InterMolecularTorsionsC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization22InterMolecularTorsionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization22InterMolecularTorsions15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD15crystallization22InterMolecularTorsions7computeERKjRNS_11multicolvar13AtomValuePackE0
_ZN4PLMD15crystallization22InterMolecularTorsions16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe96C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe96D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/InterMolecularTorsions.cpp.func.html b/coverage/crystallization/InterMolecularTorsions.cpp.func.html new file mode 100644 index 0000000000..2821df1d26 --- /dev/null +++ b/coverage/crystallization/InterMolecularTorsions.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:146322.2 %
Date:2024-06-10 08:19:14Functions:31030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe966createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe96C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe96D2Ev3473
_ZN4PLMD15crystallization22InterMolecularTorsions10isPeriodicEv0
_ZN4PLMD15crystallization22InterMolecularTorsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_0
_ZN4PLMD15crystallization22InterMolecularTorsions16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD15crystallization22InterMolecularTorsionsC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization22InterMolecularTorsionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization22InterMolecularTorsions15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD15crystallization22InterMolecularTorsions7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/InterMolecularTorsions.cpp.gcov.html b/coverage/crystallization/InterMolecularTorsions.cpp.gcov.html new file mode 100644 index 0000000000..cb226db6b4 --- /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:146322.2 %
Date:2024-06-10 08:19:14Functions:31030.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 "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       10419 : PLUMED_REGISTER_ACTION(InterMolecularTorsions,"INTERMOLECULARTORSIONS")
+      97             : 
+      98           1 : void InterMolecularTorsions::registerKeywords( Keywords& keys ) {
+      99           1 :   MultiColvarBase::registerKeywords( keys );
+     100           2 :   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           2 :   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           2 :   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           2 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     106           2 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     107           2 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     108           2 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     109           2 :   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           1 :   keys.remove("LOWMEM");
+     114           2 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+     115           1 : }
+     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.15
+
+ + + 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 0000000000..6eabdd0c1c --- /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-06-10 08:19:14Functions: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_8KeywordsE1
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EE16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EEC1ERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_43186
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/LocalSteinhardt.h.func.html b/coverage/crystallization/LocalSteinhardt.h.func.html new file mode 100644 index 0000000000..691ed7c76e --- /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-06-10 08:19:14Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q3EE16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q3EEC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EE16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EEC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE16registerKeywordsERNS_8KeywordsE6
_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.15
+
+ + + diff --git a/coverage/crystallization/LocalSteinhardt.h.gcov.html b/coverage/crystallization/LocalSteinhardt.h.gcov.html new file mode 100644 index 0000000000..081c5b8a10 --- /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-06-10 08:19:14Functions: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           8 :   static void registerKeywords( Keywords& keys ) {
+      33           8 :     OrientationSphere::registerKeywords(keys);
+      34           8 :   }
+      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.15
+
+ + + 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 0000000000..32b13d6a39 --- /dev/null +++ b/coverage/crystallization/MoleculeOrientation.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:535694.6 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization19MoleculeOrientationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization19MoleculeOrientation29getAbsoluteIndexOfCentralAtomERKj0
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe646createERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization19MoleculeOrientationC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization19MoleculeOrientation16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe64C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe64D2Ev3473
_ZNK4PLMD15crystallization19MoleculeOrientation26normalizeVectorDerivativesERNS_10MultiValueE4992
_ZNK4PLMD15crystallization19MoleculeOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE16584
_ZNK4PLMD15crystallization19MoleculeOrientation15normalizeVectorERSt6vectorIdSaIdEE1041228
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/MoleculeOrientation.cpp.func.html b/coverage/crystallization/MoleculeOrientation.cpp.func.html new file mode 100644 index 0000000000..b4dd84284c --- /dev/null +++ b/coverage/crystallization/MoleculeOrientation.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:535694.6 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe646createERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe64C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe64D2Ev3473
_ZN4PLMD15crystallization19MoleculeOrientation16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD15crystallization19MoleculeOrientationC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization19MoleculeOrientationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization19MoleculeOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE16584
_ZNK4PLMD15crystallization19MoleculeOrientation15normalizeVectorERSt6vectorIdSaIdEE1041228
_ZNK4PLMD15crystallization19MoleculeOrientation26normalizeVectorDerivativesERNS_10MultiValueE4992
_ZNK4PLMD15crystallization19MoleculeOrientation29getAbsoluteIndexOfCentralAtomERKj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/MoleculeOrientation.cpp.gcov.html b/coverage/crystallization/MoleculeOrientation.cpp.gcov.html new file mode 100644 index 0000000000..88ba12eddf --- /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:535694.6 %
Date:2024-06-10 08:19:14Functions: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             : #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       10427 : PLUMED_REGISTER_ACTION(MoleculeOrientation,"MOLECULES")
+      65             : 
+      66           5 : void MoleculeOrientation::registerKeywords( Keywords& keys ) {
+      67          10 :   VectorMultiColvar::registerKeywords( keys ); keys.use("MEAN"); keys.use("VMEAN");
+      68          10 :   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          10 :   keys.reset_style("MOL","atoms");
+      73           5 : }
+      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.15
+
+ + + 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 0000000000..5bbc5ba99f --- /dev/null +++ b/coverage/crystallization/MoleculePlane.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:385273.1 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization13MoleculePlaneC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization13MoleculePlane29getAbsoluteIndexOfCentralAtomERKj0
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe486createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization13MoleculePlaneC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization13MoleculePlane16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe48C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe48D2Ev3473
_ZNK4PLMD15crystallization13MoleculePlane15calculateVectorERNS_11multicolvar13AtomValuePackE8888
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/MoleculePlane.cpp.func.html b/coverage/crystallization/MoleculePlane.cpp.func.html new file mode 100644 index 0000000000..3ffcce7255 --- /dev/null +++ b/coverage/crystallization/MoleculePlane.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:385273.1 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe486createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe48C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe48D2Ev3473
_ZN4PLMD15crystallization13MoleculePlane16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization13MoleculePlaneC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization13MoleculePlaneC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization13MoleculePlane15calculateVectorERNS_11multicolvar13AtomValuePackE8888
_ZNK4PLMD15crystallization13MoleculePlane29getAbsoluteIndexOfCentralAtomERKj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/MoleculePlane.cpp.gcov.html b/coverage/crystallization/MoleculePlane.cpp.gcov.html new file mode 100644 index 0000000000..6cb5ed9959 --- /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:385273.1 %
Date:2024-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_ACTION(MoleculePlane,"PLANES")
+      49             : 
+      50           3 : void MoleculePlane::registerKeywords( Keywords& keys ) {
+      51           3 :   VectorMultiColvar::registerKeywords( keys ); keys.use("VMEAN");
+      52           6 :   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           6 :   keys.reset_style("MOL","atoms");
+      59           3 : }
+      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.15
+
+ + + 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 0000000000..a8cd9cdc81 --- /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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphereC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17OrientationSphereC2ERKNS_13ActionOptionsE11
_ZN4PLMD15crystallization17OrientationSphere16registerKeywordsERNS_8KeywordsE16
_ZNK4PLMD15crystallization17OrientationSphere7computeERKjRNS_11multicolvar13AtomValuePackE7782
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.cpp.func.html b/coverage/crystallization/OrientationSphere.cpp.func.html new file mode 100644 index 0000000000..acde523770 --- /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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphere16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD15crystallization17OrientationSphereC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17OrientationSphereC2ERKNS_13ActionOptionsE11
_ZNK4PLMD15crystallization17OrientationSphere7computeERKjRNS_11multicolvar13AtomValuePackE7782
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.cpp.gcov.html b/coverage/crystallization/OrientationSphere.cpp.gcov.html new file mode 100644 index 0000000000..cbdc2e7ca7 --- /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-06-10 08:19:14Functions: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          16 : void OrientationSphere::registerKeywords( Keywords& keys ) {
+      32          16 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      33          32 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      34          32 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      35          32 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      36          32 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      37          32 :   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          48 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+      42          48 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
+      43          64 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      44          32 :   keys.use("LOWEST"); keys.use("HIGHEST");
+      45          16 : }
+      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.15
+
+ + + 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 0000000000..c7639fd595 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphere10isPeriodicEv12
_ZNK4PLMD15crystallization17OrientationSphere30calculateCoordinationPrefactorERKdRd3318
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.h.func.html b/coverage/crystallization/OrientationSphere.h.func.html new file mode 100644 index 0000000000..37bbc7b7a6 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphere10isPeriodicEv12
_ZNK4PLMD15crystallization17OrientationSphere30calculateCoordinationPrefactorERKdRd3318
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.h.gcov.html b/coverage/crystallization/OrientationSphere.h.gcov.html new file mode 100644 index 0000000000..9800af40c9 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..33a4678305 --- /dev/null +++ b/coverage/crystallization/PolymerAngles.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization13PolymerAnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe766createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization13PolymerAnglesC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization13PolymerAngles16registerKeywordsERNS_8KeywordsE2
_ZNK4PLMD15crystallization13PolymerAngles21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_616
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe76C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe76D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/PolymerAngles.cpp.func.html b/coverage/crystallization/PolymerAngles.cpp.func.html new file mode 100644 index 0000000000..92b16e6988 --- /dev/null +++ b/coverage/crystallization/PolymerAngles.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe766createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe76C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe76D2Ev3473
_ZN4PLMD15crystallization13PolymerAngles16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization13PolymerAnglesC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization13PolymerAnglesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization13PolymerAngles21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_616
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/PolymerAngles.cpp.gcov.html b/coverage/crystallization/PolymerAngles.cpp.gcov.html new file mode 100644 index 0000000000..68b82b3c66 --- /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:1515100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(PolymerAngles,"POLYMER_ANGLES")
+      77             : 
+      78           2 : void PolymerAngles::registerKeywords( Keywords& keys ) {
+      79           2 :   OrientationSphere::registerKeywords(keys);
+      80           2 : }
+      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.15
+
+ + + 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 0000000000..cde1544b10 --- /dev/null +++ b/coverage/crystallization/Q3.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:51926.3 %
Date:2024-06-10 08:19:14Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe1896createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe1916createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q3C1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q3C2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q316registerKeywordsERNS_8KeywordsE1
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe189C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe189D2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe191C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe191D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Q3.cpp.func.html b/coverage/crystallization/Q3.cpp.func.html new file mode 100644 index 0000000000..2d946b50d3 --- /dev/null +++ b/coverage/crystallization/Q3.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:51926.3 %
Date:2024-06-10 08:19:14Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe1896createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe189C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe189D2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe1916createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe191C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe191D2Ev3473
_ZN4PLMD15crystallization2Q316registerKeywordsERNS_8KeywordsE1
_ZN4PLMD15crystallization2Q3C1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q3C2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Q3.cpp.gcov.html b/coverage/crystallization/Q3.cpp.gcov.html new file mode 100644 index 0000000000..a1748e2c52 --- /dev/null +++ b/coverage/crystallization/Q3.cpp.gcov.html @@ -0,0 +1,302 @@ + + + + + + + + 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:51926.3 %
Date:2024-06-10 08:19:14Functions:5955.6 %
+
+ + + + + + + + +

+
          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             : // For some reason, this is not seen correctly by cppcheck
+     188             : // cppcheck-suppress unknownMacro
+     189       10419 : PLUMED_REGISTER_ACTION(Q3,"Q3")
+     190             : typedef LocalSteinhardt<Q3> LOCAL_Q3;
+     191       10419 : PLUMED_REGISTER_ACTION(LOCAL_Q3,"LOCAL_Q3")
+     192             : 
+     193           1 : void Q3::registerKeywords( Keywords& keys ) {
+     194           1 :   Steinhardt::registerKeywords( keys );
+     195           1 : }
+     196             : 
+     197           0 : Q3::Q3(const ActionOptions& ao ):
+     198             :   Action(ao),
+     199           0 :   Steinhardt(ao)
+     200             : {
+     201           0 :   setAngularMomentum(3);
+     202             : 
+     203             : // Spherical harmonics normalization:
+     204             : // even =  sqrt ( ((2l+1)*(l-m)!) / (4*pi*(l+m)!) )
+     205             : // odd  = -sqrt ( ((2l+1)*(l-m)!) / (4*pi*(l+m)!) )
+     206             : 
+     207           0 :   normaliz.resize( 4 );
+     208           0 :   normaliz[0] = sqrt( ( 7.0*6.0 ) / (4.0*pi*6.0) );
+     209           0 :   normaliz[1] = -sqrt( ( 7.0*2.0 ) / (4.0*pi*24.0) );
+     210           0 :   normaliz[2] = sqrt( ( 7.0*1.0) / (4.0*pi*120.0) );
+     211           0 :   normaliz[3] = -sqrt( ( 7.0*1.0) / (4.0*pi*720.0) );
+     212             : 
+     213             : // Legendre polynomial coefficients of order three
+     214             : 
+     215           0 :   coeff_poly.resize( 4 );
+     216           0 :   coeff_poly[0]=0.0;
+     217           0 :   coeff_poly[1]=-1.5;
+     218           0 :   coeff_poly[2]=0.0;
+     219           0 :   coeff_poly[3]=2.5;
+     220             : 
+     221           0 : }
+     222             : 
+     223             : }
+     224             : }
+     225             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..0592a80a87 --- /dev/null +++ b/coverage/crystallization/Q4.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:1919100.0 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe1906createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q4C2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe1886createERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization2Q4C1ERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization2Q416registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe188C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe188D2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe190C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe190D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Q4.cpp.func.html b/coverage/crystallization/Q4.cpp.func.html new file mode 100644 index 0000000000..81a718b9fe --- /dev/null +++ b/coverage/crystallization/Q4.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:1919100.0 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe1886createERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe188C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe188D2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe1906createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe190C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe190D2Ev3473
_ZN4PLMD15crystallization2Q416registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization2Q4C1ERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization2Q4C2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Q4.cpp.gcov.html b/coverage/crystallization/Q4.cpp.gcov.html new file mode 100644 index 0000000000..3f639f4420 --- /dev/null +++ b/coverage/crystallization/Q4.cpp.gcov.html @@ -0,0 +1,294 @@ + + + + + + + + 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:1919100.0 %
Date:2024-06-10 08:19:14Functions: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             : #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             : // For some reason, this is not seen correctly by cppcheck
+     187             : // cppcheck-suppress unknownMacro
+     188       10425 : PLUMED_REGISTER_ACTION(Q4,"Q4")
+     189             : typedef LocalSteinhardt<Q4> LOCAL_Q4;
+     190       10419 : PLUMED_REGISTER_ACTION(LOCAL_Q4,"LOCAL_Q4")
+     191             : 
+     192           4 : void Q4::registerKeywords( Keywords& keys ) {
+     193           4 :   Steinhardt::registerKeywords( keys );
+     194           4 : }
+     195             : 
+     196           3 : Q4::Q4(const ActionOptions& ao ):
+     197             :   Action(ao),
+     198           3 :   Steinhardt(ao)
+     199             : {
+     200           3 :   setAngularMomentum(4);
+     201             : 
+     202           3 :   normaliz.resize( 5 );
+     203           3 :   normaliz[0] = sqrt( ( 9.0*24.0 ) / (4.0*pi*24.0) );
+     204           3 :   normaliz[1] = -sqrt( ( 9.0*6.0 ) / (4.0*pi*120.0) );
+     205           3 :   normaliz[2] = sqrt( ( 9.0*2.0) / (4.0*pi*720.0) );
+     206           3 :   normaliz[3] = -sqrt( ( 9.0*1) / (4.0*pi*5040.0) );
+     207           3 :   normaliz[4] = sqrt( (9.0*1) / (4.0*pi*40320.0) );
+     208             : 
+     209           3 :   coeff_poly.resize( 5 );
+     210           3 :   coeff_poly[0]=0.375; coeff_poly[1]=0.0;
+     211           3 :   coeff_poly[2]=-3.75; coeff_poly[3]=0.0;
+     212           3 :   coeff_poly[4]=4.375;
+     213           3 : }
+     214             : 
+     215             : }
+     216             : }
+     217             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..0ffb157cec --- /dev/null +++ b/coverage/crystallization/Q6.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:2222100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization2Q6C2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe1906createERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe1886createERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization2Q6C1ERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization2Q616registerKeywordsERNS_8KeywordsE16
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe188C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe188D2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe190C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe190D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Q6.cpp.func.html b/coverage/crystallization/Q6.cpp.func.html new file mode 100644 index 0000000000..67c546ea4e --- /dev/null +++ b/coverage/crystallization/Q6.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:2222100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe1886createERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe188C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe188D2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe1906createERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe190C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe190D2Ev3473
_ZN4PLMD15crystallization2Q616registerKeywordsERNS_8KeywordsE16
_ZN4PLMD15crystallization2Q6C1ERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization2Q6C2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Q6.cpp.gcov.html b/coverage/crystallization/Q6.cpp.gcov.html new file mode 100644 index 0000000000..4707f4d464 --- /dev/null +++ b/coverage/crystallization/Q6.cpp.gcov.html @@ -0,0 +1,297 @@ + + + + + + + + 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:2222100.0 %
Date:2024-06-10 08:19:14Functions:8988.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 "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             : // For some reason, this is not seen correctly by cppcheck
+     187             : // cppcheck-suppress unknownMacro
+     188       10449 : PLUMED_REGISTER_ACTION(Q6,"Q6")
+     189             : typedef LocalSteinhardt<Q6> LOCAL_Q6;
+     190       10429 : PLUMED_REGISTER_ACTION(LOCAL_Q6,"LOCAL_Q6")
+     191             : 
+     192          16 : void Q6::registerKeywords( Keywords& keys ) {
+     193          16 :   Steinhardt::registerKeywords( keys );
+     194          16 : }
+     195             : 
+     196          15 : Q6::Q6(const ActionOptions& ao ):
+     197             :   Action(ao),
+     198          15 :   Steinhardt(ao)
+     199             : {
+     200          15 :   setAngularMomentum(6);
+     201             : 
+     202          15 :   normaliz.resize( 7 );
+     203          15 :   normaliz[0] = sqrt( ( 13.0*720.0 ) / (4.0*pi*720.0) );
+     204          15 :   normaliz[1] = -sqrt( ( 13.0*120.0 ) / (4.0*pi*5040) );
+     205          15 :   normaliz[2] = sqrt( ( 13.0*24) / (4.0*pi*40320) );
+     206          15 :   normaliz[3] = -sqrt( ( 13.0*6) / (4.0*pi*362880) );
+     207          15 :   normaliz[4] = sqrt( (13.0*2) / (4.0*pi*3628800) );
+     208          15 :   normaliz[5] = -sqrt( (13.0*1) / (4.0*pi*39916800) );
+     209          15 :   normaliz[6] = sqrt( (13.0*1) / (4.0*pi*479001600) );
+     210             : 
+     211          15 :   coeff_poly.resize( 7 );
+     212          15 :   coeff_poly[0]=-0.3125; coeff_poly[1]=0.0;
+     213          15 :   coeff_poly[2]=6.5625; coeff_poly[3]=0.0;
+     214          15 :   coeff_poly[4]=-19.6875; coeff_poly[5]=0.0;
+     215          15 :   coeff_poly[6]=14.4375;
+     216          15 : }
+     217             : 
+     218             : }
+     219             : }
+     220             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..75f9ae23ac --- /dev/null +++ b/coverage/crystallization/SMAC.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization4SMACC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_117SMACRegisterMe1376createERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization4SMACC1ERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization4SMAC16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization12_GLOBAL__N_117SMACRegisterMe137C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_117SMACRegisterMe137D2Ev3473
_ZNK4PLMD15crystallization4SMAC30calculateCoordinationPrefactorERKdRd4464
_ZNK4PLMD15crystallization4SMAC21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_1025856
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/SMAC.cpp.func.html b/coverage/crystallization/SMAC.cpp.func.html new file mode 100644 index 0000000000..a49c41736b --- /dev/null +++ b/coverage/crystallization/SMAC.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_117SMACRegisterMe1376createERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization12_GLOBAL__N_117SMACRegisterMe137C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_117SMACRegisterMe137D2Ev3473
_ZN4PLMD15crystallization4SMAC16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization4SMACC1ERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization4SMACC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization4SMAC21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_1025856
_ZNK4PLMD15crystallization4SMAC30calculateCoordinationPrefactorERKdRd4464
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/SMAC.cpp.gcov.html b/coverage/crystallization/SMAC.cpp.gcov.html new file mode 100644 index 0000000000..cf5c7f6cbf --- /dev/null +++ b/coverage/crystallization/SMAC.cpp.gcov.html @@ -0,0 +1,282 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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 discussed in \cite smac-paper
+      30             : 
+      31             : The SMAC collective variable can be used to study the formation of molecular solids
+      32             : from either the melt or from solution.  The idea behind this variable is that what
+      33             : differentiates a molecular solid from a molecular liquid is an alignment of
+      34             : internal vectors in neighboring molecules.  In other words, the relative orientation
+      35             : of neighboring molecules is no longer random as it is in a liquid.  In a solid particular
+      36             : torsional angles between molecules are preferred.  As such this CV calculates the following
+      37             : average:
+      38             : 
+      39             : \f[
+      40             : 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}) }
+      41             : \f]
+      42             : 
+      43             : 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
+      44             : \ref switchingfunction that acts on this distance.  By including this switching function in the second summation in the
+      45             : numerator and in the denominator we are thus ensuring that we calculate an average over the molecules in the first coordination
+      46             : sphere of molecule \f$i\f$.  All molecules in higher coordination sphere will essentially contribute zero to the sums in the
+      47             : above expression because their \f$\sigma(r_{ij})\f$ will be very small.  \f$\psi\f$ is also a switching function.  The term
+      48             : including \f$\psi\f$ in the numerator is there to ensure that only those molecules that are attached to a reasonably large
+      49             : number of molecules.  It is important to include this "more than" switching function when you are simulating nucleation
+      50             : from solution with this CV.  Lastly, the $K_n functions are \ref kernelfunctions that take the torsion angle, \f$\theta_{ij}\f$, between the
+      51             : internal orientation vectors for molecules \f$i\f$ and \f$j\f$ as input.  These kernel functions should be set so that they are
+      52             : equal to one when the relative orientation of the molecules are as they are in the solid and equal to zero otherwise.
+      53             : The final \f$s_i\f$ quantity thus measures whether (on average) the molecules in the first coordination sphere around molecule \f$i\f$
+      54             : 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
+      55             : for all the molecules in your system simultaneously and then determine the average, the number less than and so on.
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : In the example below the orientation of the molecules in the system is determined by calculating the
+      60             : vector that connects a pair of atoms.  SMAC is then used to determine whether the molecules are sitting
+      61             : 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
+      62             : the bond vectors on adjacent molecules is close to 0 or \f$\pi\f$.  The final quantity that is output to the colvar
+      63             : file measures the number of molecules that have a SMAC parameter that is greater than 0.7.  N.B. By using
+      64             : the indices of three atoms for each of the MOL keywords below we are telling PLUMED to use the first two
+      65             : numbers to determine the orientation of the molecule that will ultimately be used when calculating the \f$\theta_{ij}\f$
+      66             : terms in the formula above.  The atom with the third index meanwhile is used when we calculate \f$r_{ij}\f$.
+      67             : 
+      68             : \plumedfile
+      69             : MOLECULES ...
+      70             : MOL1=9,10,9
+      71             : MOL2=89,90,89
+      72             : MOL3=473,474,473
+      73             : MOL4=1161,1162,1161
+      74             : MOL5=1521,1522,1521
+      75             : MOL6=1593,1594,1593
+      76             : MOL7=1601,1602,1601
+      77             : MOL8=2201,2202,2201
+      78             : LABEL=m3
+      79             : ... MOLECULES
+      80             : 
+      81             : SMAC ...
+      82             :    SPECIES=m3 LOWMEM
+      83             :    KERNEL1={GAUSSIAN CENTER=0 SIGMA=0.480} KERNEL2={GAUSSIAN CENTER=pi SIGMA=0.480}
+      84             :    SWITCH={RATIONAL R_0=0.6} MORE_THAN={RATIONAL R_0=0.7} SWITCH_COORD={EXP R_0=4}
+      85             :    LABEL=s2
+      86             : ... SMAC
+      87             : 
+      88             : PRINT ARG=s2.* FILE=colvar
+      89             : \endplumedfile
+      90             : 
+      91             : This second example works in a way that is very similar to the previous command.  Now, however,
+      92             : the orientation of the molecules is determined by finding the plane that contains the positions
+      93             : of three atoms.
+      94             : 
+      95             : \plumedfile
+      96             : PLANES ...
+      97             : MOL1=9,10,11
+      98             : MOL2=89,90,91
+      99             : MOL3=473,474,475
+     100             : MOL4=1161,1162,1163
+     101             : MOL5=1521,1522,1523
+     102             : MOL6=1593,1594,1595
+     103             : MOL7=1601,1602,1603
+     104             : MOL8=2201,2202,2203
+     105             : VMEAN
+     106             : LABEL=m3
+     107             : ... PLANES
+     108             : 
+     109             : SMAC ...
+     110             :    SPECIES=m3 LOWMEM
+     111             :    KERNEL1={GAUSSIAN CENTER=0 SIGMA=0.480} KERNEL2={GAUSSIAN CENTER=pi SIGMA=0.480}
+     112             :    SWITCH={RATIONAL R_0=0.6} MORE_THAN={RATIONAL R_0=0.7} SWITCH_COORD={EXP R_0=3.0}
+     113             :    LABEL=s2
+     114             : ... SMAC
+     115             : 
+     116             : PRINT ARG=s2.* FILE=colvar
+     117             : \endplumedfile
+     118             : 
+     119             : */
+     120             : //+ENDPLUMEDOC
+     121             : 
+     122             : namespace PLMD {
+     123             : namespace crystallization {
+     124             : 
+     125             : class SMAC : public OrientationSphere {
+     126             : private:
+     127             :   std::vector<KernelFunctions> kernels;
+     128             :   SwitchingFunction coord_switch;
+     129             : public:
+     130             :   static void registerKeywords( Keywords& keys );
+     131             :   explicit SMAC(const ActionOptions& ao);
+     132             :   double computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+     133             :                                 Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const override;
+     134             :   double calculateCoordinationPrefactor( const double& coord, double& df ) const override;
+     135             : };
+     136             : 
+     137       10429 : PLUMED_REGISTER_ACTION(SMAC,"SMAC")
+     138             : 
+     139           6 : void SMAC::registerKeywords( Keywords& keys ) {
+     140           6 :   OrientationSphere::registerKeywords(keys);
+     141          12 :   keys.add("numbered","KERNEL","The kernels used in the function of the angle");
+     142          12 :   keys.add("compulsory","SWITCH_COORD","This keyword is used to define the coordination switching function.");
+     143          12 :   keys.reset_style("KERNEL","compulsory");
+     144           6 : }
+     145             : 
+     146           5 : SMAC::SMAC(const ActionOptions& ao):
+     147             :   Action(ao),
+     148           5 :   OrientationSphere(ao)
+     149             : {
+     150           5 :   if( mybasemulticolvars.size()==0 ) error("SMAC must take multicolvar as input");
+     151          11 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) {
+     152           6 :     if( (mybasemulticolvars[i]->getNumberOfQuantities()-2)%3!=0 ) error("SMAC is only possible with three dimensional vectors");
+     153             :   }
+     154             : 
+     155             :   std::string kernelinpt;
+     156          10 :   for(int i=1;; i++) {
+     157          30 :     if( !parseNumbered("KERNEL",i,kernelinpt) ) break;
+     158          10 :     KernelFunctions mykernel( kernelinpt );
+     159          10 :     kernels.push_back( mykernel );
+     160          10 :   }
+     161           5 :   if( kernels.size()==0 ) error("no kernels defined");
+     162             : 
+     163          10 :   std::string sw, errors; parse("SWITCH_COORD",sw);
+     164           5 :   if(sw.length()==0) error("SWITCH_COORD keyword is missing");
+     165           5 :   coord_switch.set(sw,errors);
+     166           5 :   if(errors.length()>0) error("the following errors were found in input to SWITCH_COORD : " + errors );
+     167             : 
+     168           5 : }
+     169             : 
+     170     1025856 : double SMAC::computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+     171             :                                     Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const {
+     172             : 
+     173     1025856 :   unsigned nvectors = ( vec1.size() - 2 ) / 3; plumed_assert( (vec1.size()-2)%3==0 );
+     174     1025856 :   std::vector<Vector> dv1(nvectors), dv2(nvectors), tdconn(nvectors); Torsion t; std::vector<Vector> v1(nvectors), v2(nvectors);
+     175             :   std::vector<std::unique_ptr<Value>> pos;
+     176     2051712 :   for(unsigned i=0; i<nvectors; ++i) { pos.emplace_back( Tools::make_unique<Value>() ); pos[i]->setDomain( "-pi", "pi" ); }
+     177             : 
+     178     2051712 :   for(unsigned j=0; j<nvectors; ++j) {
+     179     4103424 :     for(unsigned k=0; k<3; ++k) {
+     180     3077568 :       v1[j][k]=vec1[2+3*j+k]; v2[j][k]=vec2[2+3*j+k];
+     181             :     }
+     182     1025856 :     double angle = t.compute( v1[j], conn, v2[j], dv1[j], tdconn[j], dv2[j] );
+     183             :     pos[j]->set( angle );
+     184             :   }
+     185             : 
+     186     1025856 :   auto pos_ptr=Tools::unique2raw(pos);
+     187             : 
+     188     1025856 :   double ans=0; std::vector<double> deriv( nvectors ), df( nvectors, 0 );
+     189     3077568 :   for(unsigned i=0; i<kernels.size(); ++i) {
+     190     2051712 :     ans += kernels[i].evaluate( pos_ptr, deriv );
+     191     4103424 :     for(unsigned j=0; j<nvectors; ++j) df[j] += deriv[j];
+     192             :   }
+     193     2051712 :   dconn.zero(); for(unsigned j=0; j<nvectors; ++j) dconn += df[j]*tdconn[j];
+     194     2051712 :   for(unsigned j=0; j<nvectors; ++j) {
+     195     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]; }
+     196             :   }
+     197     1025856 :   return ans;
+     198     1025856 : }
+     199             : 
+     200        4464 : double SMAC::calculateCoordinationPrefactor( const double& coord, double& df ) const {
+     201        4464 :   double f=1-coord_switch.calculate( coord, df ); df*=-coord; return f;
+     202             : }
+     203             : 
+     204             : }
+     205             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b4241d0a06 --- /dev/null +++ b/coverage/crystallization/SimpleCubic.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2525100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11SimpleCubicC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization11SimpleCubicC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe786createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11SimpleCubic16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe78C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe78D2Ev3473
_ZNK4PLMD15crystallization11SimpleCubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/SimpleCubic.cpp.func.html b/coverage/crystallization/SimpleCubic.cpp.func.html new file mode 100644 index 0000000000..76712ff53b --- /dev/null +++ b/coverage/crystallization/SimpleCubic.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2525100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11SimpleCubic16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization11SimpleCubicC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11SimpleCubicC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe786createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe78C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe78D2Ev3473
_ZNK4PLMD15crystallization11SimpleCubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/SimpleCubic.cpp.gcov.html b/coverage/crystallization/SimpleCubic.cpp.gcov.html new file mode 100644 index 0000000000..ee7cc4af9b --- /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:2525100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(SimpleCubic,"SIMPLECUBIC")
+      79             : 
+      80           2 : void SimpleCubic::registerKeywords( Keywords& keys ) {
+      81           2 :   CubicHarmonicBase::registerKeywords( keys );
+      82           2 : }
+      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.15
+
+ + + 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 0000000000..424ac4bf96 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10SteinhardtC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization10Steinhardt18setAngularMomentumERKj18
_ZN4PLMD15crystallization10SteinhardtC2ERKNS_13ActionOptionsE18
_ZN4PLMD15crystallization10Steinhardt16registerKeywordsERNS_8KeywordsE21
_ZNK4PLMD15crystallization10Steinhardt15calculateVectorERNS_11multicolvar13AtomValuePackE74931
_ZNK4PLMD15crystallization10Steinhardt10deriv_polyERKjRKdRd15435674
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Steinhardt.cpp.func.html b/coverage/crystallization/Steinhardt.cpp.func.html new file mode 100644 index 0000000000..43609b75cd --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10Steinhardt16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD15crystallization10Steinhardt18setAngularMomentumERKj18
_ZN4PLMD15crystallization10SteinhardtC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization10SteinhardtC2ERKNS_13ActionOptionsE18
_ZNK4PLMD15crystallization10Steinhardt10deriv_polyERKjRKdRd15435674
_ZNK4PLMD15crystallization10Steinhardt15calculateVectorERNS_11multicolvar13AtomValuePackE74931
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Steinhardt.cpp.gcov.html b/coverage/crystallization/Steinhardt.cpp.gcov.html new file mode 100644 index 0000000000..1148ddfd15 --- /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-06-10 08:19:14Functions: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          21 : void Steinhardt::registerKeywords( Keywords& keys ) {
+      30          21 :   VectorMultiColvar::registerKeywords( keys );
+      31          42 :   keys.add("compulsory","NN","12","The n parameter of the switching function ");
+      32          42 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      33          42 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      34          42 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      35          42 :   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          63 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+      39          84 :   keys.use("MEAN"); keys.use("LESS_THAN"); keys.use("MORE_THAN"); keys.use("VMEAN");
+      40         105 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS"); keys.use("MIN"); keys.use("ALT_MIN");
+      41          42 :   keys.use("LOWEST"); keys.use("HIGHEST");
+      42          21 : }
+      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       74931 : void Steinhardt::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
+      73             :   double dfunc, dpoly_ass, md, tq6, itq6, real_z, imag_z;
+      74       74931 :   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       74931 :   unsigned ncomp=2*tmom+1;
+      79             :   double sw, poly_ass, dlen; std::complex<double> powered;
+      80     7465705 :   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    12224372 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+      84     4833598 :          (d2+=distance[1]*distance[1])<rcut2 &&
+      85    10872046 :          (d2+=distance[2]*distance[2])<rcut2 &&
+      86             :          d2>epsilon ) {
+      87             : 
+      88     2408222 :       dlen = sqrt(d2);
+      89     2408222 :       sw = switchingFunction.calculate( dlen, dfunc );
+      90     2408222 :       accumulateSymmetryFunction( -1, i, sw, (+dfunc)*distance, (-dfunc)*Tensor( distance,distance ), myatoms );
+      91     2408222 :       double dlen3 = d2*dlen;
+      92             :       // Do stuff for m=0
+      93     2408222 :       poly_ass=deriv_poly( 0, distance[2]/dlen, dpoly_ass );
+      94             :       // Derivatives of z/r wrt x, y, z
+      95     2408222 :       dz = -( distance[2] / dlen3 )*distance; dz[2] += (1.0 / dlen);
+      96             :       // Derivative wrt to the vector connecting the two atoms
+      97     2408222 :       myrealvec = (+sw)*dpoly_ass*dz + poly_ass*(+dfunc)*distance;
+      98             :       // Accumulate the derivatives
+      99     2408222 :       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     2408222 :       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    15435674 :       for(unsigned m=1; m<=tmom; ++m) {
+     107             :         // Calculate Legendre Polynomial
+     108    13027452 :         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    13027452 :         tq6=poly_ass*real_z;   // Real part of steinhardt parameter
+     118    13027452 :         itq6=poly_ass*imag_z;  // Imaginary part of steinhardt parameter
+     119             : 
+     120             :         // Derivatives wrt ( x/r + iy )^m
+     121    13027452 :         md=static_cast<double>(m);
+     122    13027452 :         dp_x = md*powered*( (1.0/dlen)-(distance[0]*distance[0])/dlen3-ii*(distance[0]*distance[1])/dlen3 );
+     123    13027452 :         dp_y = md*powered*( ii*(1.0/dlen)-(distance[0]*distance[1])/dlen3-ii*(distance[1]*distance[1])/dlen3 );
+     124    13027452 :         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    13027452 :         real_dz[0] = real( dp_x ); real_dz[1] = real( dp_y ); real_dz[2] = real( dp_z );
+     128    13027452 :         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    13027452 :         myrealvec = (+sw)*dpoly_ass*real_z*dz + (+dfunc)*distance*tq6 + (+sw)*poly_ass*real_dz;
+     132    13027452 :         myimagvec = (+sw)*dpoly_ass*imag_z*dz + (+dfunc)*distance*itq6 + (+sw)*poly_ass*imag_dz;
+     133             : 
+     134             :         // Real part
+     135    13027452 :         accumulateSymmetryFunction( 2 + tmom + m, i, sw*tq6, myrealvec, Tensor( -myrealvec,distance ), myatoms );
+     136             :         // Imaginary part
+     137    13027452 :         accumulateSymmetryFunction( 2+ncomp+tmom+m, i, sw*itq6, myimagvec, Tensor( -myimagvec,distance ), myatoms );
+     138             :         // Store -m part of vector
+     139    13027452 :         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    13027452 :         accumulateSymmetryFunction( 2+tmom-m, i, pref*sw*tq6, pref*myrealvec, pref*Tensor( -myrealvec,distance ), myatoms );
+     144             :         // Imaginary part
+     145    13027452 :         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       74931 :   updateActiveAtoms( myatoms );
+     154     1892577 :   for(unsigned i=0; i<getNumberOfComponentsInVector(); ++i) myatoms.getUnderlyingMultiValue().quotientRule( 2+i, 2+i );
+     155       74931 : }
+     156             : 
+     157    15435674 : double Steinhardt::deriv_poly( const unsigned& m, const double& val, double& df ) const {
+     158             :   double fact=1.0;
+     159    58187996 :   for(unsigned j=1; j<=m; ++j) fact=fact*j;
+     160    15435674 :   double res=coeff_poly[m]*fact;
+     161             : 
+     162    15435674 :   double pow=1.0, xi=val, dxi=1.0; df=0.0;
+     163    58187996 :   for(int i=m+1; i<=tmom; ++i) {
+     164             :     double fact=1.0;
+     165   109266592 :     for(unsigned j=i-m+1; j<=i; ++j) fact=fact*j;
+     166    42752322 :     res=res+coeff_poly[i]*fact*xi;
+     167    42752322 :     df = df + pow*coeff_poly[i]*fact*dxi;
+     168    42752322 :     xi=xi*val; dxi=dxi*val; pow+=1.0;
+     169             :   }
+     170    15435674 :   df = df*normaliz[m];
+     171    15435674 :   return normaliz[m]*res;
+     172             : }
+     173             : 
+     174             : }
+     175             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7f03fea403 --- /dev/null +++ b/coverage/crystallization/Tetrahedral.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2323100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11TetrahedralC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization11TetrahedralC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe836createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11Tetrahedral16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe83C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe83D2Ev3473
_ZNK4PLMD15crystallization11Tetrahedral22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Tetrahedral.cpp.func.html b/coverage/crystallization/Tetrahedral.cpp.func.html new file mode 100644 index 0000000000..a0e99ab367 --- /dev/null +++ b/coverage/crystallization/Tetrahedral.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2323100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11Tetrahedral16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization11TetrahedralC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11TetrahedralC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe836createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe83C2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe83D2Ev3473
_ZNK4PLMD15crystallization11Tetrahedral22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/Tetrahedral.cpp.gcov.html b/coverage/crystallization/Tetrahedral.cpp.gcov.html new file mode 100644 index 0000000000..d4a3f1d5c9 --- /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:2323100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(Tetrahedral,"TETRAHEDRAL")
+      84             : 
+      85           2 : void Tetrahedral::registerKeywords( Keywords& keys ) {
+      86           2 :   CubicHarmonicBase::registerKeywords( keys );
+      87           2 : }
+      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.15
+
+ + + 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 0000000000..01d674c020 --- /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-06-10 08:19:14Functions: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_8KeywordsE3473
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeC2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeD2Ev3473
_ZNK4PLMD15crystallization10VectorMean9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE14712
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/VectorMean.cpp.func.html b/coverage/crystallization/VectorMean.cpp.func.html new file mode 100644 index 0000000000..aeca2399c2 --- /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-06-10 08:19:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10VectorMean14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD15crystallization10VectorMean16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization10VectorMean16value_descriptorB5cxx11Ev6
_ZN4PLMD15crystallization10VectorMean6finishERKSt6vectorIdSaIdEE1828
_ZN4PLMD15crystallization10VectorMean6resizeEv23
_ZN4PLMD15crystallization10VectorMeanC2ERKNS_10vesselbase13VesselOptionsE6
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMe6createERKNS_10vesselbase13VesselOptionsE6
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeC2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeD2Ev3473
_ZNK4PLMD15crystallization10VectorMean9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE14712
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/VectorMean.cpp.gcov.html b/coverage/crystallization/VectorMean.cpp.gcov.html new file mode 100644 index 0000000000..f9dc325230 --- /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-06-10 08:19:14Functions: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       10425 : PLUMED_REGISTER_VESSEL(VectorMean,"VMEAN")
+      45             : 
+      46           6 : void VectorMean::registerKeywords( Keywords& keys ) {
+      47           6 :   vesselbase::FunctionVessel::registerKeywords(keys);
+      48           6 : }
+      49             : 
+      50        3473 : void VectorMean::reserveKeyword( Keywords& keys ) {
+      51        6946 :   keys.reserve("vessel","VMEAN","calculate the norm of the mean vector.");
+      52        6946 :   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        3473 : }
+      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.15
+
+ + + 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 0000000000..493c4c1e91 --- /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-06-10 08:19:14Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17VectorMultiColvar16addForcesOnAtomsERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization17VectorMultiColvar22doNotCalculateDirectorEv0
_ZN4PLMD15crystallization17VectorMultiColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17VectorMultiColvar23setVectorDimensionalityERKj26
_ZN4PLMD15crystallization17VectorMultiColvarC2ERKNS_13ActionOptionsE26
_ZN4PLMD15crystallization17VectorMultiColvar16registerKeywordsERNS_8KeywordsE32
_ZNK4PLMD15crystallization17VectorMultiColvar26normalizeVectorDerivativesERNS_10MultiValueE29195
_ZNK4PLMD15crystallization17VectorMultiColvar15normalizeVectorERSt6vectorIdSaIdEE64156
_ZNK4PLMD15crystallization17VectorMultiColvar7computeERKjRNS_11multicolvar13AtomValuePackE100463
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.cpp.func.html b/coverage/crystallization/VectorMultiColvar.cpp.func.html new file mode 100644 index 0000000000..ec78ae2e71 --- /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-06-10 08:19:14Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17VectorMultiColvar16addForcesOnAtomsERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization17VectorMultiColvar16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD15crystallization17VectorMultiColvar22doNotCalculateDirectorEv0
_ZN4PLMD15crystallization17VectorMultiColvar23setVectorDimensionalityERKj26
_ZN4PLMD15crystallization17VectorMultiColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17VectorMultiColvarC2ERKNS_13ActionOptionsE26
_ZNK4PLMD15crystallization17VectorMultiColvar15normalizeVectorERSt6vectorIdSaIdEE64156
_ZNK4PLMD15crystallization17VectorMultiColvar26normalizeVectorDerivativesERNS_10MultiValueE29195
_ZNK4PLMD15crystallization17VectorMultiColvar7computeERKjRNS_11multicolvar13AtomValuePackE100463
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.cpp.gcov.html b/coverage/crystallization/VectorMultiColvar.cpp.gcov.html new file mode 100644 index 0000000000..b7a7de9851 --- /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-06-10 08:19:14Functions: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          32 : void VectorMultiColvar::registerKeywords( Keywords& keys ) {
+      29          32 :   MultiColvarBase::registerKeywords( keys );
+      30          32 :   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          32 : }
+      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      100463 : double VectorMultiColvar::compute( const unsigned& taskIndex, multicolvar::AtomValuePack& myatoms ) const {
+      66             :   // Now calculate the vector
+      67      100463 :   calculateVector( myatoms );
+      68             :   // Sort out the active derivatives
+      69      100463 :   updateActiveAtoms( myatoms );
+      70             : 
+      71             :   // Now calculate the norm of the vector (this is what we return here)
+      72             :   double norm=0;
+      73     1994705 :   for(unsigned i=0; i<ncomponents; ++i) norm += myatoms.getValue(2+i)*myatoms.getValue(2+i);
+      74      100463 :   norm=sqrt(norm);
+      75             : 
+      76      100463 :   if( !doNotCalculateDerivatives() ) {
+      77       74901 :     double inorm = 1.0 / norm; std::vector<double> dervec( ncomponents );
+      78     1498191 :     for(unsigned i=0; i<ncomponents; ++i) dervec[i] = inorm*myatoms.getValue(2+i);
+      79             : 
+      80             :     MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+      81     7788750 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+      82     7713849 :       unsigned jder=myvals.getActiveIndex(j);
+      83   183127731 :       for(unsigned i=0; i<ncomponents; ++i) myvals.addDerivative( 1, jder, dervec[i]*myvals.getDerivative( 2+i, jder ) );
+      84             :     }
+      85             :   }
+      86             : 
+      87      100463 :   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 :   setForcesOnAtoms( oldforces );
+     113           0 : }
+     114             : 
+     115             : }
+     116             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..d6b65074f3 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15crystallization17VectorMultiColvar28hasDifferentiableOrientationEv4
_ZN4PLMD15crystallization17VectorMultiColvarD2Ev26
_ZN4PLMD15crystallization17VectorMultiColvar10isPeriodicEv35
_ZNK4PLMD15crystallization17VectorMultiColvar21getNumberOfQuantitiesEv1252604
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.h.func.html b/coverage/crystallization/VectorMultiColvar.h.func.html new file mode 100644 index 0000000000..48ce325c81 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17VectorMultiColvar10isPeriodicEv35
_ZN4PLMD15crystallization17VectorMultiColvarD2Ev26
_ZNK4PLMD15crystallization17VectorMultiColvar21getNumberOfQuantitiesEv1252604
_ZNK4PLMD15crystallization17VectorMultiColvar28hasDifferentiableOrientationEv4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.h.gcov.html b/coverage/crystallization/VectorMultiColvar.h.gcov.html new file mode 100644 index 0000000000..575365dadb --- /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-06-10 08:19:14Functions: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     1892577 :   return ncomponents;
+      75             : }
+      76             : 
+      77             : inline
+      78     1252604 : unsigned VectorMultiColvar::getNumberOfQuantities() const {
+      79     1252604 :   return 2 + ncomponents;
+      80             : }
+      81             : 
+      82             : }
+      83             : }
+      84             : #endif
+      85             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bc1239ecc2 --- /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-06-10 08:19:14Functions: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_119VectorSumRegisterMeC2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeD2Ev3473
_ZN4PLMD15crystallization9VectorSum14reserveKeywordERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/VectorSum.cpp.func.html b/coverage/crystallization/VectorSum.cpp.func.html new file mode 100644 index 0000000000..1992327004 --- /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-06-10 08:19:14Functions:31030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMe6createERKNS_10vesselbase13VesselOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeC2Ev3473
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeD2Ev3473
_ZN4PLMD15crystallization9VectorSum14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD15crystallization9VectorSum16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD15crystallization9VectorSum16value_descriptorB5cxx11Ev0
_ZN4PLMD15crystallization9VectorSum6finishERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization9VectorSum6resizeEv0
_ZN4PLMD15crystallization9VectorSumC2ERKNS_10vesselbase13VesselOptionsE0
_ZNK4PLMD15crystallization9VectorSum9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/VectorSum.cpp.gcov.html b/coverage/crystallization/VectorSum.cpp.gcov.html new file mode 100644 index 0000000000..94cd1d265c --- /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-06-10 08:19:14Functions: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       10419 : PLUMED_REGISTER_VESSEL(VectorSum,"VSUM")
+      45             : 
+      46           0 : void VectorSum::registerKeywords( Keywords& keys ) {
+      47           0 :   vesselbase::FunctionVessel::registerKeywords(keys);
+      48           0 : }
+      49             : 
+      50        3473 : void VectorSum::reserveKeyword( Keywords& keys ) {
+      51        6946 :   keys.reserve("vessel","VSUM","calculate the norm of the sum of vectors.");
+      52        6946 :   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        3473 : }
+      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.15
+
+ + + diff --git a/coverage/crystallization/index-sort-f.html b/coverage/crystallization/index-sort-f.html new file mode 100644 index 0000000000..9b318e06b4 --- /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:973116883.3 %
Date:2024-06-10 08:19:14Functions:14418777.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
InterMolecularTorsions.cpp +
22.2%22.2%
+
22.2 %14 / 6330.0 %3 / 10
Q3.cpp +
26.3%26.3%
+
26.3 %5 / 1955.6 %5 / 9
LocalSteinhardt.h +
72.2%72.2%
+
72.2 %13 / 1855.6 %5 / 9
VectorMultiColvar.cpp +
79.1%79.1%
+
79.1 %34 / 4366.7 %6 / 9
CubicHarmonicBase.cpp +
93.7%93.7%
+
93.7 %74 / 7975.0 %3 / 4
OrientationSphere.cpp +
90.9%90.9%
+
90.9 %60 / 6675.0 %3 / 4
MoleculePlane.cpp +
73.1%73.1%
+
73.1 %38 / 5275.0 %6 / 8
Q4.cpp +
100.0%
+
100.0 %19 / 1977.8 %7 / 9
MoleculeOrientation.cpp +
94.6%94.6%
+
94.6 %53 / 5680.0 %8 / 10
Steinhardt.cpp +
100.0%
+
100.0 %78 / 7883.3 %5 / 6
PolymerAngles.cpp +
100.0%
+
100.0 %15 / 1585.7 %6 / 7
SimpleCubic.cpp +
100.0%
+
100.0 %25 / 2585.7 %6 / 7
Tetrahedral.cpp +
100.0%
+
100.0 %23 / 2385.7 %6 / 7
Fccubic.cpp +
100.0%
+
100.0 %29 / 2985.7 %6 / 7
SMAC.cpp +
100.0%
+
100.0 %43 / 4387.5 %7 / 8
BondOrientation.cpp +
91.2%91.2%
+
91.2 %52 / 5787.5 %7 / 8
Gradient.cpp +
71.8%71.8%
+
71.8 %51 / 7187.5 %7 / 8
Q6.cpp +
100.0%
+
100.0 %22 / 2288.9 %8 / 9
EnvironmentSimilarity.cpp +
93.4%93.4%
+
93.4 %184 / 19790.0 %9 / 10
Gradient.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
CubicHarmonicBase.h +
100.0%
+
100.0 %1 / 1100.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
VectorMean.cpp +
100.0%
+
100.0 %44 / 44100.0 %10 / 10
GradientVessel.cpp +
84.2%84.2%
+
84.2 %80 / 95100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/crystallization/index-sort-l.html b/coverage/crystallization/index-sort-l.html new file mode 100644 index 0000000000..e29de87974 --- /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:973116883.3 %
Date:2024-06-10 08:19:14Functions:14418777.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
InterMolecularTorsions.cpp +
22.2%22.2%
+
22.2 %14 / 6330.0 %3 / 10
Q3.cpp +
26.3%26.3%
+
26.3 %5 / 1955.6 %5 / 9
Gradient.cpp +
71.8%71.8%
+
71.8 %51 / 7187.5 %7 / 8
LocalSteinhardt.h +
72.2%72.2%
+
72.2 %13 / 1855.6 %5 / 9
MoleculePlane.cpp +
73.1%73.1%
+
73.1 %38 / 5275.0 %6 / 8
VectorMultiColvar.cpp +
79.1%79.1%
+
79.1 %34 / 4366.7 %6 / 9
GradientVessel.cpp +
84.2%84.2%
+
84.2 %80 / 95100.0 %10 / 10
OrientationSphere.cpp +
90.9%90.9%
+
90.9 %60 / 6675.0 %3 / 4
BondOrientation.cpp +
91.2%91.2%
+
91.2 %52 / 5787.5 %7 / 8
EnvironmentSimilarity.cpp +
93.4%93.4%
+
93.4 %184 / 19790.0 %9 / 10
CubicHarmonicBase.cpp +
93.7%93.7%
+
93.7 %74 / 7975.0 %3 / 4
MoleculeOrientation.cpp +
94.6%94.6%
+
94.6 %53 / 5680.0 %8 / 10
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 %15 / 1585.7 %6 / 7
Q4.cpp +
100.0%
+
100.0 %19 / 1977.8 %7 / 9
Q6.cpp +
100.0%
+
100.0 %22 / 2288.9 %8 / 9
Tetrahedral.cpp +
100.0%
+
100.0 %23 / 2385.7 %6 / 7
SimpleCubic.cpp +
100.0%
+
100.0 %25 / 2585.7 %6 / 7
Fccubic.cpp +
100.0%
+
100.0 %29 / 2985.7 %6 / 7
SMAC.cpp +
100.0%
+
100.0 %43 / 4387.5 %7 / 8
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.15
+
+ + + diff --git a/coverage/crystallization/index.html b/coverage/crystallization/index.html new file mode 100644 index 0000000000..1353d93c07 --- /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:973116883.3 %
Date:2024-06-10 08:19:14Functions:14418777.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
BondOrientation.cpp +
91.2%91.2%
+
91.2 %52 / 5787.5 %7 / 8
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 +
93.4%93.4%
+
93.4 %184 / 19790.0 %9 / 10
Fccubic.cpp +
100.0%
+
100.0 %29 / 2985.7 %6 / 7
Gradient.cpp +
71.8%71.8%
+
71.8 %51 / 7187.5 %7 / 8
Gradient.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
GradientVessel.cpp +
84.2%84.2%
+
84.2 %80 / 95100.0 %10 / 10
InterMolecularTorsions.cpp +
22.2%22.2%
+
22.2 %14 / 6330.0 %3 / 10
LocalSteinhardt.h +
72.2%72.2%
+
72.2 %13 / 1855.6 %5 / 9
MoleculeOrientation.cpp +
94.6%94.6%
+
94.6 %53 / 5680.0 %8 / 10
MoleculePlane.cpp +
73.1%73.1%
+
73.1 %38 / 5275.0 %6 / 8
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 %15 / 1585.7 %6 / 7
Q3.cpp +
26.3%26.3%
+
26.3 %5 / 1955.6 %5 / 9
Q4.cpp +
100.0%
+
100.0 %19 / 1977.8 %7 / 9
Q6.cpp +
100.0%
+
100.0 %22 / 2288.9 %8 / 9
SMAC.cpp +
100.0%
+
100.0 %43 / 4387.5 %7 / 8
SimpleCubic.cpp +
100.0%
+
100.0 %25 / 2585.7 %6 / 7
Steinhardt.cpp +
100.0%
+
100.0 %78 / 7883.3 %5 / 6
Tetrahedral.cpp +
100.0%
+
100.0 %23 / 2385.7 %6 / 7
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.15
+
+ + + 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 0000000000..1ba1dc04f1 --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2121100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe1696createERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC1ERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling20calculateProjectionsERKNS_6MatrixIdEERS3_12
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe169C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe169D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html new file mode 100644 index 0000000000..1476a29257 --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2121100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe1696createERKNS_13ActionOptionsE7
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe169C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe169D2Ev3473
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling20calculateProjectionsERKNS_6MatrixIdEERS3_12
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC1ERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html new file mode 100644 index 0000000000..9f00a0e99e --- /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:2121100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10433 : PLUMED_REGISTER_ACTION(ClassicalMultiDimensionalScaling,"CLASSICAL_MDS")
+     170             : 
+     171           8 : void ClassicalMultiDimensionalScaling::registerKeywords( Keywords& keys ) {
+     172           8 :   DimensionalityReductionBase::registerKeywords( keys );
+     173           8 : }
+     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.15
+
+ + + 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 0000000000..fb6113eda9 --- /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-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred27DimensionalityReductionBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred27DimensionalityReductionBase15getArgumentListEv2
_ZN4PLMD6dimred27DimensionalityReductionBaseC2ERKNS_13ActionOptionsE16
_ZN4PLMD6dimred27DimensionalityReductionBase15performAnalysisEv19
_ZN4PLMD6dimred27DimensionalityReductionBase16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD6dimred27DimensionalityReductionBase13getProjectionERKjRSt6vectorIdSaIdEERd1050
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.cpp.func.html b/coverage/dimred/DimensionalityReductionBase.cpp.func.html new file mode 100644 index 0000000000..09785ca983 --- /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-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase13getProjectionERKjRSt6vectorIdSaIdEERd1050
_ZN4PLMD6dimred27DimensionalityReductionBase15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred27DimensionalityReductionBase15getArgumentListEv2
_ZN4PLMD6dimred27DimensionalityReductionBase15performAnalysisEv19
_ZN4PLMD6dimred27DimensionalityReductionBase16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD6dimred27DimensionalityReductionBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred27DimensionalityReductionBaseC2ERKNS_13ActionOptionsE16
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.cpp.gcov.html b/coverage/dimred/DimensionalityReductionBase.cpp.gcov.html new file mode 100644 index 0000000000..caea54eaa7 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.cpp.gcov.html @@ -0,0 +1,213 @@ + + + + + + + + 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-06-10 08:19:14Functions: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             : #include "core/Atoms.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace dimred {
+      29             : 
+      30          23 : void DimensionalityReductionBase::registerKeywords( Keywords& keys ) {
+      31          23 :   analysis::AnalysisBase::registerKeywords( keys );
+      32          46 :   keys.add("compulsory","NLOW_DIM","number of low-dimensional coordinates required");
+      33          46 :   keys.addOutputComponent("coord","default","the low-dimensional projections of the various input configurations");
+      34          23 : }
+      35             : 
+      36          16 : DimensionalityReductionBase::DimensionalityReductionBase( const ActionOptions& ao ):
+      37             :   Action(ao),
+      38             :   analysis::AnalysisBase(ao),
+      39          16 :   dimredbase(NULL)
+      40             : {
+      41             :   // Check that some dissimilarity information is available
+      42          16 :   if( my_input_data ) {
+      43          27 :     if( getName()!="PCA" && !dissimilaritiesWereSet() ) error("dissimilarities have not been calcualted in input actions");
+      44             :     // Now we check if the input was a dimensionality reduction object
+      45          15 :     dimredbase = dynamic_cast<DimensionalityReductionBase*>( my_input_data );
+      46             :   }
+      47             : 
+      48             :   // Retrieve the dimension in the low dimensionality space
+      49          16 :   nlow=0;
+      50          16 :   if( dimredbase ) {
+      51           5 :     nlow=dimredbase->nlow;
+      52           5 :     log.printf("  projecting in %u dimensional space \n",nlow);
+      53          22 :   } else if( keywords.exists("NLOW_DIM") ) {
+      54          10 :     parse("NLOW_DIM",nlow);
+      55          10 :     if( nlow<1 ) error("dimensionality of low dimensional space must be at least one");
+      56          10 :     log.printf("  projecting in %u dimensional space \n",nlow);
+      57             :   }
+      58             :   // Now add fake components to the underlying ActionWithValue for the arguments
+      59             :   std::string num;
+      60          45 :   for(unsigned i=0; i<nlow; ++i) {
+      61          87 :     Tools::convert(i+1,num); addComponent( "coord-" + num ); componentIsNotPeriodic( "coord-" + num );
+      62             :   }
+      63          16 : }
+      64             : 
+      65           2 : std::vector<Value*> DimensionalityReductionBase::getArgumentList() {
+      66             :   std::vector<Value*> arglist( analysis::AnalysisBase::getArgumentList() );
+      67           6 :   for(unsigned i=0; i<nlow; ++i) arglist.push_back( getPntrToComponent(i) );
+      68           2 :   return arglist;
+      69             : }
+      70             : 
+      71        1050 : void DimensionalityReductionBase::getProjection( const unsigned& idata, std::vector<double>& point, double& weight ) {
+      72        1050 :   if( point.size()!=nlow ) point.resize( nlow );
+      73        3150 :   weight = getWeight(idata); for(unsigned i=0; i<nlow; ++i) point[i]=projections(idata,i);
+      74        1050 : }
+      75             : 
+      76          19 : void DimensionalityReductionBase::performAnalysis() {
+      77          19 :   log.printf("Generating projections required by action %s \n",getLabel().c_str() );
+      78             :   // Resize the tempory array (this is used for out of sample)
+      79          19 :   dtargets.resize( getNumberOfDataPoints() );
+      80             :   // Resize the projections array
+      81          19 :   projections.resize( getNumberOfDataPoints(), nlow );
+      82             :   // Retrieve the projections from the previous calculation
+      83          19 :   if( dimredbase ) {
+      84           6 :     std::vector<double> newp( nlow ); double w;
+      85        1056 :     for(unsigned i=0; i<getNumberOfDataPoints(); ++i) {
+      86        1050 :       dimredbase->getProjection( i, newp, w ); plumed_dbg_assert( newp.size()==nlow );
+      87        3150 :       for(unsigned j=0; j<nlow; ++j) projections(i,j)=newp[j];
+      88             :     }
+      89             :   }
+      90             :   // Calculate matrix of dissimilarities
+      91          19 :   Matrix<double> targets( getNumberOfDataPoints(), getNumberOfDataPoints() ); targets=0;
+      92        2686 :   for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+      93      367354 :     for(unsigned j=0; j<i; ++j) targets(i,j)=targets(j,i)=getDissimilarity( i, j );
+      94             :   }
+      95             :   // This calculates the projections of the points
+      96          19 :   calculateProjections( targets, projections );
+      97             :   // Now set the projection values in the underlying object
+      98          19 :   if( my_input_data ) {
+      99        2620 :     for(unsigned idat=0; idat<getNumberOfDataPoints(); ++idat) {
+     100        2602 :       analysis::DataCollectionObject& myref=AnalysisBase::getStoredData(idat,false); std::string num;
+     101        7804 :       for(unsigned i=0; i<nlow; ++i) { Tools::convert(i+1,num); myref.setArgument( getLabel() + ".coord-" + num, projections(idat,i) ); }
+     102             :     }
+     103             :   }
+     104          19 :   log.printf("Generated projections required by action %s \n",getLabel().c_str() );
+     105          19 : }
+     106             : 
+     107           0 : double DimensionalityReductionBase::calculateStress( const std::vector<double>& p, std::vector<double>& d ) {
+     108             : 
+     109             :   // Zero derivative and stress accumulators
+     110           0 :   for(unsigned i=0; i<p.size(); ++i) d[i]=0.0;
+     111           0 :   double stress=0; std::vector<double> dtmp( p.size() );
+     112             : 
+     113             :   // Now accumulate total stress on system
+     114           0 :   for(unsigned i=0; i<dtargets.size(); ++i) {
+     115           0 :     if( dtargets[i]<epsilon ) continue ;
+     116             : 
+     117             :     // Calculate distance in low dimensional space
+     118             :     double dd=0;
+     119           0 :     for(unsigned j=0; j<p.size(); ++j) { dtmp[j]=p[j]-projections(i,j); dd+=dtmp[j]*dtmp[j]; }
+     120           0 :     dd = std::sqrt(dd);
+     121             : 
+     122             :     // Now do transformations and calculate differences
+     123           0 :     double ddiff = dd - dtargets[i];
+     124             : 
+     125             :     // Calculate derivatives
+     126           0 :     double pref = 2.*getWeight(i) / dd;
+     127           0 :     for(unsigned j=0; j<p.size(); ++j) d[j] += pref*ddiff*dtmp[j];
+     128             : 
+     129             :     // Accumulate the total stress
+     130           0 :     stress += getWeight(i)*ddiff*ddiff;
+     131             :   }
+     132           0 :   return stress;
+     133             : }
+     134             : 
+     135             : }
+     136             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..1fe24b268b --- /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-06-10 08:19:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase17setTargetDistanceERKjRKd0
_ZNK4PLMD6dimred27DimensionalityReductionBase11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.h.func.html b/coverage/dimred/DimensionalityReductionBase.h.func.html new file mode 100644 index 0000000000..c5c6f1276a --- /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-06-10 08:19:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase17setTargetDistanceERKjRKd0
_ZNK4PLMD6dimred27DimensionalityReductionBase11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.h.gcov.html b/coverage/dimred/DimensionalityReductionBase.h.gcov.html new file mode 100644 index 0000000000..81e11a416b --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..7142eea30b --- /dev/null +++ b/coverage/dimred/OutputPCAProjections.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:353697.2 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred19OutputPCAProjectionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred19OutputPCAProjection11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe586createERKNS_13ActionOptionsE2
_ZN4PLMD6dimred19OutputPCAProjection15performAnalysisEv2
_ZN4PLMD6dimred19OutputPCAProjectionC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred19OutputPCAProjection16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe58C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe58D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/OutputPCAProjections.cpp.func.html b/coverage/dimred/OutputPCAProjections.cpp.func.html new file mode 100644 index 0000000000..d1bb74733e --- /dev/null +++ b/coverage/dimred/OutputPCAProjections.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:353697.2 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe586createERKNS_13ActionOptionsE2
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe58C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe58D2Ev3473
_ZN4PLMD6dimred19OutputPCAProjection15performAnalysisEv2
_ZN4PLMD6dimred19OutputPCAProjection16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred19OutputPCAProjectionC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred19OutputPCAProjectionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred19OutputPCAProjection11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/OutputPCAProjections.cpp.gcov.html b/coverage/dimred/OutputPCAProjections.cpp.gcov.html new file mode 100644 index 0000000000..58b445ac59 --- /dev/null +++ b/coverage/dimred/OutputPCAProjections.cpp.gcov.html @@ -0,0 +1,189 @@ + + + + + + + + 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:353697.2 %
Date:2024-06-10 08:19:14Functions:6875.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/Atoms.h"
+      29             : #include "core/GenericMolInfo.h"
+      30             : #include "tools/PDB.h"
+      31             : #include "PCA.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace dimred {
+      35             : 
+      36             : //+PLUMEDOC DIMRED OUTPUT_PCA_PROJECTION
+      37             : /*
+      38             : This is used to output the projection calculated by principle component analysis
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : */
+      43             : //+ENDPLUMEDOC
+      44             : 
+      45             : class OutputPCAProjection : public analysis::AnalysisBase {
+      46             : private:
+      47             :   PDB mypdb;
+      48             :   PCA* mypca;
+      49             :   std::string fmt;
+      50             :   std::string filename;
+      51             : public:
+      52             :   static void registerKeywords( Keywords& keys );
+      53             :   explicit OutputPCAProjection( const ActionOptions& );
+      54           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const { plumed_error(); }
+      55             :   void performAnalysis();
+      56             : };
+      57             : 
+      58       10423 : PLUMED_REGISTER_ACTION(OutputPCAProjection,"OUTPUT_PCA_PROJECTION")
+      59             : 
+      60           3 : void OutputPCAProjection::registerKeywords( Keywords& keys ) {
+      61           3 :   analysis::AnalysisBase::registerKeywords( keys );
+      62           6 :   keys.add("compulsory","FILE","the name of the file to output to");
+      63           6 :   keys.add("optional","FMT","the format to use in the output file");
+      64           6 :   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");
+      65           3 : }
+      66             : 
+      67           2 : OutputPCAProjection::OutputPCAProjection( const ActionOptions& ao ):
+      68             :   Action(ao),
+      69             :   analysis::AnalysisBase(ao),
+      70           2 :   fmt("%f")
+      71             : {
+      72             :   // Setup the PCA object
+      73           2 :   mypca = dynamic_cast<PCA*>( my_input_data );
+      74           2 :   if( !mypca ) error("input must be a PCA object");
+      75             : 
+      76             :   // Get setup the pdb
+      77           2 :   mypdb.setAtomNumbers( my_input_data->getAtomIndexes() );
+      78           2 :   mypdb.setArgumentNames( (mypca->my_input_data)->getArgumentNames() );
+      79             : 
+      80             :   // Find a moldata object
+      81           2 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      82           3 :   if( moldat ) warning("PDB output files do not have atom types unless you use MOLDATA");
+      83             : 
+      84           6 :   parse("FILE",filename); parse("FMT",fmt);
+      85           4 :   if( !getRestart() ) { OFile ofile; ofile.link(*this); ofile.setBackupString("analysis"); ofile.backupAllFiles(filename); }
+      86           2 :   log.printf("  printing data to file named %s \n",filename.c_str() );
+      87           2 : }
+      88             : 
+      89           2 : void OutputPCAProjection::performAnalysis() {
+      90             :   // Find a moldata object
+      91           2 :   auto* mymoldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      92             :   // Output the embedding in plumed pdb format
+      93           2 :   OFile afile; afile.link(*this); afile.setBackupString("analysis");
+      94           2 :   mypdb.setAtomPositions( (mypca->myref)->getReferencePositions() );
+      95           4 :   for(unsigned j=0; j<mypca->getArguments().size(); ++j) mypdb.setArgumentValue( (mypca->getArguments()[j])->getName(), (mypca->myref)->getReferenceArgument(j) );
+      96             :   // And output the first frame
+      97           2 :   afile.open( filename ); afile.printf("REMARK TYPE=%s \n", mypca->mtype.c_str() );
+      98           2 :   if( plumed.getAtoms().usingNaturalUnits() ) mypdb.print( 1.0, mymoldat, afile, fmt );
+      99           2 :   else mypdb.print( atoms.getUnits().getLength()/0.1, mymoldat, afile, fmt );
+     100             :   // And now output the eigenvectors
+     101           6 :   for(unsigned dim=0; dim<mypca->nlow; ++dim) {
+     102           4 :     afile.printf("REMARK TYPE=DIRECTION \n");
+     103           4 :     mypdb.setAtomPositions( mypca->directions[dim].getReferencePositions() );
+     104           8 :     for(unsigned j=0; j<mypca->getArguments().size(); ++j) mypdb.setArgumentValue( (mypca->getArguments()[j])->getName(), mypca->directions[dim].getReferenceArgument(j) );
+     105           4 :     if( plumed.getAtoms().usingNaturalUnits() ) mypdb.print( 1.0, mymoldat, afile, fmt );
+     106           4 :     else mypdb.print( atoms.getUnits().getLength()/0.1, mymoldat, afile, fmt );
+     107             :   }
+     108           2 :   afile.close();
+     109           2 : }
+     110             : 
+     111             : }
+     112             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..edf3214b77 --- /dev/null +++ b/coverage/dimred/PCA.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:9712080.8 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred3PCA13getProjectionERKjRSt6vectorIdSaIdEERd0
_ZN4PLMD6dimred3PCAC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe1006createERKNS_13ActionOptionsE3
_ZN4PLMD6dimred3PCA15performAnalysisEv3
_ZN4PLMD6dimred3PCAC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred3PCA16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred3PCA13getProjectionERNS_8analysis20DataCollectionObjectERSt6vectorIdSaIdEE546
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe100C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe100D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/PCA.cpp.func.html b/coverage/dimred/PCA.cpp.func.html new file mode 100644 index 0000000000..6d31eb1863 --- /dev/null +++ b/coverage/dimred/PCA.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:9712080.8 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe1006createERKNS_13ActionOptionsE3
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe100C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe100D2Ev3473
_ZN4PLMD6dimred3PCA13getProjectionERKjRSt6vectorIdSaIdEERd0
_ZN4PLMD6dimred3PCA13getProjectionERNS_8analysis20DataCollectionObjectERSt6vectorIdSaIdEE546
_ZN4PLMD6dimred3PCA15performAnalysisEv3
_ZN4PLMD6dimred3PCA16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred3PCAC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred3PCAC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/PCA.cpp.gcov.html b/coverage/dimred/PCA.cpp.gcov.html new file mode 100644 index 0000000000..620859d1ca --- /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:9712080.8 %
Date:2024-06-10 08:19:14Functions: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 "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       10425 : PLUMED_REGISTER_ACTION(PCA,"PCA")
+     101             : 
+     102           4 : void PCA::registerKeywords( Keywords& keys ) {
+     103          12 :   DimensionalityReductionBase::registerKeywords( keys ); keys.use("ARG"); keys.reset_style("ARG","optional");
+     104           8 :   keys.add("compulsory","METRIC","EUCLIDEAN","the method that you are going to use to measure the distances between points");
+     105           8 :   keys.add("atoms","ATOMS","the list of atoms that you are going to use in the measure of distance that you are using");
+     106           4 : }
+     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.15
+
+ + + 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 0000000000..cc0f173dc2 --- /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-06-10 08:19:14Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred3PCA15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred3PCA17setTargetDistanceERKjRKd0
_ZN4PLMD6dimred3PCA20calculateProjectionsERKNS_6MatrixIdEERS3_0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/PCA.h.func.html b/coverage/dimred/PCA.h.func.html new file mode 100644 index 0000000000..8e6fe0e888 --- /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-06-10 08:19:14Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred3PCA15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred3PCA17setTargetDistanceERKjRKd0
_ZN4PLMD6dimred3PCA20calculateProjectionsERKNS_6MatrixIdEERS3_0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/PCA.h.gcov.html b/coverage/dimred/PCA.h.gcov.html new file mode 100644 index 0000000000..78452aacd8 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..441a9349fa --- /dev/null +++ b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:394390.7 %
Date:2024-06-10 08:19:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15getArgumentListEv0
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred24ProjectNonLandmarkPoints11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe696createERKNS_13ActionOptionsE2
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15performAnalysisEv2
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred24ProjectNonLandmarkPoints16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred24ProjectNonLandmarkPoints13getStoredDataERKjRKb1046
_ZN4PLMD6dimred24ProjectNonLandmarkPoints18generateProjectionERKjRSt6vectorIdSaIdEE1046
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe69C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe69D2Ev3473
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15calculateStressERKSt6vectorIdSaIdEERS4_16744
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html new file mode 100644 index 0000000000..40324ca279 --- /dev/null +++ b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:394390.7 %
Date:2024-06-10 08:19:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe696createERKNS_13ActionOptionsE2
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe69C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe69D2Ev3473
_ZN4PLMD6dimred24ProjectNonLandmarkPoints13getStoredDataERKjRKb1046
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15calculateStressERKSt6vectorIdSaIdEERS4_16744
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15getArgumentListEv0
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15performAnalysisEv2
_ZN4PLMD6dimred24ProjectNonLandmarkPoints16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred24ProjectNonLandmarkPoints18generateProjectionERKjRSt6vectorIdSaIdEE1046
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred24ProjectNonLandmarkPoints11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/ProjectNonLandmarkPoints.cpp.gcov.html b/coverage/dimred/ProjectNonLandmarkPoints.cpp.gcov.html new file mode 100644 index 0000000000..4199577a83 --- /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:394390.7 %
Date:2024-06-10 08:19:14Functions:91275.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 "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       10423 : PLUMED_REGISTER_ACTION(ProjectNonLandmarkPoints,"PROJECT_ALL_ANALYSIS_DATA")
+      70             : 
+      71           3 : void ProjectNonLandmarkPoints::registerKeywords( Keywords& keys ) {
+      72           3 :   analysis::AnalysisBase::registerKeywords( keys );
+      73           6 :   keys.add("compulsory","PROJECTION","the projection that you wish to generate out-of-sample projections with");
+      74           6 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient optimization");
+      75           6 :   keys.addOutputComponent("coord","default","the low-dimensional projections of the various input configurations");
+      76           3 : }
+      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.15
+
+ + + 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 0000000000..f0bf359d87 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.func.html b/coverage/dimred/SMACOF.cpp.func.html new file mode 100644 index 0000000000..c5138212d4 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.gcov.html b/coverage/dimred/SMACOF.cpp.gcov.html new file mode 100644 index 0000000000..fc85b08338 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..f930b524dc --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:154831.2 %
Date:2024-06-10 08:19:14Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe436createERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe43C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe43D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.func.html b/coverage/dimred/SketchMap.cpp.func.html new file mode 100644 index 0000000000..82e98c377b --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:154831.2 %
Date:2024-06-10 08:19:14Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe436createERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe43C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe43D2Ev3473
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD6dimred9SketchMapC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.gcov.html b/coverage/dimred/SketchMap.cpp.gcov.html new file mode 100644 index 0000000000..7568acb56a --- /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:154831.2 %
Date:2024-06-10 08:19:14Functions:3650.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 "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       10419 : PLUMED_REGISTER_ACTION(SketchMap,"SKETCH_MAP")
+      44             : 
+      45           1 : void SketchMap::registerKeywords( Keywords& keys ) {
+      46           1 :   ActionShortcut::registerKeywords( keys );
+      47           2 :   keys.add("compulsory","NLOW_DIM","the dimension of the low dimensional space in which the projections will be constructed");
+      48           2 :   keys.add("compulsory","MATRIX","the matrix of distances between points that you want to reproduce in your sketch-map projection");
+      49           3 :   keys.add("compulsory","HIGH_DIM_FUNCTION","the parameters of the switching function in the high dimensional space");
+      50           3 :   keys.add("compulsory","LOW_DIM_FUNCTION","the parameters of the switching function in the low dimensional space");
+      51           2 :   keys.add("compulsory","ANNEAL_RATE","0.5","the rate at which to do the annealing");
+      52           2 :   keys.add("compulsory","ANNEAL_STEPS","10","the number of steps of annealing to do");
+      53           2 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      54             : // Smap pointwise input
+      55           2 :   keys.add("compulsory","NCYCLES","5","the number of cycles of global optimization to attempt");
+      56           2 :   keys.add("compulsory","BUFFER","1.1","grid extent for search is (max projection - minimum projection) multiplied by this value");
+      57           2 :   keys.add("compulsory","CGRID_SIZE","10","number of points to use in each grid direction");
+      58           2 :   keys.add("compulsory","FGRID_SIZE","0","interpolate the grid onto this number of points -- only works in 2D");
+      59           1 : }
+      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.15
+
+ + + 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 0000000000..8e533f13a8 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13SketchMapBaseC2ERKNS_13ActionOptionsE6
_ZN4PLMD6dimred13SketchMapBase20calculateProjectionsERKNS_6MatrixIdEERS3_7
_ZN4PLMD6dimred13SketchMapBase16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6dimred13SketchMapBase19calculateFullStressERKSt6vectorIdSaIdEERS4_1913
_ZN4PLMD6dimred13SketchMapBase15calculateStressERKSt6vectorIdSaIdEERS4_41344
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapBase.cpp.func.html b/coverage/dimred/SketchMapBase.cpp.func.html new file mode 100644 index 0000000000..b032f2419e --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBase15calculateStressERKSt6vectorIdSaIdEERS4_41344
_ZN4PLMD6dimred13SketchMapBase16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6dimred13SketchMapBase19calculateFullStressERKSt6vectorIdSaIdEERS4_1913
_ZN4PLMD6dimred13SketchMapBase20calculateProjectionsERKNS_6MatrixIdEERS3_7
_ZN4PLMD6dimred13SketchMapBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13SketchMapBaseC2ERKNS_13ActionOptionsE6
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapBase.cpp.gcov.html b/coverage/dimred/SketchMapBase.cpp.gcov.html new file mode 100644 index 0000000000..faf6ca2e4d --- /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-06-10 08:19:14Functions: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          10 : void SketchMapBase::registerKeywords( Keywords& keys ) {
+      28          10 :   DimensionalityReductionBase::registerKeywords( keys );
+      29          10 :   keys.remove("NLOW_DIM");
+      30          40 :   keys.add("compulsory","HIGH_DIM_FUNCTION","as in input action","the parameters of the switching function in the high dimensional space");
+      31          40 :   keys.add("compulsory","LOW_DIM_FUNCTION","as in input action","the parameters of the switching function in the low dimensional space");
+      32          20 :   keys.add("compulsory","MIXPARAM","0.0","the amount of the pure distances to mix into the stress function");
+      33          10 : }
+      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.15
+
+ + + 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 0000000000..93e3fa15ba --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBase17setTargetDistanceERKjRKd145000
_ZNK4PLMD6dimred13SketchMapBase32transformHighDimensionalDistanceERKdRd341661
_ZNK4PLMD6dimred13SketchMapBase31transformLowDimensionalDistanceERKdRd26384110
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapBase.h.func.html b/coverage/dimred/SketchMapBase.h.func.html new file mode 100644 index 0000000000..de9f63d518 --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBase17setTargetDistanceERKjRKd145000
_ZNK4PLMD6dimred13SketchMapBase31transformLowDimensionalDistanceERKdRd26384110
_ZNK4PLMD6dimred13SketchMapBase32transformHighDimensionalDistanceERKdRd341661
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapBase.h.gcov.html b/coverage/dimred/SketchMapBase.h.gcov.html new file mode 100644 index 0000000000..8f73b97fb7 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..8b1bdf4c05 --- /dev/null +++ b/coverage/dimred/SketchMapConjGrad.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred17SketchMapConjGradC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe476createERKNS_13ActionOptionsE3
_ZN4PLMD6dimred17SketchMapConjGradC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred17SketchMapConjGrad16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred17SketchMapConjGrad8minimiseERNS_6MatrixIdEE4
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe47C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe47D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapConjGrad.cpp.func.html b/coverage/dimred/SketchMapConjGrad.cpp.func.html new file mode 100644 index 0000000000..0512ca5b33 --- /dev/null +++ b/coverage/dimred/SketchMapConjGrad.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe476createERKNS_13ActionOptionsE3
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe47C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe47D2Ev3473
_ZN4PLMD6dimred17SketchMapConjGrad16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred17SketchMapConjGrad8minimiseERNS_6MatrixIdEE4
_ZN4PLMD6dimred17SketchMapConjGradC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred17SketchMapConjGradC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapConjGrad.cpp.gcov.html b/coverage/dimred/SketchMapConjGrad.cpp.gcov.html new file mode 100644 index 0000000000..45ba7cf1ea --- /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:1515100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10425 : PLUMED_REGISTER_ACTION(SketchMapConjGrad,"SKETCHMAP_CONJGRAD")
+      48             : 
+      49           4 : void SketchMapConjGrad::registerKeywords( Keywords& keys ) {
+      50           4 :   SketchMapBase::registerKeywords( keys );
+      51           8 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      52           4 : }
+      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.15
+
+ + + 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 0000000000..428a09e9a7 --- /dev/null +++ b/coverage/dimred/SketchMapPointwise.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4747100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred18SketchMapPointwiseC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe506createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred18SketchMapPointwise8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred18SketchMapPointwiseC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred18SketchMapPointwise16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe50C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe50D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapPointwise.cpp.func.html b/coverage/dimred/SketchMapPointwise.cpp.func.html new file mode 100644 index 0000000000..85f10925b7 --- /dev/null +++ b/coverage/dimred/SketchMapPointwise.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4747100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe506createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe50C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe50D2Ev3473
_ZN4PLMD6dimred18SketchMapPointwise16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred18SketchMapPointwise8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred18SketchMapPointwiseC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred18SketchMapPointwiseC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapPointwise.cpp.gcov.html b/coverage/dimred/SketchMapPointwise.cpp.gcov.html new file mode 100644 index 0000000000..ff340bbac8 --- /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:4747100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(SketchMapPointwise,"SKETCHMAP_POINTWISE")
+      51             : 
+      52           2 : void SketchMapPointwise::registerKeywords( Keywords& keys ) {
+      53           2 :   SketchMapBase::registerKeywords( keys );
+      54           4 :   keys.add("compulsory","NCYCLES","5","the number of cycles of global optimization to attempt");
+      55           4 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      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           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.15
+
+ + + 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 0000000000..1b1b3fb1e8 --- /dev/null +++ b/coverage/dimred/SketchMapRead.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:768292.7 %
Date:2024-06-10 08:19:14Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapRead15getArgumentListEv0
_ZN4PLMD6dimred13SketchMapReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred13SketchMapRead23getDataPointIndexInBaseERKj0
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe666createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred13SketchMapRead8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred13SketchMapReadC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred13SketchMapRead16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred13SketchMapRead9getWeightERKj168
_ZNK4PLMD6dimred13SketchMapRead21getNumberOfDataPointsEv173
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe66C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe66D2Ev3473
_ZN4PLMD6dimred13SketchMapRead16getDissimilarityERKjS3_3486
_ZN4PLMD6dimred13SketchMapRead13getStoredDataERKjRKb7056
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapRead.cpp.func.html b/coverage/dimred/SketchMapRead.cpp.func.html new file mode 100644 index 0000000000..6ff5c65e23 --- /dev/null +++ b/coverage/dimred/SketchMapRead.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:768292.7 %
Date:2024-06-10 08:19:14Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe666createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe66C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe66D2Ev3473
_ZN4PLMD6dimred13SketchMapRead13getStoredDataERKjRKb7056
_ZN4PLMD6dimred13SketchMapRead15getArgumentListEv0
_ZN4PLMD6dimred13SketchMapRead16getDissimilarityERKjS3_3486
_ZN4PLMD6dimred13SketchMapRead16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred13SketchMapRead8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred13SketchMapRead9getWeightERKj168
_ZN4PLMD6dimred13SketchMapReadC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred13SketchMapReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred13SketchMapRead21getNumberOfDataPointsEv173
_ZNK4PLMD6dimred13SketchMapRead23getDataPointIndexInBaseERKj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapRead.cpp.gcov.html b/coverage/dimred/SketchMapRead.cpp.gcov.html new file mode 100644 index 0000000000..9aa88befff --- /dev/null +++ b/coverage/dimred/SketchMapRead.cpp.gcov.html @@ -0,0 +1,271 @@ + + + + + + + + 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:768292.7 %
Date:2024-06-10 08:19:14Functions:101376.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 "core/ActionRegister.h"
+      23             : #include "SketchMapBase.h"
+      24             : #include "reference/ReferenceConfiguration.h"
+      25             : #include "reference/MetricRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/Atoms.h"
+      28             : #include "tools/PDB.h"
+      29             : 
+      30             : //+PLUMEDOC DIMRED SKETCHMAP_READ
+      31             : /*
+      32             : Read in a sketch-map projection from an input file
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace dimred {
+      41             : 
+      42             : class SketchMapRead : public SketchMapBase {
+      43             : private:
+      44             :   std::string mtype;
+      45             :   PDB mypdb;
+      46             :   std::vector<Value*> all_values;
+      47             :   std::vector<double> weights;
+      48             : /// The list of properties in the property map
+      49             :   std::map<std::string,std::vector<double> > property;
+      50             : /// The data collection objects we have
+      51             :   std::vector<analysis::DataCollectionObject> data;
+      52             : /// The frames that we are using to calculate distances
+      53             :   std::vector<std::unique_ptr<ReferenceConfiguration> > myframes;
+      54             : public:
+      55             :   static void registerKeywords( Keywords& keys );
+      56             :   explicit SketchMapRead( const ActionOptions& ao );
+      57             :   void minimise( Matrix<double>& ) override;
+      58             :   analysis::DataCollectionObject& getStoredData( const unsigned& idata, const bool& calcdist ) override;
+      59             :   unsigned getNumberOfDataPoints() const override;
+      60             :   std::vector<Value*> getArgumentList() override;
+      61             :   unsigned getDataPointIndexInBase( const unsigned& idata ) const override;
+      62             :   double getDissimilarity( const unsigned& i, const unsigned& j ) override;
+      63             :   double getWeight( const unsigned& idata ) override;
+      64             : };
+      65             : 
+      66       10421 : PLUMED_REGISTER_ACTION(SketchMapRead,"SKETCHMAP_READ")
+      67             : 
+      68           2 : void SketchMapRead::registerKeywords( Keywords& keys ) {
+      69           2 :   SketchMapBase::registerKeywords( keys ); keys.remove("USE_OUTPUT_DATA_FROM");
+      70           4 :   keys.add("compulsory","TYPE","OPTIMAL-FAST","the manner in which distances are calculated. More information on the different "
+      71             :            "metrics that are available in PLUMED can be found in the section of the manual on "
+      72             :            "\\ref dists");
+      73           4 :   keys.add("compulsory","REFERENCE","the file containing the sketch-map projection");
+      74           4 :   keys.add("compulsory","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
+      75           4 :   keys.addFlag("DISABLE_CHECKS",false,"disable checks on reference input structures.");
+      76           2 :   useCustomisableComponents(keys);
+      77           2 : }
+      78             : 
+      79           1 : SketchMapRead::SketchMapRead( const ActionOptions& ao ):
+      80             :   Action(ao),
+      81           1 :   SketchMapBase(ao)
+      82             : {
+      83           2 :   std::vector<std::string> propnames; parseVector("PROPERTY",propnames);
+      84           1 :   if(propnames.size()==0) error("no properties were specified");
+      85           1 :   nlow=propnames.size();
+      86           3 :   for(unsigned i=0; i<nlow; ++i) {
+      87           4 :     std::size_t dot=propnames[i].find_first_of( getLabel() + "." ); std::string substr=propnames[i].c_str();
+      88           2 :     if( dot!=std::string::npos ) { substr.erase(dot,getLabel().length()+1); }
+      89           2 :     log.printf(",%s", propnames[i].c_str() ); addComponent( substr ); componentIsNotPeriodic( substr );
+      90           4 :     property.insert( std::pair<std::string,std::vector<double> >( propnames[i], std::vector<double>() ) );
+      91             :   }
+      92           1 :   log.printf("  mapped properties are %s ",propnames[0].c_str() );
+      93           2 :   for(unsigned i=1; i<nlow; ++i) log.printf(",%s", propnames[i].c_str() );
+      94           1 :   log.printf("\n");
+      95             : 
+      96           3 :   parse("TYPE",mtype); bool skipchecks; parseFlag("DISABLE_CHECKS",skipchecks);
+      97           2 :   std::string ifilename; parse("REFERENCE",ifilename);
+      98           1 :   FILE* fp=fopen(ifilename.c_str(),"r");
+      99           1 :   if(!fp) error("could not open reference file " + ifilename );
+     100             : 
+     101             :   // Read in the embedding
+     102             :   bool do_read=true; double val, ww, wnorm=0, prop; unsigned nfram=0;
+     103          85 :   while (do_read) {
+     104          85 :     PDB inpdb;
+     105             :     // Read the pdb file
+     106         170 :     do_read=inpdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
+     107             :     // Break if we are done
+     108          85 :     if( !do_read ) break ;
+     109             :     // Check for required properties
+     110         252 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     111         168 :       if( !inpdb.getArgumentValue( it->first, prop ) ) error("pdb input does not have contain property named " + it->first );
+     112         168 :       it->second.push_back(prop);
+     113             :     }
+     114             :     // And read the frame ( create a measure )
+     115          84 :     myframes.emplace_back( metricRegister().create<ReferenceConfiguration>( mtype, inpdb ) );
+     116         168 :     if( !inpdb.getArgumentValue( "WEIGHT", ww ) ) error("could not find weights in input pdb");
+     117          84 :     weights.push_back( ww ); wnorm += ww; nfram++;
+     118             :     // And create a data collection object
+     119          84 :     analysis::DataCollectionObject new_data; new_data.setAtomNumbersAndArgumentNames( getLabel(), inpdb.getAtomNumbers(), inpdb.getArgumentNames() );
+     120          84 :     new_data.setAtomPositions( inpdb.getPositions() );
+     121         504 :     for(unsigned i=0; i<inpdb.getArgumentNames().size(); ++i) {
+     122         420 :       std::string aname = inpdb.getArgumentNames()[i];
+     123         420 :       if( !inpdb.getArgumentValue( aname, val ) ) error("failed to find argument named " + aname);
+     124         420 :       new_data.setArgument( aname, val );
+     125             :     }
+     126          84 :     data.push_back( new_data );
+     127          85 :   }
+     128           1 :   fclose(fp);
+     129             :   // Finish the setup of the object by getting the arguments and atoms that are required
+     130             :   std::vector<AtomNumber> atoms; std::vector<std::string> args;
+     131          85 :   for(unsigned i=0; i<myframes.size(); ++i) { weights[i] /= wnorm; myframes[i]->getAtomRequests( atoms, skipchecks ); myframes[i]->getArgumentRequests( args, skipchecks ); }
+     132           1 :   requestAtoms( atoms ); std::vector<Value*> req_args; std::vector<std::string> fargs;
+     133           6 :   for(unsigned i=0; i<args.size(); ++i) {
+     134             :     bool found=false;
+     135          12 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     136           9 :       if( args[i]==it->first ) { found=true; break; }
+     137             :     }
+     138           5 :     if( !found ) { fargs.push_back( args[i] ); }
+     139             :   }
+     140           1 :   interpretArgumentList( fargs, req_args ); mypdb.setArgumentNames( fargs ); requestArguments( req_args );
+     141             : 
+     142           1 :   if(nfram==0 ) error("no reference configurations were specified");
+     143           1 :   log.printf(" found %u configurations in file %s\n",nfram,ifilename.c_str() );
+     144           3 : }
+     145             : 
+     146           1 : void SketchMapRead::minimise( Matrix<double>& projections ) {
+     147             :   unsigned j=0;
+     148           3 :   for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     149         170 :     for(unsigned i=0; i<myframes.size(); ++i) projections(i,j) = it->second[i];
+     150           2 :     j++;
+     151             :   }
+     152           1 : }
+     153             : 
+     154        7056 : analysis::DataCollectionObject & SketchMapRead::getStoredData( const unsigned& idata, const bool& calcdist ) {
+     155        7056 :   return data[idata];
+     156             : }
+     157             : 
+     158         173 : unsigned SketchMapRead::getNumberOfDataPoints() const {
+     159         173 :   return myframes.size();
+     160             : }
+     161             : 
+     162           0 : unsigned SketchMapRead::getDataPointIndexInBase( const unsigned& idata ) const {
+     163           0 :   error("cannot use read in sketch-map to out of sample project data");
+     164             :   return idata;
+     165             : }
+     166             : 
+     167           0 : std::vector<Value*> SketchMapRead::getArgumentList() {
+     168           0 :   std::vector<Value*> arglist( ActionWithArguments::getArguments() );
+     169           0 :   for(unsigned i=0; i<nlow; ++i) arglist.push_back( getPntrToComponent(i) );
+     170           0 :   return arglist;
+     171             : }
+     172             : 
+     173             : // Highly unsatisfactory solution to problem GAT
+     174        3486 : double SketchMapRead::getDissimilarity( const unsigned& i, const unsigned& j ) {
+     175        3486 :   plumed_assert( i<myframes.size() && j<myframes.size() );
+     176        3486 :   if( i!=j ) {
+     177             :     double dd;
+     178        3486 :     getStoredData( i, true ).transferDataToPDB( mypdb );
+     179        3486 :     auto myref1=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     180        3486 :     getStoredData( j, true ).transferDataToPDB( mypdb );
+     181        3486 :     auto myref2=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     182        3486 :     dd=distance( getPbc(), ActionWithArguments::getArguments(), myref1.get(), myref2.get(), true );
+     183             :     return dd;
+     184        3486 :   }
+     185             :   return 0.0;
+     186             : }
+     187             : 
+     188         168 : double SketchMapRead::getWeight( const unsigned& idata ) {
+     189         168 :   plumed_assert( idata<weights.size() );
+     190         168 :   return weights[idata];
+     191             : }
+     192             : 
+     193             : }
+     194             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..a49aa8031a --- /dev/null +++ b/coverage/dimred/SketchMapSmacof.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3737100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred15SketchMapSmacofC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe496createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred15SketchMapSmacof8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred15SketchMapSmacofC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred15SketchMapSmacof16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred15SketchMapSmacof18recalculateWeightsERKNS_6MatrixIdEERS3_2
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe49C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe49D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapSmacof.cpp.func.html b/coverage/dimred/SketchMapSmacof.cpp.func.html new file mode 100644 index 0000000000..6e3a7069ef --- /dev/null +++ b/coverage/dimred/SketchMapSmacof.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3737100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe496createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe49C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe49D2Ev3473
_ZN4PLMD6dimred15SketchMapSmacof16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred15SketchMapSmacof18recalculateWeightsERKNS_6MatrixIdEERS3_2
_ZN4PLMD6dimred15SketchMapSmacof8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred15SketchMapSmacofC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred15SketchMapSmacofC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SketchMapSmacof.cpp.gcov.html b/coverage/dimred/SketchMapSmacof.cpp.gcov.html new file mode 100644 index 0000000000..0cf1f4fbe0 --- /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:3737100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(SketchMapSmacof,"SKETCHMAP_SMACOF")
+      50             : 
+      51           2 : void SketchMapSmacof::registerKeywords( Keywords& keys ) {
+      52           2 :   SketchMapBase::registerKeywords( keys );
+      53           4 :   keys.add("compulsory","SMACOF_TOL","1E-4","the tolerance for each SMACOF cycle");
+      54           4 :   keys.add("compulsory","SMACOF_MAXCYC","1000","maximum number of optimization cycles for SMACOF algorithm");
+      55           4 :   keys.add("compulsory","SMAP_TOL","1E-4","the tolerance for sketch-map");
+      56           4 :   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           2 : }
+      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.15
+
+ + + 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 0000000000..d9b6ca8056 --- /dev/null +++ b/coverage/dimred/SmacoffMDS.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:72035.0 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe486createERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SmacofMDS20calculateProjectionsERKNS_6MatrixIdEERS3_0
_ZN4PLMD6dimred9SmacofMDSC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SmacofMDSC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SmacofMDS16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe48C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe48D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SmacoffMDS.cpp.func.html b/coverage/dimred/SmacoffMDS.cpp.func.html new file mode 100644 index 0000000000..620c1c8406 --- /dev/null +++ b/coverage/dimred/SmacoffMDS.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:72035.0 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe486createERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe48C2Ev3473
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe48D2Ev3473
_ZN4PLMD6dimred9SmacofMDS16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD6dimred9SmacofMDS20calculateProjectionsERKNS_6MatrixIdEERS3_0
_ZN4PLMD6dimred9SmacofMDSC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SmacofMDSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/SmacoffMDS.cpp.gcov.html b/coverage/dimred/SmacoffMDS.cpp.gcov.html new file mode 100644 index 0000000000..cdaf845928 --- /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:72035.0 %
Date:2024-06-10 08:19:14Functions:3742.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 "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       10419 : PLUMED_REGISTER_ACTION(SmacofMDS,"SMACOF_MDS")
+      49             : 
+      50           1 : void SmacofMDS::registerKeywords( Keywords& keys ) {
+      51           1 :   DimensionalityReductionBase::registerKeywords( keys );
+      52           1 :   keys.remove("NLOW_DIM");
+      53           2 :   keys.add("compulsory","SMACOF_TOL","1E-4","tolerance for the SMACOF optimization algorithm");
+      54           2 :   keys.add("compulsory","SMACOF_MAXCYC","1000","maximum number of optimization cycles for SMACOF algorithm");
+      55           1 : }
+      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.15
+
+ + + diff --git a/coverage/dimred/index-sort-f.html b/coverage/dimred/index-sort-f.html new file mode 100644 index 0000000000..1835c14d02 --- /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:55665684.8 %
Date:2024-06-10 08:19:14Functions:7810772.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
35.0%35.0%
+
35.0 %7 / 2042.9 %3 / 7
SketchMap.cpp +
31.2%31.2%
+
31.2 %15 / 4850.0 %3 / 6
DimensionalityReductionBase.cpp +
79.7%79.7%
+
79.7 %47 / 5971.4 %5 / 7
OutputPCAProjections.cpp +
97.2%97.2%
+
97.2 %35 / 3675.0 %6 / 8
ProjectNonLandmarkPoints.cpp +
90.7%90.7%
+
90.7 %39 / 4375.0 %9 / 12
SketchMapRead.cpp +
92.7%92.7%
+
92.7 %76 / 8276.9 %10 / 13
PCA.cpp +
80.8%80.8%
+
80.8 %97 / 12077.8 %7 / 9
SketchMapBase.cpp +
100.0%
+
100.0 %79 / 7983.3 %5 / 6
SketchMapConjGrad.cpp +
100.0%
+
100.0 %15 / 1585.7 %6 / 7
SketchMapPointwise.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
ClassicalMultiDimensionalScaling.cpp +
100.0%
+
100.0 %21 / 2185.7 %6 / 7
SketchMapSmacof.cpp +
100.0%
+
100.0 %37 / 3787.5 %7 / 8
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.15
+
+ + + diff --git a/coverage/dimred/index-sort-l.html b/coverage/dimred/index-sort-l.html new file mode 100644 index 0000000000..142553e9a5 --- /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:55665684.8 %
Date:2024-06-10 08:19:14Functions:7810772.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
31.2%31.2%
+
31.2 %15 / 4850.0 %3 / 6
SmacoffMDS.cpp +
35.0%35.0%
+
35.0 %7 / 2042.9 %3 / 7
DimensionalityReductionBase.cpp +
79.7%79.7%
+
79.7 %47 / 5971.4 %5 / 7
PCA.cpp +
80.8%80.8%
+
80.8 %97 / 12077.8 %7 / 9
ProjectNonLandmarkPoints.cpp +
90.7%90.7%
+
90.7 %39 / 4375.0 %9 / 12
SketchMapRead.cpp +
92.7%92.7%
+
92.7 %76 / 8276.9 %10 / 13
SMACOF.cpp +
97.0%97.0%
+
97.0 %32 / 33100.0 %2 / 2
OutputPCAProjections.cpp +
97.2%97.2%
+
97.2 %35 / 3675.0 %6 / 8
SketchMapBase.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
SketchMapConjGrad.cpp +
100.0%
+
100.0 %15 / 1585.7 %6 / 7
ClassicalMultiDimensionalScaling.cpp +
100.0%
+
100.0 %21 / 2185.7 %6 / 7
SketchMapSmacof.cpp +
100.0%
+
100.0 %37 / 3787.5 %7 / 8
SketchMapPointwise.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
SketchMapBase.cpp +
100.0%
+
100.0 %79 / 7983.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/dimred/index.html b/coverage/dimred/index.html new file mode 100644 index 0000000000..77258ad661 --- /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:55665684.8 %
Date:2024-06-10 08:19:14Functions:7810772.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ClassicalMultiDimensionalScaling.cpp +
100.0%
+
100.0 %21 / 2185.7 %6 / 7
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.2%97.2%
+
97.2 %35 / 3675.0 %6 / 8
PCA.cpp +
80.8%80.8%
+
80.8 %97 / 12077.8 %7 / 9
PCA.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
ProjectNonLandmarkPoints.cpp +
90.7%90.7%
+
90.7 %39 / 4375.0 %9 / 12
SMACOF.cpp +
97.0%97.0%
+
97.0 %32 / 33100.0 %2 / 2
SketchMap.cpp +
31.2%31.2%
+
31.2 %15 / 4850.0 %3 / 6
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 %15 / 1585.7 %6 / 7
SketchMapPointwise.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
SketchMapRead.cpp +
92.7%92.7%
+
92.7 %76 / 8276.9 %10 / 13
SketchMapSmacof.cpp +
100.0%
+
100.0 %37 / 3787.5 %7 / 8
SmacoffMDS.cpp +
35.0%35.0%
+
35.0 %7 / 2042.9 %3 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..eb52206916 --- /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:31834293.0 %
Date:2024-06-10 08:19:14Functions:242596.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3drr7DRRAxis12isInBoundaryEd0
_ZN4PLMD3drr3ABF11mergewindowERKS1_S3_2
_ZN4PLMD3drr4CZAR11mergewindowERKS1_S3_2
_ZNK4PLMD3drr12DRRForceGrid15writeDivergenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD3drr12DRRForceGrid5mergeERKSt6vectorINS0_7DRRAxisESaIS3_EES7_4
_ZN4PLMD3drr7DRRAxis5mergeERKS1_S3_4
_ZNK4PLMD3drr4CZAR11writeZCountERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb18
_ZN4PLMD3drr12DRRForceGridC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb26
_ZNK4PLMD3drr12DRRForceGrid10write1DPMFENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE26
_ZN4PLMD3drr12DRRForceGrid9fillTableERKSt6vectorIS2_IdSaIdEESaIS4_EE34
_ZNK4PLMD3drr12DRRForceGrid8writeAllERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb36
_ZN4PLMD3drr12DRRForceGridC2Ev38
_ZN4PLMD3drr7DRRAxis15getMiddlePointsEv60
_ZN4PLMD3drr3ABF13store_getbiasERKSt6vectorIdSaIdEES6_RS4_123
_ZNK4PLMD3drr12DRRForceGrid20getAccumulatedForcesERKSt6vectorIdSaIdEE1600
_ZN4PLMD3drr12DRRForceGrid5storeERKSt6vectorIdSaIdEES6_m1723
_ZNK4PLMD3drr7DRRAxis14isRealPeriodicEv5860
_ZNK4PLMD3drr12DRRForceGrid13getDivergenceERKSt6vectorIdSaIdEE64800
_ZNK4PLMD3drr12DRRForceGrid8getCountERKSt6vectorIdSaIdEEb100618
_ZNK4PLMD3drr12DRRForceGrid11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid22getCountsLogDerivativeERKSt6vectorIdSaIdEE195576
_ZNK4PLMD3drr4CZAR11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid12isInBoundaryERKSt6vectorIdSaIdEE393846
_ZNK4PLMD3drr12DRRForceGrid13sampleAddressERKSt6vectorIdSaIdEE1012383
_ZN4PLMD3drr12DRRForceGrid7index1DERKNS0_7DRRAxisEd2407170
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/drr/DRR.cpp.func.html b/coverage/drr/DRR.cpp.func.html new file mode 100644 index 0000000000..7dbeb3d8a5 --- /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:31834293.0 %
Date:2024-06-10 08:19:14Functions: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_traitsIcESaIcEEE26
_ZNK4PLMD3drr12DRRForceGrid11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid12isInBoundaryERKSt6vectorIdSaIdEE393846
_ZNK4PLMD3drr12DRRForceGrid13getDivergenceERKSt6vectorIdSaIdEE64800
_ZNK4PLMD3drr12DRRForceGrid13sampleAddressERKSt6vectorIdSaIdEE1012383
_ZNK4PLMD3drr12DRRForceGrid15writeDivergenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD3drr12DRRForceGrid20getAccumulatedForcesERKSt6vectorIdSaIdEE1600
_ZNK4PLMD3drr12DRRForceGrid22getCountsLogDerivativeERKSt6vectorIdSaIdEE195576
_ZNK4PLMD3drr12DRRForceGrid8getCountERKSt6vectorIdSaIdEEb100618
_ZNK4PLMD3drr12DRRForceGrid8writeAllERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb36
_ZNK4PLMD3drr4CZAR11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr4CZAR11writeZCountERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb18
_ZNK4PLMD3drr7DRRAxis12isInBoundaryEd0
_ZNK4PLMD3drr7DRRAxis14isRealPeriodicEv5860
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/drr/DRR.cpp.gcov.html b/coverage/drr/DRR.cpp.gcov.html new file mode 100644 index 0000000000..ea3cf07268 --- /dev/null +++ b/coverage/drr/DRR.cpp.gcov.html @@ -0,0 +1,616 @@ + + + + + + + + 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:31834293.0 %
Date:2024-06-10 08:19:14Functions: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) * ndims;
+     164         914 :     samples[baseaddr / ndims] += nsamples;
+     165             :     auto it_fa = begin(forces) + baseaddr;
+     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 baseaddr = sampleAddress(pos) * ndims;
+     186         800 :   std::copy(begin(forces) + baseaddr, begin(forces) + baseaddr + ndims,
+     187             :             begin(result));
+     188         800 :   return result;
+     189             : }
+     190             : 
+     191      100618 : unsigned long int DRRForceGrid::getCount(const vector<double> &pos,
+     192             :     bool SkipCheck) const {
+     193      100618 :   if (!SkipCheck) {
+     194        1600 :     if (!isInBoundary(pos)) {
+     195             :       return 0;
+     196             :     }
+     197             :   }
+     198       99818 :   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 {
+     338          52 :   filename += suffix + ".pmf";
+     339             :   FILE *ppmf;
+     340          26 :   ppmf = fopen(filename.c_str(), "w");
+     341          26 :   const double w = dimensions[0].binWidth;
+     342             :   double pmf = 0;
+     343          26 :   fprintf(ppmf, "%.9f %.9f\n", endpoints[0], pmf);
+     344        1166 :   for (size_t i = 0; i < dimensions[0].nbins; ++i) {
+     345        1140 :     vector<double> pos(1, 0);
+     346        1140 :     pos[0] = table[0][i];
+     347        1140 :     const vector<double> f = getGradient(pos, true);
+     348        1140 :     pmf += f[0] * w / outputunit;
+     349        1140 :     fprintf(ppmf, "%.9f %.9f\n", endpoints[i + 1], pmf);
+     350             :   }
+     351          26 :   fclose(ppmf);
+     352          26 : }
+     353             : 
+     354          36 : void DRRForceGrid::writeAll(const string &filename, bool addition) const {
+     355          36 :   string countname = filename + suffix + ".count";
+     356          36 :   string gradname = filename + suffix + ".grad";
+     357          36 :   vector<double> pos(ndims, 0);
+     358             :   FILE *pGrad, *pCount;
+     359          36 :   if (addition) {
+     360           8 :     pGrad = fopen(gradname.c_str(), "a");
+     361           8 :     pCount = fopen(countname.c_str(), "a");
+     362             :   } else {
+     363          28 :     pGrad = fopen(gradname.c_str(), "w");
+     364          28 :     pCount = fopen(countname.c_str(), "w");
+     365             :   }
+     366             : 
+     367             :   char *buffer1, *buffer2;
+     368          36 :   buffer1 = (char *)malloc((sizeof(double)) * sampleSize * ndims);
+     369          36 :   buffer2 = (char *)malloc((sizeof(double)) * sampleSize * ndims);
+     370          36 :   setvbuf(pGrad, buffer1, _IOFBF, (sizeof(double)) * sampleSize * ndims);
+     371          36 :   setvbuf(pCount, buffer2, _IOFBF, (sizeof(double)) * sampleSize * ndims);
+     372          36 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pGrad);
+     373          36 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pCount);
+     374       66048 :   for (size_t i = 0; i < sampleSize; ++i) {
+     375      196896 :     for (size_t j = 0; j < ndims; ++j) {
+     376      130884 :       pos[j] = table[j][i];
+     377      130884 :       fprintf(pGrad, " %.9f", table[j][i]);
+     378      130884 :       fprintf(pCount, " %.9f", table[j][i]);
+     379             :     }
+     380       66012 :     fprintf(pCount, " %lu\n", getCount(pos, true));
+     381       66012 :     vector<double> f = getGradient(pos, true);
+     382      196896 :     for (size_t j = 0; j < ndims; ++j) {
+     383      130884 :       fprintf(pGrad, " %.9f", (f[j] / outputunit));
+     384             :     }
+     385             :     fprintf(pGrad, "\n");
+     386             :   }
+     387          36 :   fclose(pGrad);
+     388          36 :   fclose(pCount);
+     389          36 :   free(buffer1);
+     390          36 :   free(buffer2);
+     391          36 :   if (ndims == 1) {
+     392          52 :     write1DPMF(filename);
+     393             :   }
+     394          36 : }
+     395             : 
+     396           2 : void DRRForceGrid::writeDivergence(const string &filename) const {
+     397           2 :   string divname = filename + suffix + ".div";
+     398           2 :   vector<double> pos(ndims, 0);
+     399             :   FILE *pDiv;
+     400           2 :   pDiv = fopen(divname.c_str(), "w");
+     401           2 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pDiv);
+     402       64802 :   for (size_t i = 0; i < sampleSize; ++i) {
+     403      194400 :     for (size_t j = 0; j < ndims; ++j) {
+     404      129600 :       pos[j] = table[j][i];
+     405      129600 :       fprintf(pDiv, " %.9f", table[j][i]);
+     406             :     }
+     407       64800 :     const double divergence = getDivergence(pos);
+     408       64800 :     fprintf(pDiv, " %.9f", (divergence / outputunit));
+     409             :     fprintf(pDiv, "\n");
+     410             :   }
+     411           2 :   fclose(pDiv);
+     412           2 : }
+     413             : 
+     414         123 : bool ABF::store_getbias(const vector<double> &pos, const vector<double> &f,
+     415             :                         vector<double> &fbias) {
+     416         123 :   if (!isInBoundary(pos)) {
+     417             :     std::fill(begin(fbias), end(fbias), 0.0);
+     418             :     return false;
+     419             :   }
+     420         123 :   const size_t baseaddr = sampleAddress(pos);
+     421             :   unsigned long int &count = samples[baseaddr];
+     422         123 :   ++count;
+     423         123 :   double factor = 2 * (static_cast<double>(count)) / mFullSamples - 1;
+     424         123 :   auto it_fa = begin(forces) + baseaddr * ndims;
+     425             :   auto it_fb = begin(fbias);
+     426             :   auto it_f = begin(f);
+     427             :   auto it_maxFactor = begin(mMaxFactors);
+     428             :   do {
+     429             :     // Clamp to [0,maxFactors]
+     430         207 :     factor = factor < 0 ? 0 : factor > (*it_maxFactor) ? (*it_maxFactor) : factor;
+     431         207 :     (*it_fa) += (*it_f); // Accumulate instantaneous force
+     432         207 :     (*it_fb) = factor * (*it_fa) * (-1.0) /
+     433         207 :                static_cast<double>(count); // Calculate bias force
+     434             :     ++it_fa;
+     435             :     ++it_fb;
+     436             :     ++it_f;
+     437             :     ++it_maxFactor;
+     438         207 :   } while (it_f != end(f));
+     439             : 
+     440             :   return true;
+     441             : }
+     442             : 
+     443           2 : ABF ABF::mergewindow(const ABF &aWA, const ABF &aWB) {
+     444           2 :   const vector<DRRAxis> dR = merge(aWA.dimensions, aWB.dimensions);
+     445           2 :   const string suffix = ".abf";
+     446           2 :   ABF result(dR, suffix);
+     447           2 :   const size_t nrows = result.sampleSize;
+     448           2 :   const size_t ncols = result.ndims;
+     449           2 :   vector<double> pos(ncols, 0);
+     450         402 :   for (size_t i = 0; i < nrows; ++i) {
+     451         800 :     for (size_t j = 0; j < ncols; ++j) {
+     452         400 :       pos[j] = result.table[j][i];
+     453             :     }
+     454         400 :     const unsigned long int countA = aWA.getCount(pos);
+     455         400 :     const unsigned long int countB = aWB.getCount(pos);
+     456         400 :     const vector<double> aForceA = aWA.getAccumulatedForces(pos);
+     457         400 :     const vector<double> aForceB = aWB.getAccumulatedForces(pos);
+     458         400 :     result.store(pos, aForceA, countA);
+     459         400 :     result.store(pos, aForceB, countB);
+     460             :   }
+     461           2 :   return result;
+     462           0 : }
+     463             : 
+     464      195576 : vector<double> CZAR::getGradient(const vector<double> &pos,
+     465             :                                  bool SkipCheck) const {
+     466      195576 :   vector<double> result(ndims, 0);
+     467      195576 :   if (!SkipCheck) {
+     468      162000 :     if (!isInBoundary(pos)) {
+     469             :       return result;
+     470             :     }
+     471             :   }
+     472      195576 :   if (kbt <= std::numeric_limits<double>::epsilon()) {
+     473             :     std::cerr << "ERROR! The kbt shouldn't be zero when use CZAR estimator. "
+     474           0 :               << '\n';
+     475           0 :     std::abort();
+     476             :   }
+     477      195576 :   const size_t baseaddr = sampleAddress(pos);
+     478      195576 :   const vector<double> log_deriv(getCountsLogDerivative(pos));
+     479             :   const unsigned long int &count = samples[baseaddr];
+     480      195576 :   if (count == 0)
+     481             :     return result;
+     482      195421 :   auto it_fa = begin(forces) + baseaddr * ndims;
+     483      195421 :   std::transform(it_fa, it_fa + ndims, begin(log_deriv), begin(result),
+     484      389822 :   [&count, this](double fa, double ld) {
+     485      389822 :     return fa * (-1.0) / count - kbt * ld;
+     486             :   });
+     487      195421 :   return result;
+     488             : }
+     489             : 
+     490           2 : CZAR CZAR::mergewindow(const CZAR &cWA, const CZAR &cWB) {
+     491           2 :   const vector<DRRAxis> dR = merge(cWA.dimensions, cWB.dimensions);
+     492           2 :   const double newkbt = cWA.kbt;
+     493           2 :   const string suffix = ".czar";
+     494             :   CZAR result(dR, suffix, newkbt);
+     495           2 :   const size_t nrows = result.sampleSize;
+     496           2 :   const size_t ncols = result.ndims;
+     497           2 :   vector<double> pos(ncols, 0);
+     498         402 :   for (size_t i = 0; i < nrows; ++i) {
+     499         800 :     for (size_t j = 0; j < ncols; ++j) {
+     500         400 :       pos[j] = result.table[j][i];
+     501             :     }
+     502         400 :     const unsigned long int countA = cWA.getCount(pos);
+     503         400 :     const unsigned long int countB = cWB.getCount(pos);
+     504         400 :     const vector<double> aForceA = cWA.getAccumulatedForces(pos);
+     505         400 :     const vector<double> aForceB = cWB.getAccumulatedForces(pos);
+     506         400 :     result.store(pos, aForceA, countA);
+     507         400 :     result.store(pos, aForceB, countB);
+     508             :   }
+     509           2 :   return result;
+     510             : }
+     511             : 
+     512          18 : void CZAR:: writeZCount(const string &filename, bool addition) const {
+     513          18 :   string countname = filename + ".zcount";
+     514          18 :   vector<double> pos(ndims, 0);
+     515             :   FILE *pCount;
+     516          18 :   if (addition) {
+     517           4 :     pCount = fopen(countname.c_str(), "a");
+     518             :   } else {
+     519          14 :     pCount = fopen(countname.c_str(), "w");
+     520             :   }
+     521             :   char *buffer;
+     522          18 :   buffer = (char *)malloc((sizeof(double)) * sampleSize * ndims);
+     523          18 :   setvbuf(pCount, buffer, _IOFBF, (sizeof(double)) * sampleSize * ndims);
+     524          18 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pCount);
+     525       33024 :   for (size_t i = 0; i < sampleSize; ++i) {
+     526       98448 :     for (size_t j = 0; j < ndims; ++j) {
+     527       65442 :       pos[j] = table[j][i];
+     528       65442 :       fprintf(pCount, " %.9f", table[j][i]);
+     529             :     }
+     530       33006 :     fprintf(pCount, " %lu\n", getCount(pos, true));
+     531             :   }
+     532          18 :   fclose(pCount);
+     533          18 :   free(buffer);
+     534          18 : }
+     535             : 
+     536             : }
+     537             : }
+     538             : 
+     539             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..f1101b07be --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/drr/DRR.h.func.html b/coverage/drr/DRR.h.func.html new file mode 100644 index 0000000000..8b4210ed12 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/drr/DRR.h.gcov.html b/coverage/drr/DRR.h.gcov.html new file mode 100644 index 0000000000..ed1773a5a5 --- /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-06-10 08:19:14Functions: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;
+     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, bool addition = false) const;
+     195             :   /// Output divergence (.div) (experimental)
+     196             :   void writeDivergence(const string &filename) 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         152 :   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          63 :   ~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 writeZCount(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.15
+
+ + + 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 0000000000..d12d79e60a --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:40344490.8 %
Date:2024-06-10 08:19:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr27DynamicReferenceRestrainingC2ERKNS_13ActionOptionsE0
_ZN4PLMD3drr27DynamicReferenceRestraining10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestraining13is_file_existEPKc1
_ZN4PLMD3drr27DynamicReferenceRestraining4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr12_GLOBAL__N_140DynamicReferenceRestrainingRegisterMe2436createERKNS_13ActionOptionsE12
_ZN4PLMD3drr27DynamicReferenceRestrainingC1ERKNS_13ActionOptionsE12
_ZN4PLMD3drr27DynamicReferenceRestraining16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD3drr27DynamicReferenceRestraining4saveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx19
_ZN4PLMD3drr27DynamicReferenceRestraining6updateEv123
_ZN4PLMD3drr27DynamicReferenceRestraining9calculateEv123
_ZN4PLMD3drr12_GLOBAL__N_140DynamicReferenceRestrainingRegisterMe243C2Ev3473
_ZN4PLMD3drr12_GLOBAL__N_140DynamicReferenceRestrainingRegisterMe243D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.func.html b/coverage/drr/DynamicReferenceRestraining.cpp.func.html new file mode 100644 index 0000000000..1c294f30cd --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:40344490.8 %
Date:2024-06-10 08:19:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12_GLOBAL__N_140DynamicReferenceRestrainingRegisterMe2436createERKNS_13ActionOptionsE12
_ZN4PLMD3drr12_GLOBAL__N_140DynamicReferenceRestrainingRegisterMe243C2Ev3473
_ZN4PLMD3drr12_GLOBAL__N_140DynamicReferenceRestrainingRegisterMe243D2Ev3473
_ZN4PLMD3drr27DynamicReferenceRestraining10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestraining13is_file_existEPKc1
_ZN4PLMD3drr27DynamicReferenceRestraining16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD3drr27DynamicReferenceRestraining4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestraining4saveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx19
_ZN4PLMD3drr27DynamicReferenceRestraining6updateEv123
_ZN4PLMD3drr27DynamicReferenceRestraining9calculateEv123
_ZN4PLMD3drr27DynamicReferenceRestrainingC1ERKNS_13ActionOptionsE12
_ZN4PLMD3drr27DynamicReferenceRestrainingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html b/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html new file mode 100644 index 0000000000..ffa66090ba --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html @@ -0,0 +1,971 @@ + + + + + + + + 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:40344490.8 %
Date:2024-06-10 08:19:14Functions:111291.7 %
+
+ + + + + + + + +

+
          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/Atoms.h"
+      22             : #include "core/PlumedMain.h"
+      23             : #include "DRR.h"
+      24             : #include "tools/Random.h"
+      25             : #include "tools/Tools.h"
+      26             : #include "colvar_UIestimator.h"
+      27             : 
+      28             : #include <boost/archive/binary_iarchive.hpp>
+      29             : #include <boost/archive/binary_oarchive.hpp>
+      30             : #include <boost/serialization/vector.hpp>
+      31             : #include <cmath>
+      32             : #include <fstream>
+      33             : #include <iomanip>
+      34             : #include <iostream>
+      35             : #include <limits>
+      36             : #include <random>
+      37             : #include <string>
+      38             : 
+      39             : using namespace PLMD;
+      40             : using namespace bias;
+      41             : using namespace std;
+      42             : 
+      43             : namespace PLMD {
+      44             : namespace drr {
+      45             : 
+      46             : //+PLUMEDOC EABFMOD_BIAS DRR
+      47             : /*
+      48             : Used to performed extended-system adaptive biasing force(eABF) \cite Lelievre2007 method
+      49             :  on one or more collective variables. This method is also
+      50             :  called dynamic reference restraining(DRR) \cite Zheng2012 . A detailed description
+      51             :  of this module can be found at \cite Chen2018 .
+      52             : 
+      53             : For each collective variable \f$\xi_i\f$, a fictitious variable \f$\lambda_i\f$
+      54             : is attached through a spring. The fictitious variable \f$\lambda_i\f$ undergoes
+      55             : overdamped Langevin dynamics just like \ref EXTENDED_LAGRANGIAN. The ABF
+      56             : algorithm applies bias force on \f$\lambda_i\f$. The bias force acts on
+      57             : \f$\lambda_i\f$ is the negative average spring force on \f$\lambda_i\f$, which
+      58             : enhances the sampling of \f$\lambda_i\f$.
+      59             : 
+      60             : \f[
+      61             : F_{bias}(\lambda_i)=k(\lambda_i-\langle\xi_i\rangle_{\lambda_i})
+      62             : \f]
+      63             : 
+      64             : If spring force constant k is large enough, then \f$\xi_i\f$ synchronizes with
+      65             : \f$\lambda_i\f$. The naive(ABF) estimator is just the negative
+      66             : average spring force of \f$\lambda_i\f$.
+      67             : 
+      68             : The naive(ABF) estimator is biased. There are unbiased estimators such as
+      69             : CZAR(Corrected z-averaged restraint) \cite Lesage2016 and UI(Umbrella
+      70             : Integration).
+      71             : The CZAR estimates the gradients as:
+      72             : 
+      73             : \f[
+      74             : \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)
+      75             : \f]
+      76             : 
+      77             : The UI estimates the gradients as:
+      78             : \f[
+      79             : 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)}
+      80             : \f]
+      81             : 
+      82             : The code performing UI(colvar_UIestimator.h) is contributed by Haohao Fu \cite Fu2016 .
+      83             : It may be slow. I only change the Boltzmann constant and output
+      84             : precision in it. For new version and issues, please see:
+      85             : https://github.com/fhh2626/colvars
+      86             : 
+      87             : 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. To get PMF, the abf_integrate(https://github.com/Colvars/colvars/tree/master/colvartools) is useful.
+      88             : 
+      89             : \par Examples
+      90             : 
+      91             : The following input tells plumed to perform a eABF/DRR simulation on two
+      92             : torsional angles.
+      93             : \plumedfile
+      94             : phi: TORSION ATOMS=5,7,9,15
+      95             : psi: TORSION ATOMS=7,9,15,17
+      96             : 
+      97             : DRR ...
+      98             : LABEL=eabf
+      99             : ARG=phi,psi
+     100             : FULLSAMPLES=500
+     101             : GRID_MIN=-pi,-pi
+     102             : GRID_MAX=pi,pi
+     103             : GRID_BIN=180,180
+     104             : FRICTION=8.0,8.0
+     105             : TAU=0.5,0.5
+     106             : OUTPUTFREQ=50000
+     107             : HISTORYFREQ=500000
+     108             : ... DRR
+     109             : 
+     110             : # monitor the two variables, their fictitious variables and applied forces.
+     111             : PRINT STRIDE=10 ARG=phi,psi,eabf.phi_fict,eabf.psi_fict,eabf.phi_biasforce,eabf.psi_biasforce FILE=COLVAR
+     112             : \endplumedfile
+     113             : 
+     114             : The following input tells plumed to perform a eABF/DRR simulation on the
+     115             : distance of atom 10 and 92. The distance is restraint by \ref LOWER_WALLS and
+     116             : \ref UPPER_WALLS.
+     117             : \plumedfile
+     118             : dist1: DISTANCE ATOMS=10,92
+     119             : 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
+     120             : uwall: UPPER_WALLS ARG=eabf_winall.dist1_fict AT=3.2 KAPPA=418.4
+     121             : lwall: LOWER_WALLS ARG=eabf_winall.dist1_fict AT=1.2 KAPPA=418.4
+     122             : PRINT STRIDE=10 ARG=dist1,eabf_winall.dist1_fict,eabf_winall.dist1_biasforce FILE=COLVAR
+     123             : \endplumedfile
+     124             : 
+     125             : It's also possible to run extended generalized adaptive biasing force (egABF) described in \cite Zhao2017 .
+     126             : An egABF example:
+     127             : \plumedfile
+     128             : phi: TORSION ATOMS=5,7,9,15
+     129             : psi: TORSION ATOMS=7,9,15,17
+     130             : 
+     131             : DRR ...
+     132             : LABEL=gabf_phi
+     133             : ARG=phi
+     134             : FULLSAMPLES=500
+     135             : GRID_MIN=-pi
+     136             : GRID_MAX=pi
+     137             : GRID_BIN=180
+     138             : FRICTION=8.0
+     139             : TAU=0.5
+     140             : OUTPUTFREQ=50000
+     141             : HISTORYFREQ=500000
+     142             : ... DRR
+     143             : 
+     144             : DRR ...
+     145             : LABEL=gabf_psi
+     146             : ARG=psi
+     147             : FULLSAMPLES=500
+     148             : GRID_MIN=-pi
+     149             : GRID_MAX=pi
+     150             : GRID_BIN=180
+     151             : FRICTION=8.0
+     152             : TAU=0.5
+     153             : OUTPUTFREQ=50000
+     154             : HISTORYFREQ=500000
+     155             : ... DRR
+     156             : 
+     157             : DRR ...
+     158             : LABEL=gabf_2d
+     159             : ARG=phi,psi
+     160             : EXTERNAL_FORCE=gabf_phi.phi_springforce,gabf_psi.psi_springforce
+     161             : EXTERNAL_FICT=gabf_phi.phi_fictNoPBC,gabf_psi.psi_fictNoPBC
+     162             : GRID_MIN=-pi,-pi
+     163             : GRID_MAX=pi,pi
+     164             : GRID_BIN=180,180
+     165             : NOBIAS
+     166             : OUTPUTFREQ=50000
+     167             : HISTORYFREQ=500000
+     168             : ... DRR
+     169             : 
+     170             : PRINT STRIDE=10 ARG=phi,psi FILE=COLVAR
+     171             : \endplumedfile
+     172             : 
+     173             :  */
+     174             : //+ENDPLUMEDOC
+     175             : 
+     176             : using std::vector;
+     177             : using std::string;
+     178             : 
+     179             : class DynamicReferenceRestraining : public Bias {
+     180             : private:
+     181             :   bool firsttime;
+     182             :   bool nobias;
+     183             :   vector<double> fictNoPBC;
+     184             :   vector<double> real;
+     185             :   vector<double> springlength; // spring lengths
+     186             :   vector<double> fict;         // coordinates of extended variables
+     187             :   vector<double> vfict;        // velocities of extended variables
+     188             :   vector<double> vfict_laststep;
+     189             :   vector<double> ffict; // forces exerted on extended variables
+     190             :   vector<double> fbias; // bias forces from eABF
+     191             :   vector<double> kappa;
+     192             :   vector<double> tau;
+     193             :   vector<double> friction;
+     194             :   vector<double> etemp;
+     195             :   vector<double> ffict_measured;
+     196             :   vector<double> force_external;
+     197             :   vector<double> fict_external;
+     198             :   vector<Value *> biasforceValue;
+     199             :   vector<Value *> springforceValue;
+     200             :   vector<Value *> fictValue;
+     201             :   vector<Value *> vfictValue;
+     202             :   vector<Value *> fictNoPBCValue;
+     203             :   vector<Value *> externalForceValue;
+     204             :   vector<Value *> externalFictValue;
+     205             :   vector<double> c1;
+     206             :   vector<double> c2;
+     207             :   vector<double> mass;
+     208             :   vector<DRRAxis> delim;
+     209             :   string outputname;
+     210             :   string cptname;
+     211             :   string outputprefix;
+     212             :   const size_t ndims;
+     213             :   double dt;
+     214             :   double kbt;
+     215             :   double outputfreq;
+     216             :   double historyfreq;
+     217             :   bool isRestart;
+     218             :   bool useCZARestimator;
+     219             :   bool useUIestimator;
+     220             :   bool mergeHistoryFiles;
+     221             :   bool textoutput;
+     222             :   bool withExternalForce;
+     223             :   bool withExternalFict;
+     224             :   vector<unsigned> reflectingWall;
+     225             :   ABF ABFGrid;
+     226             :   CZAR CZARestimator;
+     227             :   double fullsamples;
+     228             :   vector<double> maxFactors;
+     229             :   UIestimator::UIestimator eabf_UI;
+     230             :   Random rand;
+     231             : 
+     232             : public:
+     233             :   explicit DynamicReferenceRestraining(const ActionOptions &);
+     234             :   void calculate();
+     235             :   void update();
+     236             :   void save(const string &filename, long long int step);
+     237             :   void load(const string &filename);
+     238             :   void backupFile(const string &filename);
+     239             :   static void registerKeywords(Keywords &keys);
+     240             :   bool is_file_exist(const char *fileName);
+     241             : };
+     242             : 
+     243       10443 : PLUMED_REGISTER_ACTION(DynamicReferenceRestraining, "DRR")
+     244             : 
+     245          13 : void DynamicReferenceRestraining::registerKeywords(Keywords &keys) {
+     246          13 :   Bias::registerKeywords(keys);
+     247          13 :   keys.use("ARG");
+     248          26 :   keys.add("optional", "KAPPA", "specifies that the restraint is harmonic and "
+     249             :            "what the values of the force constants on "
+     250             :            "each of the variables are (default to "
+     251             :            "\\f$k_BT\\f$/(GRID_SPACING)^2)");
+     252          26 :   keys.add("compulsory", "TAU", "0.5", "specifies relaxation time on each of "
+     253             :            "variables are, similar to "
+     254             :            "extended Time Constant in Colvars");
+     255          26 :   keys.add("compulsory", "FRICTION", "8.0",
+     256             :            "add a friction to the variable, similar to extended Langevin Damping "
+     257             :            "in Colvars");
+     258          26 :   keys.add("compulsory", "GRID_MIN", "the lower bounds for the grid (GRID_BIN "
+     259             :            "or GRID_SPACING should be specified)");
+     260          26 :   keys.add("compulsory", "GRID_MAX", "the upper bounds for the grid (GRID_BIN "
+     261             :            "or GRID_SPACING should be specified)");
+     262          26 :   keys.add("compulsory", "REFLECTINGWALL", "0", "whether add reflecting walls "
+     263             :            "for each CV at GRID_MIN and GRID_MAX. Setting non-zero values will "
+     264             :            "enable this feature");
+     265          26 :   keys.add("optional", "GRID_BIN", "the number of bins for the grid");
+     266          26 :   keys.add("optional", "GRID_SPACING", "the approximate grid spacing (to be "
+     267             :            "used as an alternative or together "
+     268             :            "with GRID_BIN)");
+     269          26 :   keys.add("optional", "ZGRID_MIN", "the lower bounds for the grid (ZGRID_BIN"
+     270             :            " or ZGRID_SPACING should be specified)");
+     271          26 :   keys.add("optional", "ZGRID_MAX", "the upper bounds for the grid (ZGRID_BIN"
+     272             :            " or ZGRID_SPACING should be specified)");
+     273          26 :   keys.add("optional", "ZGRID_BIN", "the number of bins for the grid");
+     274          26 :   keys.add("optional", "ZGRID_SPACING", "the approximate grid spacing (to be "
+     275             :            "used as an alternative or together "
+     276             :            "with ZGRID_BIN)");
+     277          26 :   keys.add("optional", "EXTERNAL_FORCE", "use forces from other action instead"
+     278             :            " of internal spring force, this disable the extended system!");
+     279          26 :   keys.add("optional", "EXTERNAL_FICT", "position of external fictitious "
+     280             :            "particles, useful for UIESTIMATOR");
+     281          26 :   keys.add("compulsory", "FULLSAMPLES", "500",
+     282             :            "number of samples in a bin prior to application of the ABF");
+     283          26 :   keys.add("compulsory", "MAXFACTOR", "1.0",
+     284             :            "maximum scaling factor of biasing force");
+     285          26 :   keys.add("compulsory", "OUTPUTFREQ", "write results to a file every N steps");
+     286          26 :   keys.add("optional", "HISTORYFREQ", "save history to a file every N steps");
+     287          26 :   keys.addFlag("NOCZAR", false, "disable the CZAR estimator");
+     288          26 :   keys.addFlag("UI", false,
+     289             :                "enable the umbrella integration estimator");
+     290          26 :   keys.add("optional", "UIRESTARTPREFIX",
+     291             :            "specify the restart files for umbrella integration");
+     292          26 :   keys.add("optional", "OUTPUTPREFIX",
+     293             :            "specify the output prefix (default to the label name)");
+     294          26 :   keys.add("optional", "TEMP", "the system temperature - needed when FRICTION "
+     295             :            "is present. If not provided will be taken from "
+     296             :            "MD code (if available)");
+     297          26 :   keys.add(
+     298             :     "optional", "EXTTEMP",
+     299             :     "the temperature of extended variables (default to system temperature)");
+     300          26 :   keys.add("optional", "DRR_RFILE",
+     301             :            "specifies the restart file (.drrstate file)");
+     302          26 :   keys.addFlag("NOBIAS", false, "DO NOT apply bias forces.");
+     303          26 :   keys.addFlag("TEXTOUTPUT", false, "use text output for grad and count files "
+     304             :                "instead of boost::serialization binary "
+     305             :                "output");
+     306          26 :   keys.addFlag("MERGEHISTORYFILES", false, "output all historic results "
+     307             :                "to a single file rather than multiple .drrstate files. "
+     308             :                "This option is effective only when textOutput is on.");
+     309          13 :   componentsAreNotOptional(keys);
+     310          26 :   keys.addOutputComponent(
+     311             :     "_fict", "default",
+     312             :     "one or multiple instances of this quantity can be referenced "
+     313             :     "elsewhere in the input file. "
+     314             :     "These quantities will named with the arguments of the bias followed by "
+     315             :     "the character string _tilde. It is possible to add forces on these "
+     316             :     "variable.");
+     317          26 :   keys.addOutputComponent(
+     318             :     "_vfict", "default",
+     319             :     "one or multiple instances of this quantity can be referenced "
+     320             :     "elsewhere in the input file. "
+     321             :     "These quantities will named with the arguments of the bias followed by "
+     322             :     "the character string _tilde. It is NOT possible to add forces on these "
+     323             :     "variable.");
+     324          26 :   keys.addOutputComponent(
+     325             :     "_biasforce", "default",
+     326             :     "The bias force from eABF/DRR of the fictitious particle.");
+     327          26 :   keys.addOutputComponent("_springforce", "default", "Spring force between real CVs and extended CVs");
+     328          26 :   keys.addOutputComponent("_fictNoPBC", "default",
+     329             :                           "the positions of fictitious particles (without PBC).");
+     330          13 : }
+     331             : 
+     332          12 : DynamicReferenceRestraining::DynamicReferenceRestraining(
+     333          12 :   const ActionOptions &ao)
+     334          12 :   : PLUMED_BIAS_INIT(ao), firsttime(true), nobias(false),
+     335          12 :     fictNoPBC(getNumberOfArguments(), 0.0), real(getNumberOfArguments(), 0.0),
+     336          12 :     springlength(getNumberOfArguments(), 0.0),
+     337          12 :     fict(getNumberOfArguments(), 0.0), vfict(getNumberOfArguments(), 0.0),
+     338          12 :     vfict_laststep(getNumberOfArguments(), 0.0),
+     339          12 :     ffict(getNumberOfArguments(), 0.0), fbias(getNumberOfArguments(), 0.0),
+     340          12 :     kappa(getNumberOfArguments(), 0.0), tau(getNumberOfArguments(), 0.0),
+     341          12 :     friction(getNumberOfArguments(), 0.0), etemp(getNumberOfArguments(), 0.0),
+     342          12 :     ffict_measured(getNumberOfArguments(), 0.0),
+     343          12 :     biasforceValue(getNumberOfArguments(), NULL),
+     344          12 :     springforceValue(getNumberOfArguments(), NULL),
+     345          12 :     fictValue(getNumberOfArguments(), NULL),
+     346          12 :     vfictValue(getNumberOfArguments(), NULL),
+     347          12 :     fictNoPBCValue(getNumberOfArguments(), NULL),
+     348          12 :     externalForceValue(getNumberOfArguments(), NULL),
+     349          12 :     externalFictValue(getNumberOfArguments(), NULL),
+     350          12 :     c1(getNumberOfArguments(), 0.0),
+     351          12 :     c2(getNumberOfArguments(), 0.0), mass(getNumberOfArguments(), 0.0),
+     352          12 :     delim(getNumberOfArguments()), outputname(""), cptname(""),
+     353          12 :     outputprefix(""), ndims(getNumberOfArguments()), dt(0.0), kbt(0.0),
+     354          12 :     outputfreq(0.0), historyfreq(-1.0), isRestart(false),
+     355          12 :     useCZARestimator(true), useUIestimator(false), textoutput(false),
+     356          12 :     withExternalForce(false), withExternalFict(false), mergeHistoryFiles(false),
+     357          12 :     reflectingWall(getNumberOfArguments(), 0),
+     358          36 :     maxFactors(getNumberOfArguments(), 1.0)
+     359             : {
+     360          12 :   log << "eABF/DRR: You now are using the extended adaptive biasing "
+     361             :       "force(eABF) method."
+     362          12 :       << '\n';
+     363          12 :   log << "eABF/DRR: Some people also refer to it as dynamic reference "
+     364             :       "restraining(DRR) method."
+     365          12 :       << '\n';
+     366          12 :   log << "eABF/DRR: Currently the CZAR and naive(ABF on extended variables) "
+     367             :       "estimator is enabled by default."
+     368          12 :       << '\n';
+     369          12 :   log << "eABF/DRR: For reasons of performance, the umbrella integration "
+     370             :       "estimator is not enabled by default."
+     371          12 :       << '\n';
+     372          12 :   log << "eABF/DRR: This method is originally implemented in "
+     373             :       "colvars(https://github.com/colvars/colvars)."
+     374          12 :       << '\n';
+     375          12 :   log << "eABF/DRR: The code in plumed is heavily modified from "
+     376             :       "ExtendedLagrangian.cpp and doesn't implemented all variants of "
+     377             :       "eABF/DRR."
+     378          12 :       << '\n';
+     379          12 :   log << "eABF/DRR: The thermostat used here may be different from Colvars."
+     380          12 :       << '\n';
+     381          12 :   log << "eABF/DRR: To integrate the gradients file, you can use abf_integrate "
+     382             :       "from https://github.com/colvars/colvars/tree/master/colvartools."
+     383          12 :       << '\n';
+     384          12 :   log << "eABF/DRR: Please read relevant articles and use this biasing "
+     385             :       "method carefully!"
+     386          12 :       << '\n';
+     387          12 :   parseFlag("NOBIAS", nobias);
+     388          12 :   parseFlag("UI", useUIestimator);
+     389          12 :   bool noCZAR = false;
+     390          12 :   parseFlag("NOCZAR", noCZAR);
+     391             : //   noCZAR == false ? useCZARestimator = true : useCZARestimator = false;
+     392          12 :   parseFlag("TEXTOUTPUT", textoutput);
+     393          12 :   parseFlag("MERGEHISTORYFILES", mergeHistoryFiles);
+     394          12 :   parseVector("TAU", tau);
+     395          12 :   parseVector("FRICTION", friction);
+     396          12 :   parseVector("EXTTEMP", etemp);
+     397          12 :   parseVector("KAPPA", kappa);
+     398          12 :   parseVector("REFLECTINGWALL", reflectingWall);
+     399          12 :   double temp = -1.0;
+     400          12 :   parse("TEMP", temp);
+     401          12 :   parse("FULLSAMPLES", fullsamples);
+     402          12 :   parseVector("MAXFACTOR", maxFactors);
+     403          12 :   parse("OUTPUTFREQ", outputfreq);
+     404          12 :   parse("HISTORYFREQ", historyfreq);
+     405          24 :   parse("OUTPUTPREFIX", outputprefix);
+     406             :   string restart_prefix;
+     407          24 :   parse("DRR_RFILE", restart_prefix);
+     408             :   string uirprefix;
+     409          12 :   parse("UIRESTARTPREFIX", uirprefix);
+     410          12 :   parseArgumentList("EXTERNAL_FORCE", externalForceValue);
+     411          24 :   parseArgumentList("EXTERNAL_FICT", externalFictValue);
+     412          12 :   if (externalForceValue.empty()) {
+     413          11 :     withExternalForce = false;
+     414           1 :   } else if (externalForceValue.size() != ndims) {
+     415           0 :     error("eABF/DRR: Number of forces doesn't match ARGS!");
+     416             :   } else {
+     417           1 :     withExternalForce = true;
+     418             :   }
+     419          12 :   if (withExternalForce && useUIestimator) {
+     420           1 :     if (externalFictValue.empty()) {
+     421           0 :       error("eABF/DRR: No external fictitious particles specified. UI estimator needs it.");
+     422           1 :     } else if(externalFictValue.size() != ndims) {
+     423           0 :       error("eABF/DRR: Number of fictitious particles doesn't match ARGS!");
+     424             :     } else {
+     425           1 :       withExternalFict = true;
+     426             :     }
+     427             :   }
+     428          12 :   if (temp >= 0.0)
+     429          12 :     kbt = plumed.getAtoms().getKBoltzmann() * temp;
+     430             :   else {
+     431           0 :     kbt = plumed.getAtoms().getKbT();
+     432           0 :     if (kbt <= std::numeric_limits<double>::epsilon()) {
+     433           0 :       error("eABF/DRR: It seems the MD engine does not setup the temperature correctly for PLUMED."
+     434             :             "Please set it by the TEMP keyword manually.");
+     435             :     }
+     436             :   }
+     437          12 :   if (fullsamples < 0.5) {
+     438           0 :     fullsamples = 500.0;
+     439           0 :     log << "eABF/DRR: The fullsamples parametre is not set. Set it to "
+     440             :         "500(default)."
+     441           0 :         << '\n';
+     442             :   }
+     443          12 :   if (getRestart()) {
+     444           1 :     if (restart_prefix.length() != 0) {
+     445           1 :       isRestart = true;
+     446           1 :       firsttime = false;
+     447           1 :       load(restart_prefix);
+     448             :     } else {
+     449           0 :       log << "eABF/DRR: You don't specify the file for restarting." << '\n';
+     450           0 :       log << "eABF/DRR: So I assume you are splitting windows." << '\n';
+     451           0 :       isRestart = false;
+     452           0 :       firsttime = true;
+     453             :     }
+     454             :   }
+     455             : 
+     456          12 :   vector<string> gmin(ndims);
+     457          12 :   vector<string> zgmin(ndims);
+     458          12 :   parseVector("GRID_MIN", gmin);
+     459          24 :   parseVector("ZGRID_MIN", zgmin);
+     460          12 :   if (gmin.size() != ndims)
+     461           0 :     error("eABF/DRR: not enough values for GRID_MIN");
+     462          12 :   if (zgmin.size() != ndims) {
+     463          33 :     log << "eABF/DRR: You didn't specify ZGRID_MIN. " << '\n'
+     464          11 :         << "eABF/DRR: The GRID_MIN will be used instead.";
+     465          11 :     zgmin = gmin;
+     466             :   }
+     467          12 :   vector<string> gmax(ndims);
+     468          12 :   vector<string> zgmax(ndims);
+     469          12 :   parseVector("GRID_MAX", gmax);
+     470          24 :   parseVector("ZGRID_MAX", zgmax);
+     471          12 :   if (gmax.size() != ndims)
+     472           0 :     error("eABF/DRR: not enough values for GRID_MAX");
+     473          12 :   if (zgmax.size() != ndims) {
+     474          33 :     log << "eABF/DRR: You didn't specify ZGRID_MAX. " << '\n'
+     475          11 :         << "eABF/DRR: The GRID_MAX will be used instead.";
+     476          11 :     zgmax = gmax;
+     477             :   }
+     478          12 :   vector<unsigned> gbin(ndims);
+     479          12 :   vector<unsigned> zgbin(ndims);
+     480          12 :   vector<double> gspacing(ndims);
+     481          12 :   vector<double> zgspacing(ndims);
+     482          12 :   parseVector("GRID_BIN", gbin);
+     483          12 :   parseVector("ZGRID_BIN", zgbin);
+     484          12 :   parseVector("GRID_SPACING", gspacing);
+     485          24 :   parseVector("ZGRID_SPACING", zgspacing);
+     486          12 :   if (gbin.size() != ndims) {
+     487           3 :     log << "eABF/DRR: You didn't specify GRID_BIN. Trying to use GRID_SPACING "
+     488             :         "instead."
+     489           3 :         << '\n';
+     490           3 :     if (gspacing.size() != ndims) {
+     491           0 :       error("eABF/DRR: not enough values for GRID_BIN");
+     492             :     } else {
+     493           3 :       gbin.resize(ndims);
+     494           6 :       for (size_t i = 0; i < ndims; ++i) {
+     495             :         double l, h;
+     496           3 :         PLMD::Tools::convert(gmin[i], l);
+     497           3 :         PLMD::Tools::convert(gmax[i], h);
+     498           3 :         gbin[i] = std::nearbyint((h - l) / gspacing[i]);
+     499           3 :         gspacing[i] = (h - l) / gbin[i];
+     500           3 :         log << "GRID_BIN[" << i << "] is " << gbin[i] << '\n';
+     501             :       }
+     502             :     }
+     503             :   }
+     504          12 :   if (zgbin.size() != ndims) {
+     505          11 :     log << "eABF/DRR: You didn't specify ZGRID_BIN. Trying to use ZGRID_SPACING instead." << '\n';
+     506          11 :     if (zgspacing.size() != ndims) {
+     507          11 :       log << "eABF/DRR: You didn't specify ZGRID_SPACING. Trying to use GRID_SPACING or GRID_BIN instead." << '\n';
+     508          11 :       zgbin = gbin;
+     509          11 :       zgspacing = gspacing;
+     510             :     } else {
+     511           0 :       zgbin.resize(ndims);
+     512           0 :       for (size_t i = 0; i < ndims; ++i) {
+     513             :         double l, h;
+     514           0 :         PLMD::Tools::convert(zgmin[i], l);
+     515           0 :         PLMD::Tools::convert(zgmax[i], h);
+     516           0 :         zgbin[i] = std::nearbyint((h - l) / zgspacing[i]);
+     517           0 :         zgspacing[i] = (h - l) / zgbin[i];
+     518           0 :         log << "ZGRID_BIN[" << i << "] is " << zgbin[i] << '\n';
+     519             :       }
+     520             :     }
+     521             :   }
+     522          12 :   checkRead();
+     523             : 
+     524             :   // Set up kbt for extended system
+     525          12 :   log << "eABF/DRR: The fullsamples is " << fullsamples << '\n';
+     526          12 :   log << "eABF/DRR: The kbt(real system) is " << kbt << '\n';
+     527          12 :   dt = getTimeStep() * getStride();
+     528          12 :   log << "eABF/DRR: timestep = " << getTimeStep() << " ps with stride = " << getStride() << " steps\n";
+     529          12 :   vector<double> ekbt(ndims, 0.0);
+     530          12 :   if (etemp.size() != ndims) {
+     531          12 :     etemp.assign(ndims, kbt / plumed.getAtoms().getKBoltzmann());
+     532             :   }
+     533          12 :   if (tau.size() != ndims) {
+     534           0 :     tau.assign(ndims, 0.5);
+     535             :   }
+     536          12 :   if (friction.size() != ndims) {
+     537           0 :     friction.assign(ndims, 8.0);
+     538             :   }
+     539          12 :   if (maxFactors.size() != ndims) {
+     540           0 :     maxFactors.assign(ndims, 1.0);
+     541             :   }
+     542          31 :   for (size_t i = 0; i < ndims; ++i) {
+     543          19 :     log << "eABF/DRR: The maximum scaling factor [" << i << "] is " << maxFactors[i] << '\n';
+     544          19 :     if (maxFactors[i] > 1.0) {
+     545           0 :       log << "eABF/DRR: Warning! The maximum scaling factor larger than 1.0 is not recommended!" << '\n';
+     546             :     }
+     547             :   }
+     548          31 :   for (size_t i = 0; i < ndims; ++i) {
+     549          19 :     ekbt[i] = etemp[i] * plumed.getAtoms().getKBoltzmann();
+     550          19 :     log << "eABF/DRR: The kbt(extended system) of [" << i << "] is " << ekbt[i]
+     551          19 :         << '\n';
+     552          19 :     log << "eABF/DRR: relaxation time tau [" << i << "] is " << tau[i] << '\n';
+     553          19 :     log << "eABF/DRR: Extended variable [" << i << "] has friction: " << friction[i] << '\n';
+     554             :   }
+     555             : 
+     556             :   // Set up the force grid
+     557          12 :   vector<DRRAxis> zdelim(ndims);
+     558          31 :   for (size_t i = 0; i < ndims; ++i) {
+     559          19 :     log << "eABF/DRR: The " << i << " dimensional grid minimum is " << gmin[i]
+     560          19 :         << '\n';
+     561          19 :     log << "eABF/DRR: The " << i << " dimensional grid maximum is " << gmax[i]
+     562          19 :         << '\n';
+     563          19 :     log << "eABF/DRR: The " << i << " dimensional grid has " << gbin[i]
+     564          19 :         << " bins" << '\n';
+     565          19 :     log << "eABF/DRR: The " << i << " dimensional zgrid minimum is " << zgmin[i]
+     566          19 :         << '\n';
+     567          19 :     log << "eABF/DRR: The " << i << " dimensional zgrid maximum is " << zgmax[i]
+     568          19 :         << '\n';
+     569          19 :     log << "eABF/DRR: The " << i << " dimensional zgrid has " << zgbin[i]
+     570          19 :         << " bins" << '\n';
+     571             :     double l, h;
+     572          19 :     PLMD::Tools::convert(gmin[i], l);
+     573          19 :     PLMD::Tools::convert(gmax[i], h);
+     574          19 :     delim[i].set(l, h, gbin[i]);
+     575             :     double zl,zh;
+     576          19 :     PLMD::Tools::convert(zgmin[i], zl);
+     577          19 :     PLMD::Tools::convert(zgmax[i], zh);
+     578          19 :     zdelim[i].set(zl, zh, zgbin[i]);
+     579             :   }
+     580          12 :   if (kappa.size() != ndims) {
+     581           9 :     kappa.resize(ndims, 0.0);
+     582          25 :     for (size_t i = 0; i < ndims; ++i) {
+     583          16 :       if (kappa[i] <= 0) {
+     584          16 :         log << "eABF/DRR: The spring force constant kappa[" << i
+     585          16 :             << "] is not set." << '\n';
+     586          16 :         kappa[i] = ekbt[i] / (delim[i].getWidth() * delim[i].getWidth());
+     587          16 :         log << "eABF/DRR: set kappa[" << i
+     588          16 :             << "] according to bin width(ekbt/(binWidth^2))." << '\n';
+     589             :       }
+     590          16 :       log << "eABF/DRR: The spring force constant kappa[" << i << "] is "
+     591          16 :           << std::fixed << std::setprecision(10) << kappa[i] << '\n';
+     592             :     }
+     593             :   } else {
+     594           3 :     log << "eABF/DRR: The kappa have been set manually." << '\n';
+     595           6 :     for (size_t i = 0; i < ndims; ++i) {
+     596           3 :       log << "eABF/DRR: The spring force constant kappa[" << i << "] is "
+     597           3 :           << std::fixed << std::setprecision(10) << kappa[i] << '\n';
+     598             :     }
+     599             :   }
+     600             : 
+     601          31 :   for (size_t i = 0; i < ndims; ++i) {
+     602          19 :     mass[i] = kappa[i] * tau[i] * tau[i] / (4 * pi * pi);
+     603          19 :     log << "eABF/DRR: Fictitious mass[" << i << "] is " << mass[i] << '\n';
+     604          19 :     c1[i] = exp(-0.5 * friction[i] * dt);
+     605          19 :     c2[i] = sqrt(ekbt[i] * (1.0 - c1[i] * c1[i]) / mass[i]);
+     606             :   }
+     607             : 
+     608          31 :   for (size_t i = 0; i < ndims; ++i) {
+     609             :     // Position output
+     610          19 :     string comp = getPntrToArgument(i)->getName() + "_fict";
+     611          19 :     addComponentWithDerivatives(comp);
+     612          19 :     if (getPntrToArgument(i)->isPeriodic()) {
+     613             :       string a, b;
+     614             :       double c, d;
+     615          16 :       getPntrToArgument(i)->getDomain(a, b);
+     616          16 :       getPntrToArgument(i)->getDomain(c, d);
+     617          16 :       componentIsPeriodic(comp, a, b);
+     618          16 :       delim[i].setPeriodicity(c, d);
+     619             :       zdelim[i].setPeriodicity(c, d);
+     620             :     } else
+     621           3 :       componentIsNotPeriodic(comp);
+     622          19 :     fictValue[i] = getPntrToComponent(comp);
+     623             :     // Velocity output
+     624          19 :     comp = getPntrToArgument(i)->getName() + "_vfict";
+     625          19 :     addComponent(comp);
+     626          19 :     componentIsNotPeriodic(comp);
+     627          19 :     vfictValue[i] = getPntrToComponent(comp);
+     628             :     // Bias force from eABF/DRR output
+     629          19 :     comp = getPntrToArgument(i)->getName() + "_biasforce";
+     630          19 :     addComponent(comp);
+     631          19 :     componentIsNotPeriodic(comp);
+     632          19 :     biasforceValue[i] = getPntrToComponent(comp);
+     633             :     // Spring force output, useful for perform egABF and other analysis
+     634          19 :     comp = getPntrToArgument(i)->getName() + "_springforce";
+     635          19 :     addComponent(comp);
+     636          19 :     componentIsNotPeriodic(comp);
+     637          19 :     springforceValue[i] = getPntrToComponent(comp);
+     638             :     // Position output, no pbc-aware
+     639          19 :     comp = getPntrToArgument(i)->getName() + "_fictNoPBC";
+     640          19 :     addComponent(comp);
+     641          19 :     componentIsNotPeriodic(comp);
+     642          19 :     fictNoPBCValue[i] = getPntrToComponent(comp);
+     643             :   }
+     644             : 
+     645          12 :   if (outputprefix.length() == 0) {
+     646           0 :     outputprefix = getLabel();
+     647             :   }
+     648             :   // Support multiple replica
+     649          12 :   string replica_suffix = plumed.getSuffix();
+     650          12 :   if (replica_suffix.empty() == false) {
+     651           4 :     outputprefix = outputprefix + replica_suffix;
+     652             :   }
+     653          12 :   outputname = outputprefix + ".drrstate";
+     654          12 :   cptname = outputprefix + ".cpt.drrstate";
+     655             : 
+     656          12 :   if (!isRestart) {
+     657             :     // If you want to use on-the-fly text output for CZAR and naive estimator,
+     658             :     // you should turn it to true first!
+     659          11 :     ABFGrid = ABF(delim, ".abf", fullsamples, maxFactors, textoutput);
+     660             :     // Just initialize it even useCZARestimator is off.
+     661          22 :     CZARestimator = CZAR(zdelim, ".czar", kbt, textoutput);
+     662          11 :     log << "eABF/DRR: The init function of the grid is finished." << '\n';
+     663             :   } else {
+     664             :     // ABF Parametres are not saved in binary files
+     665             :     // So manully set them up
+     666           1 :     ABFGrid.setParameters(fullsamples, maxFactors);
+     667             :   }
+     668          12 :   if (useCZARestimator) {
+     669          12 :     log << "eABF/DRR: Using corrected z-average restraint estimator of gradients" << '\n';
+     670          24 :     log << "  Bibliography " << plumed.cite("Lesage, Lelièvre, Stoltz and Hénin, "
+     671          24 :                                             "J. Phys. Chem. B 3676, 121 (2017)");
+     672          12 :     log << plumed.cite("Darve and Pohorille, J. Chem. Phys. 9169, 115 (2001)") << '\n';
+     673             :   }
+     674          12 :   if (useUIestimator) {
+     675           9 :     log << "eABF/DRR: Using umbrella integration(Zheng and Yang's) estimator "
+     676             :         "of gradients."
+     677           9 :         << '\n';
+     678           9 :     log << "eABF/DRR: The UI estimator code is contributed by Haohao Fu."
+     679           9 :         << '\n';
+     680          18 :     log << "  Bibliography " << plumed.cite(
+     681          18 :           "Fu, Shao, Chipot and Cai, J. Chem. Theory Comput. 3506, 12 (2016)");
+     682          18 :     log << plumed.cite("Zheng and Yang, J. Chem. Theory Comput. 810, 8 (2012)");
+     683           9 :     log << plumed.cite("Darve and Pohorille, J. Chem. Phys. 9169, 115 (2001)") << '\n';
+     684           9 :     vector<double> lowerboundary(zdelim.size(), 0);
+     685           9 :     vector<double> upperboundary(zdelim.size(), 0);
+     686           9 :     vector<double> width(zdelim.size(), 0);
+     687          24 :     for (size_t i = 0; i < zdelim.size(); ++i) {
+     688          15 :       lowerboundary[i] = zdelim[i].getMin();
+     689          15 :       upperboundary[i] = zdelim[i].getMax();
+     690          15 :       width[i] = zdelim[i].getWidth();
+     691             :     }
+     692             :     vector<string> input_filename;
+     693             :     bool uirestart = false;
+     694           9 :     if (isRestart && (uirprefix.length() != 0)) {
+     695           1 :       input_filename.push_back(uirprefix);
+     696             :       uirestart = true;
+     697             :     }
+     698           9 :     if (isRestart && (uirprefix.length() == 0)) {
+     699           0 :       input_filename.push_back(outputprefix);
+     700             :     }
+     701           9 :     eabf_UI = UIestimator::UIestimator(
+     702           9 :                 lowerboundary, upperboundary, width, kappa, outputprefix, int(outputfreq),
+     703          18 :                 uirestart, input_filename, kbt / plumed.getAtoms().getKBoltzmann());
+     704           9 :   }
+     705          24 : }
+     706             : 
+     707         123 : void DynamicReferenceRestraining::calculate() {
+     708         123 :   long long int step_now = getStep();
+     709         123 :   if (firsttime) {
+     710          28 :     for (size_t i = 0; i < ndims; ++i) {
+     711          17 :       fict[i] = getArgument(i);
+     712          17 :       if(reflectingWall[i] && (fict[i]>=delim[i].getMax() || fict[i]<=delim[i].getMin())) {
+     713           0 :         error("eABF/DRR: initial position not in the range of [gmin, gmax]!");
+     714             :       }
+     715             :     }
+     716          11 :     firsttime = false;
+     717             :   }
+     718         123 :   if (step_now != 0) {
+     719         111 :     if ((step_now % int(outputfreq)) == 0) {
+     720          15 :       save(outputname, step_now);
+     721          15 :       if (textoutput) {
+     722          10 :         ABFGrid.writeAll(outputprefix);
+     723          10 :         if (useCZARestimator) {
+     724          10 :           CZARestimator.writeAll(outputprefix);
+     725          10 :           CZARestimator.writeZCount(outputprefix);
+     726             :         }
+     727             :       }
+     728             :     }
+     729         111 :     if (historyfreq > 0 && (step_now % int(historyfreq)) == 0) {
+     730           4 :       if (textoutput) {
+     731             :         const string filename =
+     732           4 :           outputprefix + ".another.drrstate";
+     733           4 :         save(filename, step_now);
+     734             :         const string textfilename =
+     735           4 :           mergeHistoryFiles ? (outputprefix + ".hist") : (outputprefix + "." + std::to_string(step_now));
+     736           4 :         ABFGrid.writeAll(textfilename, mergeHistoryFiles);
+     737           4 :         if (useCZARestimator) {
+     738           4 :           CZARestimator.writeAll(textfilename, mergeHistoryFiles);
+     739           4 :           CZARestimator.writeZCount(textfilename, mergeHistoryFiles);
+     740             :         }
+     741             :       } else {
+     742             :         const string filename =
+     743           0 :           outputprefix + "." + std::to_string(step_now) + ".drrstate";
+     744           0 :         save(filename, step_now);
+     745             :       }
+     746             :     }
+     747         111 :     if (getCPT()) {
+     748           0 :       log << "eABF/DRR: The MD engine is writing checkpoint so we also write a "
+     749             :           "DRR state file at step: "
+     750           0 :           << step_now << ".\n";
+     751           0 :       save(cptname, step_now);
+     752             :     }
+     753             :   }
+     754         123 :   if (withExternalForce == false) {
+     755             :     double ene = 0.0;
+     756         294 :     for (size_t i = 0; i < ndims; ++i) {
+     757         183 :       real[i] = getArgument(i);
+     758         183 :       springlength[i] = difference(i, fict[i], real[i]);
+     759         183 :       fictNoPBC[i] = real[i] - springlength[i];
+     760         183 :       double f = -kappa[i] * springlength[i];
+     761         183 :       ffict_measured[i] = -f;
+     762         183 :       ene += 0.5 * kappa[i] * springlength[i] * springlength[i];
+     763             :       setOutputForce(i, f);
+     764         183 :       ffict[i] = -f;
+     765         183 :       fict[i] = fictValue[i]->bringBackInPbc(fict[i]);
+     766         183 :       fictValue[i]->set(fict[i]);
+     767         183 :       vfictValue[i]->set(vfict_laststep[i]);
+     768         183 :       springforceValue[i]->set(ffict_measured[i]);
+     769         183 :       fictNoPBCValue[i]->set(fictNoPBC[i]);
+     770             :     }
+     771             :     setBias(ene);
+     772         111 :     ABFGrid.store_getbias(fict, ffict_measured, fbias);
+     773             :   } else {
+     774          36 :     for (size_t i = 0; i < ndims; ++i) {
+     775          24 :       real[i] = getArgument(i);
+     776          24 :       ffict_measured[i] = externalForceValue[i]->get();
+     777          24 :       if (withExternalFict) {
+     778          24 :         fictNoPBC[i] = externalFictValue[i]->get();
+     779             :       }
+     780          24 :       springforceValue[i]->set(ffict_measured[i]);
+     781          24 :       fictNoPBCValue[i]->set(fictNoPBC[i]);
+     782             :     }
+     783          12 :     ABFGrid.store_getbias(real, ffict_measured, fbias);
+     784          12 :     if (!nobias) {
+     785           0 :       for (size_t i = 0; i < ndims; ++i) {
+     786           0 :         setOutputForce(i, fbias[i]);
+     787             :       }
+     788             :     }
+     789             :   }
+     790         123 :   if (useCZARestimator) {
+     791         123 :     CZARestimator.store(real, ffict_measured);
+     792             :   }
+     793         123 :   if (useUIestimator) {
+     794          87 :     eabf_UI.update_output_filename(outputprefix);
+     795         261 :     eabf_UI.update(int(step_now), real, fictNoPBC);
+     796             :   }
+     797         123 : }
+     798             : 
+     799         123 : void DynamicReferenceRestraining::update() {
+     800         123 :   if (withExternalForce == false) {
+     801         294 :     for (size_t i = 0; i < ndims; ++i) {
+     802             :       // consider additional forces on the fictitious particle
+     803             :       // (e.g. MetaD stuff)
+     804         183 :       ffict[i] += fictValue[i]->getForce();
+     805         183 :       if (!nobias) {
+     806         183 :         ffict[i] += fbias[i];
+     807             :       }
+     808         183 :       biasforceValue[i]->set(fbias[i]);
+     809             :       // update velocity (half step)
+     810         183 :       vfict[i] += ffict[i] * 0.5 * dt / mass[i];
+     811             :       // thermostat (half step)
+     812         183 :       vfict[i] = c1[i] * vfict[i] + c2[i] * rand.Gaussian();
+     813             :       // save full step velocity to be dumped at next step
+     814         183 :       vfict_laststep[i] = vfict[i];
+     815             :       // thermostat (half step)
+     816         183 :       vfict[i] = c1[i] * vfict[i] + c2[i] * rand.Gaussian();
+     817             :       // update velocity (half step)
+     818         183 :       vfict[i] += ffict[i] * 0.5 * dt / mass[i];
+     819             :       // update position (full step)
+     820         183 :       fict[i] += vfict[i] * dt;
+     821             :       // reflecting boundary
+     822         183 :       if (reflectingWall[i]) {
+     823          24 :         if (fict[i]<delim[i].getMin()) {
+     824           1 :           fict[i]=delim[i].getMin()+(delim[i].getMin()-fict[i]);
+     825           1 :           vfict[i]*=-1.0;
+     826          23 :         } else if (fict[i]>delim[i].getMax()) {
+     827           0 :           fict[i]=delim[i].getMax()-(fict[i]-delim[i].getMax());
+     828           0 :           vfict[i]*=-1.0;
+     829             :         }
+     830             :       }
+     831             :     }
+     832             :   }
+     833         123 : }
+     834             : 
+     835          19 : void DynamicReferenceRestraining::save(const string &filename,
+     836             :                                        long long int step) {
+     837          19 :   std::ofstream out;
+     838          19 :   out.open(filename.c_str(), std::ios::binary);
+     839          19 :   boost::archive::binary_oarchive oa(out);
+     840          19 :   oa << step << fict << vfict << vfict_laststep << ffict << ABFGrid
+     841          19 :      << CZARestimator;
+     842          19 :   out.close();
+     843          19 : }
+     844             : 
+     845           1 : void DynamicReferenceRestraining::load(const string &rfile_prefix) {
+     846           1 :   string replica_suffix = plumed.getSuffix();
+     847             :   string filename;
+     848           1 :   if (replica_suffix.empty() == true) {
+     849           2 :     filename = rfile_prefix + ".drrstate";
+     850             :   } else {
+     851           0 :     filename = rfile_prefix + "." + replica_suffix + ".drrstate";
+     852             :   }
+     853           1 :   std::ifstream in;
+     854             :   long long int step;
+     855           1 :   in.open(filename.c_str(), std::ios::binary);
+     856           1 :   log << "eABF/DRR: Read restart file: " << filename << '\n';
+     857           1 :   boost::archive::binary_iarchive ia(in);
+     858           1 :   ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> ABFGrid >>
+     859           1 :      CZARestimator;
+     860           1 :   in.close();
+     861           1 :   log << "eABF/DRR: Restart at step: " << step << '\n';
+     862           1 :   backupFile(filename);
+     863           2 : }
+     864             : 
+     865           1 : void DynamicReferenceRestraining::backupFile(const string &filename) {
+     866             :   bool isSuccess = false;
+     867             :   long int i = 0;
+     868           2 :   while (!isSuccess) {
+     869             :     // If libstdc++ support C++17 we can simplify following code.
+     870           2 :     const string bckname = "bck." + filename + "." + std::to_string(i);
+     871           1 :     if (is_file_exist(bckname.c_str())) {
+     872           0 :       ++i;
+     873             :     } else {
+     874           1 :       log << "eABF/DRR: Backup original restart file to " << bckname << '\n';
+     875           1 :       std::ifstream src(filename.c_str(), std::ios::binary);
+     876           1 :       std::ofstream dst(bckname.c_str(), std::ios::binary);
+     877           1 :       dst << src.rdbuf();
+     878           1 :       src.close();
+     879           1 :       dst.close();
+     880             :       isSuccess = true;
+     881           1 :     }
+     882             :   }
+     883           1 : }
+     884             : 
+     885             : // Copy from
+     886             : // stackoverflow(https://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c)
+     887           1 : bool DynamicReferenceRestraining::is_file_exist(const char *fileName) {
+     888           1 :   std::ifstream infile(fileName);
+     889           1 :   return infile.good();
+     890           1 : }
+     891             : }
+     892             : }
+     893             : 
+     894             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..8bc2ecf1a9 --- /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-06-10 08:19:14Functions: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
_ZN4PLMD3drr11UIestimator11UIestimator6updateEiSt6vectorIdSaIdEES5_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.15
+
+ + + diff --git a/coverage/drr/colvar_UIestimator.h.func.html b/coverage/drr/colvar_UIestimator.h.func.html new file mode 100644 index 0000000000..15441545df --- /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-06-10 08:19:14Functions: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
_ZN4PLMD3drr11UIestimator11UIestimator6updateEiSt6vectorIdSaIdEES5_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.15
+
+ + + diff --git a/coverage/drr/colvar_UIestimator.h.gcov.html b/coverage/drr/colvar_UIestimator.h.gcov.html new file mode 100644 index 0000000000..2e0121accc --- /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-06-10 08:19:14Functions: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, 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         126 :         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(9) << loop_flag[i] + 0.5 * width[i] << " ";
+     723         343 :         ofile_hist << std::fixed << std::setprecision(9) << loop_flag[i] + 0.5 * width[i] << " ";
+     724         343 :         ofile_count << std::fixed << std::setprecision(9) << 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(9) << grad.get_value(loop_flag)[i] << " ";
+     732         614 :           ofile_hist << std::fixed << std::setprecision(9) << 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          40 :             final_grad = grad.get_value(loop_flag)[i];
+     746             :           else
+     747          48 :             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(9) << final_grad << " ";
+     749          36 :           ofile_hist << std::fixed << std::setprecision(9) << 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          16 :           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.15
+
+ + + 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 0000000000..a220e1dc85 --- /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:656994.2 %
Date:2024-06-10 08:19:14Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr7drrtool14calcDivergenceERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD3drr7drrtool10extractdrrERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE2
_ZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_2
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_SE_E0_clESE_SE_2
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlS8_E_clES8_2
_ZNK4PLMD3drr7drrtool11descriptionB5cxx11Ev4
_ZN4PLMD3drr7drrtool4mainEP8_IO_FILES3_RNS_12CommunicatorE5
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMe6createERKNS_13CLToolOptionsE9
_ZN4PLMD3drr7drrtoolC2ERKNS_13CLToolOptionsE9
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeC2Ev3473
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeD2Ev3473
_ZN4PLMD3drr7drrtool16registerKeywordsERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/drr/drrtool.cpp.func.html b/coverage/drr/drrtool.cpp.func.html new file mode 100644 index 0000000000..c5b07e794e --- /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:656994.2 %
Date:2024-06-10 08:19:14Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMe6createERKNS_13CLToolOptionsE9
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeC2Ev3473
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeD2Ev3473
_ZN4PLMD3drr7drrtool10extractdrrERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE2
_ZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_2
_ZN4PLMD3drr7drrtool14calcDivergenceERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD3drr7drrtool16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD3drr7drrtool4mainEP8_IO_FILES3_RNS_12CommunicatorE5
_ZN4PLMD3drr7drrtoolC2ERKNS_13CLToolOptionsE9
_ZNK4PLMD3drr7drrtool11descriptionB5cxx11Ev4
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_SE_E0_clESE_SE_2
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlS8_E_clES8_2
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/drr/drrtool.cpp.gcov.html b/coverage/drr/drrtool.cpp.gcov.html new file mode 100644 index 0000000000..dfd13de942 --- /dev/null +++ b/coverage/drr/drrtool.cpp.gcov.html @@ -0,0 +1,342 @@ + + + + + + + + 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:656994.2 %
Date:2024-06-10 08:19:14Functions: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 "cltools/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);
+      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       10428 : PLUMED_REGISTER_CLTOOL(drrtool, "drr_tool")
+      90             : 
+      91        3473 : void drrtool::registerKeywords(Keywords &keys) {
+      92        3473 :   CLTool::registerKeywords(keys);
+      93        6946 :   keys.add("optional", "--extract", "Extract drrstate file(s)");
+      94        6946 :   keys.add("optional", "--merge", "Merge eABF windows");
+      95        6946 :   keys.add("optional", "--merge_output", "The output filename of the merged result");
+      96        6946 :   keys.add("optional", "--divergence", "Calculate divergence of gradient field (experimental)");
+      97        6946 :   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");
+      98        6946 :   keys.addFlag("-v", false, "Verbose output");
+      99        3473 : }
+     100             : 
+     101           9 : drrtool::drrtool(const CLToolOptions &co) : CLTool(co) {
+     102           9 :   inputdata = commandline;
+     103           9 :   verbosity = false;
+     104           9 : }
+     105             : 
+     106           5 : int drrtool::main(FILE *in, FILE *out, Communicator &pc) {
+     107          10 :   parseFlag("-v", verbosity);
+     108             :   vector<string> stateFilesToExtract;
+     109             :   string unitname;
+     110           5 :   parse("--units",unitname);
+     111           5 :   units.setEnergy( unitname );
+     112           5 :   bool doextract = parseVector("--extract", stateFilesToExtract);
+     113           5 :   if (doextract) {
+     114           2 :     extractdrr(stateFilesToExtract);
+     115             :   }
+     116             :   vector<string> stateFilesToMerge;
+     117           5 :   bool domerge = parseVector("--merge", stateFilesToMerge);
+     118           5 :   if (domerge) {
+     119             :     string merge_outputname;
+     120           2 :     parse("--merge_output", merge_outputname);
+     121           4 :     mergewindows(stateFilesToMerge, merge_outputname);
+     122             :   }
+     123             :   vector<string> stateFilesToDivergence;
+     124           5 :   bool dodivergence = parseVector("--divergence", stateFilesToDivergence);
+     125           5 :   if (dodivergence) {
+     126           1 :     calcDivergence(stateFilesToDivergence);
+     127             :   }
+     128           5 :   return 0;
+     129          10 : }
+     130             : 
+     131           2 : void drrtool::extractdrr(const vector<string> &filename) {
+     132           2 :   #pragma omp parallel for
+     133             :   for (size_t j = 0; j < filename.size(); ++j) {
+     134             :     std::ifstream in;
+     135             :     in.open(filename[j]);
+     136             :     boost::archive::binary_iarchive ia(in);
+     137             :     long long int step;
+     138             :     vector<double> fict;
+     139             :     vector<double> vfict;
+     140             :     vector<double> vfict_laststep;
+     141             :     vector<double> ffict;
+     142             :     ABF abfgrid;
+     143             :     CZAR czarestimator;
+     144             :     ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> abfgrid >>
+     145             :        czarestimator;
+     146             :     in.close();
+     147             :     abfgrid.setOutputUnit(units.getEnergy());
+     148             :     czarestimator.setOutputUnit(units.getEnergy());
+     149             :     if (verbosity) {
+     150             :       std::cout << "Output units factor: " << units.getEnergy() << '\n';
+     151             :       std::cout << "Dumping information of extended variables..." << '\n';
+     152             :       std::cout << "Step: " << step << '\n';
+     153             :       for (size_t i = 0; i < fict.size(); ++i) {
+     154             :         std::cout << "Dimension[" << i + 1 << "]:\n"
+     155             :                   << "  Coordinate: " << fict[i] << '\n'
+     156             :                   << "  Velocity: " << vfict[i] << '\n'
+     157             :                   << "  Velocity(laststep): " << vfict_laststep[i] << '\n'
+     158             :                   << "  Force: " << ffict[i] << '\n';
+     159             :       }
+     160             :       std::cout << "Dumping counts and gradients from grids..." << '\n';
+     161             :     }
+     162             :     string outputname(filename[j]);
+     163             :     outputname = outputname.substr(0, outputname.length() - suffix.length());
+     164             :     if (verbosity)
+     165             :       std::cout << "Writing ABF(naive) estimator files..." << '\n';
+     166             :     abfgrid.writeAll(outputname);
+     167             :     if (verbosity)
+     168             :       std::cout << "Writing CZAR estimator files..." << '\n';
+     169             :     czarestimator.writeAll(outputname);
+     170             :     czarestimator.writeZCount(outputname);
+     171             :   }
+     172           2 : }
+     173             : 
+     174           2 : void drrtool::mergewindows(const vector<string> &filename, string outputname) {
+     175           2 :   if (filename.size() < 2) {
+     176           0 :     std::cerr << "ERROR! You need at least two .drrstate file to merge windows!" << std::endl;
+     177           0 :     std::abort();
+     178             :   }
+     179             :   // Read grid into abfs and czars;
+     180             :   vector<ABF> abfs;
+     181             :   vector<CZAR> czars;
+     182           6 :   for (auto it_fn = filename.begin(); it_fn != filename.end(); ++it_fn) {
+     183           4 :     std::ifstream in;
+     184           4 :     in.open((*it_fn));
+     185           4 :     boost::archive::binary_iarchive ia(in);
+     186             :     long long int step;
+     187             :     vector<double> fict;
+     188             :     vector<double> vfict;
+     189             :     vector<double> vfict_laststep;
+     190             :     vector<double> ffict;
+     191             :     ABF abfgrid;
+     192             :     CZAR czarestimator;
+     193             :     ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> abfgrid >>
+     194             :        czarestimator;
+     195           4 :     abfgrid.setOutputUnit(units.getEnergy());
+     196             :     czarestimator.setOutputUnit(units.getEnergy());
+     197           4 :     abfs.push_back(abfgrid);
+     198           4 :     czars.push_back(czarestimator);
+     199           4 :     in.close();
+     200           8 :   }
+     201           2 :   CZAR cmerged = CZAR::mergewindow(czars[0], czars[1]);
+     202           2 :   ABF amerged = ABF::mergewindow(abfs[0], abfs[1]);
+     203           2 :   for (size_t i = 2; i < czars.size(); ++i) {
+     204           0 :     cmerged = CZAR::mergewindow(cmerged, czars[i]);
+     205           0 :     amerged = ABF::mergewindow(amerged, abfs[i]);
+     206             :   }
+     207           2 :   if (outputname.empty()) {
+     208             :     // Generate new file name for merged grad and count
+     209           1 :     vector<string> tmp_name = filename;
+     210           1 :     std::transform(std::begin(tmp_name), std::end(tmp_name), std::begin(tmp_name),
+     211           2 :     [&](string s) {return s.substr(0, s.find(suffix));});
+     212           2 :     outputname = std::accumulate(std::begin(tmp_name), std::end(tmp_name), string(""),
+     213           5 :     [](const string & a, const string & b) {return a + b + "+";});
+     214           1 :     outputname = outputname.substr(0, outputname.size() - 1);
+     215             :     std::cerr << "You have not specified an output filename for the merged"
+     216           1 :               << " result, so the default name \"" + outputname
+     217           2 :               << "\" is used here, which may yield unexpected behavior.\n";
+     218           1 :   }
+     219           2 :   cmerged.writeAll(outputname);
+     220           2 :   cmerged.writeZCount(outputname);
+     221           2 :   amerged.writeAll(outputname);
+     222           4 : }
+     223             : 
+     224           1 : void drrtool::calcDivergence(const vector<string> &filename) {
+     225           1 :   #pragma omp parallel for
+     226             :   for (size_t j = 0; j < filename.size(); ++j) {
+     227             :     std::ifstream in;
+     228             :     in.open(filename[j]);
+     229             :     boost::archive::binary_iarchive ia(in);
+     230             :     long long int step;
+     231             :     vector<double> fict;
+     232             :     vector<double> vfict;
+     233             :     vector<double> vfict_laststep;
+     234             :     vector<double> ffict;
+     235             :     ABF abfgrid;
+     236             :     CZAR czarestimator;
+     237             :     ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> abfgrid >>
+     238             :        czarestimator;
+     239             :     in.close();
+     240             :     abfgrid.setOutputUnit(units.getEnergy());
+     241             :     czarestimator.setOutputUnit(units.getEnergy());
+     242             :     if (verbosity) {
+     243             :       std::cout << "Output units factor: " << units.getEnergy() << '\n';
+     244             :       std::cout << "Dumping information of extended variables..." << '\n';
+     245             :       std::cout << "Step: " << step << '\n';
+     246             :       for (size_t i = 0; i < fict.size(); ++i) {
+     247             :         std::cout << "Dimension[" << i + 1 << "]:\n"
+     248             :                   << "  Coordinate: " << fict[i] << '\n'
+     249             :                   << "  Velocity: " << vfict[i] << '\n'
+     250             :                   << "  Velocity(laststep): " << vfict_laststep[i] << '\n'
+     251             :                   << "  Force: " << ffict[i] << '\n';
+     252             :       }
+     253             :       std::cout << "Dumping counts and gradients from grids..." << '\n';
+     254             :     }
+     255             :     string outputname(filename[j]);
+     256             :     outputname = outputname.substr(0, outputname.length() - suffix.length());
+     257             :     abfgrid.writeDivergence(outputname);
+     258             :     czarestimator.writeDivergence(outputname);
+     259             :   }
+     260           1 : }
+     261             : 
+     262             : } // End of namespace
+     263             : }
+     264             : 
+     265             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/drr/index-sort-f.html b/coverage/drr/index-sort-f.html new file mode 100644 index 0000000000..938a2e3407 --- /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:1184125694.3 %
Date:2024-06-10 08:19:14Functions:929794.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
90.8%90.8%
+
90.8 %403 / 44491.7 %11 / 12
DRR.cpp +
93.0%93.0%
+
93.0 %318 / 34296.0 %24 / 25
drrtool.cpp +
94.2%94.2%
+
94.2 %65 / 69100.0 %12 / 12
colvar_UIestimator.h +
99.0%99.0%
+
99.0 %299 / 302100.0 %34 / 34
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/drr/index-sort-l.html b/coverage/drr/index-sort-l.html new file mode 100644 index 0000000000..1e4763a12e --- /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:1184125694.3 %
Date:2024-06-10 08:19:14Functions:929794.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DynamicReferenceRestraining.cpp +
90.8%90.8%
+
90.8 %403 / 44491.7 %11 / 12
DRR.cpp +
93.0%93.0%
+
93.0 %318 / 34296.0 %24 / 25
drrtool.cpp +
94.2%94.2%
+
94.2 %65 / 69100.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.15
+
+ + + diff --git a/coverage/drr/index.html b/coverage/drr/index.html new file mode 100644 index 0000000000..7b8ef3c1d8 --- /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:1184125694.3 %
Date:2024-06-10 08:19:14Functions:929794.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DRR.cpp +
93.0%93.0%
+
93.0 %318 / 34296.0 %24 / 25
DRR.h +
100.0%
+
100.0 %99 / 9978.6 %11 / 14
DynamicReferenceRestraining.cpp +
90.8%90.8%
+
90.8 %403 / 44491.7 %11 / 12
colvar_UIestimator.h +
99.0%99.0%
+
99.0 %299 / 302100.0 %34 / 34
drrtool.cpp +
94.2%94.2%
+
94.2 %65 / 69100.0 %12 / 12
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9b89ac4f90 --- /dev/null +++ b/coverage/eds/EDS.cpp.func-sort-c.html @@ -0,0 +1,165 @@ + + + + + + + + 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:45248892.6 %
Date:2024-06-10 08:19:14Functions:202387.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
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe2806createERKNS_13ActionOptionsE8
_ZN4PLMD3eds3EDS11update_biasEv8
_ZN4PLMD3eds3EDS15setupOutRestartEv8
_ZN4PLMD3eds3EDS16reset_statisticsEv8
_ZN4PLMD3eds3EDSC1ERKNS_13ActionOptionsE8
_ZN4PLMD3eds3EDSD0Ev8
_ZN4PLMD3eds3EDSD1Ev8
_ZN4PLMD3eds3EDS16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD3eds3EDS17update_statisticsEv12
_ZN4PLMD3eds3EDS15writeOutRestartEv27
_ZN4PLMD3eds3EDS10apply_biasEv40
_ZN4PLMD3eds3EDS6updateEv40
_ZN4PLMD3eds3EDS9calculateEv40
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe280C2Ev3473
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe280D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/eds/EDS.cpp.func.html b/coverage/eds/EDS.cpp.func.html new file mode 100644 index 0000000000..c0fb401ff3 --- /dev/null +++ b/coverage/eds/EDS.cpp.func.html @@ -0,0 +1,165 @@ + + + + + + + + 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:45248892.6 %
Date:2024-06-10 08:19:14Functions:202387.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe2806createERKNS_13ActionOptionsE8
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe280C2Ev3473
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe280D2Ev3473
_ZN4PLMD3eds3EDS10apply_biasEv40
_ZN4PLMD3eds3EDS11update_biasEv8
_ZN4PLMD3eds3EDS13readInRestartEb2
_ZN4PLMD3eds3EDS15setupOutRestartEv8
_ZN4PLMD3eds3EDS15writeOutRestartEv27
_ZN4PLMD3eds3EDS16registerKeywordsERNS_8KeywordsE9
_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.15
+
+ + + diff --git a/coverage/eds/EDS.cpp.gcov.html b/coverage/eds/EDS.cpp.gcov.html new file mode 100644 index 0000000000..0a0b1e7fac --- /dev/null +++ b/coverage/eds/EDS.cpp.gcov.html @@ -0,0 +1,1257 @@ + + + + + + + + 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:45248892.6 %
Date:2024-06-10 08:19:14Functions:202387.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/Atoms.h"
+      22             : #include "core/PlumedMain.h"
+      23             : #include "tools/File.h"
+      24             : #include "tools/Matrix.h"
+      25             : #include "tools/Random.h"
+      26             : 
+      27             : #include <iostream>
+      28             : 
+      29             : using namespace PLMD;
+      30             : using namespace bias;
+      31             : 
+      32             : // namespace is lowercase to match
+      33             : // module names being all lowercase
+      34             : 
+      35             : namespace PLMD
+      36             : {
+      37             : namespace eds
+      38             : {
+      39             : 
+      40             : //+PLUMEDOC EDSMOD_BIAS EDS
+      41             : /*
+      42             : Add a linear bias on a set of observables.
+      43             : 
+      44             : This force is the same as the linear part of the bias in \ref
+      45             : RESTRAINT, but this bias has the ability to compute the prefactors
+      46             : adaptively using the scheme of White and Voth \cite white2014efficient
+      47             : in order to match target observable values for a set of CVs.
+      48             : Further updates to the algorithm are described in \cite hocky2017cgds
+      49             : and you can read a review on the method and its applications here: \cite Amirkulova2019Recent.
+      50             : 
+      51             : You can
+      52             : see a tutorial on EDS specifically for biasing coordination number at
+      53             : <a
+      54             : href="http://thewhitelab.org/blog/tutorial/2017/05/10/lammps-coordination-number-tutorial/">
+      55             : Andrew White's webpage</a>.
+      56             : 
+      57             : The addition to the potential is of the form
+      58             : \f[
+      59             :   \sum_i \frac{\alpha_i}{s_i} x_i
+      60             : \f]
+      61             : 
+      62             : where for CV \f$x_i\f$, a coupling constant \f${\alpha}_i\f$ is determined
+      63             : adaptively or set by the user to match a target value for
+      64             : \f$x_i\f$. \f$s_i\f$ is a scale parameter, which by default is set to
+      65             : the target value. It may also be set separately.
+      66             : 
+      67             : \warning
+      68             : It is not possible to set the target value of the observable
+      69             : to zero with the default value of \f$s_i\f$ as this will cause a
+      70             : divide-by-zero error. Instead, set \f$s_i=1\f$ or modify the CV so the
+      71             : desired target value is no longer zero.
+      72             : 
+      73             : Notice that a similar method is available as \ref MAXENT, although with different features and using a different optimization algorithm.
+      74             : 
+      75             : \par Virial
+      76             : 
+      77             : The bias forces modify the virial and this can change your simulation density if the bias is used in an NPT simulation.
+      78             : One way to avoid changing the virial contribution from the bias is to add the keyword VIRIAL=1.0, which changes how the bias
+      79             : is computed to minimize its contribution to the virial. This can also lead to smaller magnitude biases that are more robust if
+      80             : transferred to other systems.  VIRIAL=1.0 can be a reasonable starting point and increasing the value changes the balance between matching
+      81             : the set-points and minimizing the virial. See \cite Amirkulova2019Recent for details on the equations. Since the coupling constants
+      82             : are unique with a single CV, VIRIAL is not applicable with a single CV. When used with multiple CVs, the CVs should be correlated
+      83             : which is almost always the case.
+      84             : 
+      85             : \par Weighting
+      86             : 
+      87             : EDS computes means and variances as part of its algorithm. If you are
+      88             : also using a biasing method like metadynamics, you may wish to remove
+      89             : the effect of this bias in your EDS computations so that EDS works on
+      90             : the canonical values (reweighted to be unbiased).  For example, you may be using
+      91             : metadynamics to bias a dihedral angle to enhance sampling and be using
+      92             : EDS to set the average distance between two particular atoms. Specifically:
+      93             : 
+      94             : \plumedfile
+      95             : # set-up metadynamics
+      96             : t: TORSION ATOMS=1,2,3,4
+      97             : md: METAD ARG=d SIGMA=0.2 HEIGHT=0.3 PACE=500 TEMP=300
+      98             : # compute bias weights
+      99             : bias: REWEIGHT_METAD TEMP=300
+     100             : # now do EDS on distance while removing effect of metadynamics
+     101             : d: DISTANCE ATOMS=4,7
+     102             : eds: EDS ARG=d CENTER=3.0 PERIOD=100 TEMP=300 LOGWEIGHTS=bias
+     103             : \endplumedfile
+     104             : 
+     105             : This is an approximation though because EDS uses a finite samples while running to get means/variances.
+     106             : At the end of a run,
+     107             : you should ensure this approach worked and indeed your reweighted CV matches the target value.
+     108             : 
+     109             : \par Examples
+     110             : 
+     111             : The following input for a harmonic oscillator of two beads will
+     112             : adaptively find a linear bias to change the mean and variance to the
+     113             : target values. The PRINT line shows how to access the value of the
+     114             : coupling constants.
+     115             : 
+     116             : \plumedfile
+     117             : dist: DISTANCE ATOMS=1,2
+     118             : # this is the squared of the distance
+     119             : dist2: COMBINE ARG=dist POWERS=2 PERIODIC=NO
+     120             : 
+     121             : # bias mean and variance
+     122             : eds: EDS ARG=dist,dist2 CENTER=2.0,1.0 PERIOD=100 TEMP=1.0
+     123             : PRINT ARG=dist,dist2,eds.dist_coupling,eds.dist2_coupling,eds.bias,eds.force2 FILE=colvars.dat STRIDE=100
+     124             : \endplumedfile
+     125             : 
+     126             : <hr>
+     127             : 
+     128             : Rather than trying to find the coupling constants adaptively, one can ramp up to a constant value.
+     129             : \plumedfile
+     130             : dist: DISTANCE ATOMS=1,2
+     131             : dist2: COMBINE ARG=dist POWERS=2 PERIODIC=NO
+     132             : 
+     133             : # ramp couplings from 0,0 to -1,1 over 50000 steps
+     134             : eds: EDS ARG=dist,dist2 CENTER=2.0,1.0 FIXED=-1,1 RAMP PERIOD=50000 TEMP=1.0
+     135             : 
+     136             : # same as above, except starting at -0.5,0.5 rather than default of 0,0
+     137             : eds2: EDS ARG=dist,dist2 CENTER=2.0,1.0 FIXED=-1,1 INIT=-0.5,0.5 RAMP PERIOD=50000 TEMP=1.0
+     138             : \endplumedfile
+     139             : 
+     140             : <hr>
+     141             : A restart file can be added to dump information needed to restart/continue simulation using these parameters every PERIOD.
+     142             : \plumedfile
+     143             : dist: DISTANCE ATOMS=1,2
+     144             : dist2: COMBINE ARG=dist POWERS=2 PERIODIC=NO
+     145             : 
+     146             : # add the option to write to a restart file
+     147             : eds: EDS ARG=dist,dist2 CENTER=2.0,1.0 PERIOD=100 TEMP=1.0 OUT_RESTART=checkpoint.eds
+     148             : \endplumedfile
+     149             : 
+     150             : The first few lines of the restart file that is output if we run a calculation with one CV will look something like this:
+     151             : 
+     152             : \auxfile{restart.eds}
+     153             : #! FIELDS time d1_center d1_set d1_target d1_coupling d1_maxrange d1_maxgrad d1_accum d1_mean d1_std
+     154             : #! SET adaptive  1
+     155             : #! SET update_period  1
+     156             : #! SET seed  0
+     157             : #! SET kbt    2.4943
+     158             :    0.0000   1.0000   0.0000   0.0000   0.0000   7.4830   0.1497   0.0000   0.0000   0.0000
+     159             :    1.0000   1.0000   0.0000   0.0000   0.0000   7.4830   0.1497   0.0000   0.0000   0.0000
+     160             :    2.0000   1.0000  -7.4830   0.0000   0.0000   7.4830   0.1497   0.0224   0.0000   0.0000
+     161             :    3.0000   1.0000  -7.4830   0.0000  -7.4830   7.4830   0.1497   0.0224   0.0000   0.0000
+     162             :    4.0000   1.0000  -7.4830   0.0000  -7.4830   7.4830   0.1497   0.0224   0.0000   0.0000
+     163             : \endauxfile
+     164             : 
+     165             : <hr>
+     166             : 
+     167             : Read in a previous restart file. Adding RESTART flag makes output append
+     168             : \plumedfile
+     169             : d1: DISTANCE ATOMS=1,2
+     170             : 
+     171             : eds: EDS ARG=d1 CENTER=2.0 PERIOD=100 TEMP=1.0 IN_RESTART=restart.eds RESTART=YES
+     172             : \endplumedfile
+     173             : 
+     174             : <hr>
+     175             : 
+     176             : Read in a previous restart file and freeze the bias at the final level from the previous simulation
+     177             : \plumedfile
+     178             : d1: DISTANCE ATOMS=1,2
+     179             : 
+     180             : eds: EDS ARG=d1 CENTER=2.0 TEMP=1.0 IN_RESTART=restart.eds FREEZE
+     181             : \endplumedfile
+     182             : 
+     183             : <hr>
+     184             : 
+     185             : Read in a previous restart file and freeze the bias at the mean from the previous simulation
+     186             : \plumedfile
+     187             : d1: DISTANCE ATOMS=1,2
+     188             : 
+     189             : eds: EDS ARG=d1 CENTER=2.0 TEMP=1.0 IN_RESTART=restart.eds FREEZE MEAN
+     190             : \endplumedfile
+     191             : 
+     192             : 
+     193             : */
+     194             : //+ENDPLUMEDOC
+     195             : 
+     196             : class EDS : public Bias
+     197             : {
+     198             : 
+     199             : private:
+     200             :   /*We will get this and store it once, since on-the-fly changing number of CVs will be fatal*/
+     201             :   const unsigned int ncvs_;
+     202             :   std::vector<double> center_;
+     203             :   std::vector<Value *> center_values_;
+     204             :   ReweightBase *logweights_; // weights to use if reweighting averages
+     205             :   std::vector<double> scale_;
+     206             :   std::vector<double> current_coupling_;   // actually current coupling
+     207             :   std::vector<double> set_coupling_;       // what our coupling is ramping up to. Equal to current_coupling when gathering stats
+     208             :   std::vector<double> target_coupling_;    // used when loaded to reach a value
+     209             :   std::vector<double> max_coupling_range_; // used for adaptive range
+     210             :   std::vector<double> max_coupling_grad_;  // maximum allowed gradient
+     211             :   std::vector<double> coupling_rate_;
+     212             :   std::vector<double> coupling_accum_;
+     213             :   std::vector<double> means_;
+     214             :   std::vector<double> differences_;
+     215             :   std::vector<double> alpha_vector_;
+     216             :   std::vector<double> alpha_vector_2_;
+     217             :   std::vector<double> ssds_;
+     218             :   std::vector<double> step_size_;
+     219             :   std::vector<double> pseudo_virial_;
+     220             :   std::vector<Value *> out_coupling_;
+     221             :   Matrix<double> covar_;
+     222             :   Matrix<double> covar2_;
+     223             :   Matrix<double> lm_inv_;
+     224             :   std::string in_restart_name_;
+     225             :   std::string out_restart_name_;
+     226             :   std::string fmt_;
+     227             :   OFile out_restart_;
+     228             :   IFile in_restart_;
+     229             :   bool b_c_values_;
+     230             :   bool b_adaptive_;
+     231             :   bool b_freeze_;
+     232             :   bool b_equil_;
+     233             :   bool b_ramp_;
+     234             :   bool b_covar_;
+     235             :   bool b_restart_;
+     236             :   bool b_write_restart_;
+     237             :   bool b_lm_;
+     238             :   bool b_virial_;
+     239             :   bool b_update_virial_;
+     240             :   bool b_weights_;
+     241             :   int seed_;
+     242             :   int update_period_;
+     243             :   int avg_coupling_count_;
+     244             :   int update_calls_;
+     245             :   double kbt_;
+     246             :   double multi_prop_;
+     247             :   double lm_mixing_par_;
+     248             :   double virial_scaling_;
+     249             :   double pseudo_virial_sum_; // net virial for all cvs in current period
+     250             :   double max_logweight_;     // maximum observed max logweight for period
+     251             :   double wsum_;              // sum of weights thus far
+     252             :   Random rand_;
+     253             :   Value *value_force2_;
+     254             :   Value *value_pressure_;
+     255             : 
+     256             :   /*read input restart. b_mean sets if we use mean or final value for freeze*/
+     257             :   void readInRestart(const bool b_mean);
+     258             :   /*setup output restart*/
+     259             :   void setupOutRestart();
+     260             :   /*write output restart*/
+     261             :   void writeOutRestart();
+     262             :   void update_statistics();
+     263             :   void update_pseudo_virial();
+     264             :   void calc_lm_step_size();
+     265             :   void calc_covar_step_size();
+     266             :   void calc_ssd_step_size();
+     267             :   void reset_statistics();
+     268             :   void update_bias();
+     269             :   void apply_bias();
+     270             : 
+     271             : public:
+     272             :   explicit EDS(const ActionOptions &);
+     273             :   void calculate();
+     274             :   void update();
+     275             :   void turnOnDerivatives();
+     276             :   static void registerKeywords(Keywords &keys);
+     277             :   ~EDS();
+     278             : };
+     279             : 
+     280       10435 : PLUMED_REGISTER_ACTION(EDS, "EDS")
+     281             : 
+     282           9 : void EDS::registerKeywords(Keywords &keys)
+     283             : {
+     284           9 :   Bias::registerKeywords(keys);
+     285           9 :   keys.use("ARG");
+     286          18 :   keys.add("optional", "CENTER", "The desired centers (equilibrium values) which will be sought during the adaptive linear biasing. This is for fixed centers");
+     287          18 :   keys.add("optional", "CENTER_ARG", "The desired centers (equilibrium values) which will be sought during the adaptive linear biasing. "
+     288             :            "CENTER_ARG is for calculated centers, e.g. from a CV or analysis. ");
+     289             : 
+     290          18 :   keys.add("optional", "PERIOD", "Steps over which to adjust bias for adaptive or ramping");
+     291          18 :   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 based");
+     292          18 :   keys.add("compulsory", "SEED", "0", "Seed for random order of changing bias");
+     293          18 :   keys.add("compulsory", "INIT", "0", "Starting value for coupling constant");
+     294          18 :   keys.add("compulsory", "FIXED", "0", "Fixed target values for coupling constant. Non-adaptive.");
+     295          18 :   keys.add("optional", "BIAS_SCALE", "A divisor to set the units of the bias. "
+     296             :            "If not set, this will be the CENTER value by default (as is done in White and Voth 2014).");
+     297          18 :   keys.add("optional", "TEMP", "The system temperature. If not provided will be taken from MD code (if available)");
+     298          18 :   keys.add("optional", "MULTI_PROP", "What proportion of dimensions to update at each step. "
+     299             :            "Must be in interval [1,0), where 1 indicates all and any other indicates a stochastic update. "
+     300             :            "If not set, default is 1 / N, where N is the number of CVs. ");
+     301          18 :   keys.add("optional", "VIRIAL", "Add an update penalty for having non-zero virial contributions. Only makes sense with multiple correlated CVs.");
+     302          18 :   keys.add("optional", "LOGWEIGHTS", "Add weights to use for computing statistics. For example, if biasing with metadynamics.");
+     303          18 :   keys.addFlag("LM", false, "Use Levenberg-Marquadt algorithm along with simultaneous keyword. Otherwise use gradient descent.");
+     304          18 :   keys.add("compulsory", "LM_MIXING", "1", "Initial mixing parameter when using Levenberg-Marquadt minimization.");
+     305          18 :   keys.add("optional", "RESTART_FMT", "the format that should be used to output real numbers in EDS restarts");
+     306          18 :   keys.add("optional", "OUT_RESTART", "Output file for all information needed to continue EDS simulation. "
+     307             :            "If you have the RESTART directive set (global or for EDS), this file will be appended to. "
+     308             :            "Note that the header will be printed again if appending.");
+     309          18 :   keys.add("optional", "IN_RESTART", "Read this file to continue an EDS simulation. "
+     310             :            "If same as OUT_RESTART and you have not set the RESTART directive, the file will be backed-up and overwritten with new output. "
+     311             :            "If you do have the RESTART flag set and it is the same name as OUT_RESTART, this file will be appended.");
+     312             : 
+     313          18 :   keys.addFlag("RAMP", false, "Slowly increase bias constant to a fixed value");
+     314          18 :   keys.addFlag("COVAR", false, "Utilize the covariance matrix when updating the bias. Default Off, but may be enabled due to other options");
+     315          18 :   keys.addFlag("FREEZE", false, "Fix bias at current level (only used for restarting).");
+     316          18 :   keys.addFlag("MEAN", false, "Instead of using final bias level from restart, use average. Can only be used in conjunction with FREEZE");
+     317             : 
+     318           9 :   keys.use("RESTART");
+     319             : 
+     320          18 :   keys.addOutputComponent("force2", "default", "squared value of force from the bias");
+     321          18 :   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)");
+     322          18 :   keys.addOutputComponent("_coupling", "default", "For each named CV biased, there will be a corresponding output CV_coupling storing the current linear bias prefactor.");
+     323           9 : }
+     324             : 
+     325           8 : EDS::EDS(const ActionOptions &ao) : PLUMED_BIAS_INIT(ao),
+     326           8 :   ncvs_(getNumberOfArguments()),
+     327           8 :   scale_(ncvs_, 0.0),
+     328           8 :   current_coupling_(ncvs_, 0.0),
+     329           8 :   set_coupling_(ncvs_, 0.0),
+     330           8 :   target_coupling_(ncvs_, 0.0),
+     331           8 :   max_coupling_range_(ncvs_, 25.0),
+     332           8 :   max_coupling_grad_(ncvs_, 0.0),
+     333           8 :   coupling_rate_(ncvs_, 1.0),
+     334           8 :   coupling_accum_(ncvs_, 0.0),
+     335           8 :   means_(ncvs_, 0.0),
+     336           8 :   step_size_(ncvs_, 0.0),
+     337           8 :   pseudo_virial_(ncvs_),
+     338           8 :   out_coupling_(ncvs_, NULL),
+     339           8 :   in_restart_name_(""),
+     340           8 :   out_restart_name_(""),
+     341           8 :   fmt_("%f"),
+     342           8 :   b_adaptive_(true),
+     343           8 :   b_freeze_(false),
+     344           8 :   b_equil_(true),
+     345           8 :   b_ramp_(false),
+     346           8 :   b_covar_(false),
+     347           8 :   b_restart_(false),
+     348           8 :   b_write_restart_(false),
+     349           8 :   b_lm_(false),
+     350           8 :   b_virial_(false),
+     351           8 :   b_weights_(false),
+     352           8 :   seed_(0),
+     353           8 :   update_period_(0),
+     354           8 :   avg_coupling_count_(1),
+     355           8 :   update_calls_(0),
+     356           8 :   kbt_(0.0),
+     357           8 :   multi_prop_(-1.0),
+     358           8 :   lm_mixing_par_(0.1),
+     359           8 :   virial_scaling_(0.),
+     360           8 :   pseudo_virial_sum_(0.0),
+     361           8 :   max_logweight_(0.0),
+     362           8 :   wsum_(0.0),
+     363          32 :   value_force2_(NULL)
+     364             : {
+     365           8 :   double temp = -1.0;
+     366           8 :   bool b_mean = false;
+     367             :   std::vector<Value *> wvalues;
+     368             : 
+     369           8 :   addComponent("force2");
+     370           8 :   componentIsNotPeriodic("force2");
+     371           8 :   value_force2_ = getPntrToComponent("force2");
+     372             : 
+     373          20 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     374             :   {
+     375          12 :     std::string comp = getPntrToArgument(i)->getName() + "_coupling";
+     376          12 :     addComponent(comp);
+     377          12 :     componentIsNotPeriodic(comp);
+     378          12 :     out_coupling_[i] = getPntrToComponent(comp);
+     379             :   }
+     380             : 
+     381           8 :   parseVector("CENTER", center_);
+     382           8 :   parseArgumentList("CENTER_ARG", center_values_);
+     383           8 :   parseArgumentList("LOGWEIGHTS", wvalues);
+     384           8 :   parseVector("BIAS_SCALE", scale_);
+     385           8 :   parseVector("RANGE", max_coupling_range_);
+     386           8 :   parseVector("FIXED", target_coupling_);
+     387           8 :   parseVector("INIT", set_coupling_);
+     388           8 :   parse("PERIOD", update_period_);
+     389           8 :   parse("TEMP", temp);
+     390           8 :   parse("SEED", seed_);
+     391           8 :   parse("MULTI_PROP", multi_prop_);
+     392           8 :   parse("LM_MIXING", lm_mixing_par_);
+     393           8 :   parse("RESTART_FMT", fmt_);
+     394           8 :   parse("VIRIAL", virial_scaling_);
+     395           8 :   fmt_ = " " + fmt_; // add space since parse strips them
+     396           8 :   parse("OUT_RESTART", out_restart_name_);
+     397           8 :   parseFlag("LM", b_lm_);
+     398           8 :   parseFlag("RAMP", b_ramp_);
+     399           8 :   parseFlag("FREEZE", b_freeze_);
+     400           8 :   parseFlag("MEAN", b_mean);
+     401           8 :   parseFlag("COVAR", b_covar_);
+     402           8 :   parse("IN_RESTART", in_restart_name_);
+     403           8 :   checkRead();
+     404             : 
+     405             :   /*
+     406             :    * Things that are different when using changing centers:
+     407             :    * 1. Scale
+     408             :    * 2. The log file
+     409             :    * 3. Reading Restarts
+     410             :    */
+     411             : 
+     412           8 :   if (center_.size() == 0)
+     413             :   {
+     414           1 :     if (center_values_.size() == 0)
+     415           0 :       error("Must set either CENTER or CENTER_ARG");
+     416           1 :     else if (center_values_.size() != ncvs_)
+     417           0 :       error("CENTER_ARG must contain the same number of variables as ARG");
+     418           1 :     b_c_values_ = true;
+     419           1 :     center_.resize(ncvs_);
+     420           1 :     log.printf("  EDS will use possibly varying centers\n");
+     421             :   }
+     422             :   else
+     423             :   {
+     424           7 :     if (center_.size() != ncvs_)
+     425           0 :       error("Must have same number of CENTER arguments as ARG arguments");
+     426           7 :     else if (center_values_.size() != 0)
+     427           0 :       error("You can only set CENTER or CENTER_ARG. Not both");
+     428           7 :     b_c_values_ = false;
+     429           7 :     log.printf("  EDS will use fixed centers\n");
+     430             :   }
+     431             : 
+     432             :   // check for weights
+     433           8 :   if (wvalues.size() > 1)
+     434             :   {
+     435           0 :     error("LOGWEIGHTS can only support one weight set. Please only pass one action");
+     436             :   }
+     437           8 :   else if (wvalues.size() == 1)
+     438             :   {
+     439           1 :     logweights_ = dynamic_cast<ReweightBase *>(wvalues[0]->getPntrToAction());
+     440           1 :     b_weights_ = true;
+     441             :   }
+     442             : 
+     443           8 :   log.printf("  setting scaling:");
+     444           8 :   if (scale_.size() > 0 && scale_.size() < ncvs_)
+     445             :   {
+     446           0 :     error("the number of BIAS_SCALE values be the same as number of CVs");
+     447             :   }
+     448           8 :   else if (scale_.size() == 0 && b_c_values_)
+     449             :   {
+     450           0 :     log.printf(" Setting SCALE to be 1 for all CVs\n");
+     451           0 :     scale_.resize(ncvs_);
+     452           0 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     453           0 :       scale_[i] = 1;
+     454             :   }
+     455           8 :   else if (scale_.size() == 0 && !b_c_values_)
+     456             :   {
+     457           2 :     log.printf(" (default) ");
+     458             : 
+     459           2 :     scale_.resize(ncvs_);
+     460           6 :     for (unsigned int i = 0; i < scale_.size(); ++i)
+     461             :     {
+     462           4 :       if (center_[i] == 0)
+     463           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");
+     464           4 :       scale_[i] = center_[i];
+     465             :     }
+     466             :   }
+     467             :   else
+     468             :   {
+     469          14 :     for (unsigned int i = 0; i < scale_.size(); ++i)
+     470           8 :       log.printf(" %f", scale_[i]);
+     471             :   }
+     472           8 :   log.printf("\n");
+     473             : 
+     474           8 :   if (b_lm_)
+     475             :   {
+     476           1 :     log.printf("  EDS will perform Levenberg-Marquardt minimization with mixing parameter = %f\n", lm_mixing_par_);
+     477           1 :     differences_.resize(ncvs_);
+     478           1 :     alpha_vector_.resize(ncvs_);
+     479           1 :     alpha_vector_2_.resize(ncvs_);
+     480           1 :     covar_.resize(ncvs_, ncvs_);
+     481           1 :     covar2_.resize(ncvs_, ncvs_);
+     482           1 :     lm_inv_.resize(ncvs_, ncvs_);
+     483           1 :     covar2_ *= 0;
+     484           1 :     lm_inv_ *= 0;
+     485           1 :     if (multi_prop_ != 1)
+     486           0 :       log.printf("     WARNING - doing LM minimization but MULTI_PROP!=1\n");
+     487             :   }
+     488           7 :   else if (b_covar_)
+     489             :   {
+     490           1 :     log.printf("  EDS will utilize covariance matrix for update steps\n");
+     491           1 :     covar_.resize(ncvs_, ncvs_);
+     492             :   }
+     493             :   else
+     494             :   {
+     495           6 :     log.printf("  EDS will utilize variance for update steps\n");
+     496           6 :     ssds_.resize(ncvs_);
+     497             :   }
+     498             : 
+     499           8 :   b_virial_ = virial_scaling_;
+     500             : 
+     501           8 :   if (b_virial_)
+     502             :   {
+     503           1 :     if (ncvs_ == 1)
+     504           0 :       error("Minimizing the virial is only valid with multiply correlated collective variables.");
+     505             :     // check that the CVs can be used to compute pseudo-virial
+     506           1 :     log.printf("  EDS will compute virials of CVs and penalize with scale of %f. Checking CVs are valid...", virial_scaling_);
+     507           4 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     508             :     {
+     509           3 :       auto a = dynamic_cast<ActionAtomistic *>(getPntrToArgument(i)->getPntrToAction());
+     510           3 :       if (!a)
+     511           0 :         error("If using VIRIAL keyword, you must have normal CVs as arguments to EDS. Offending action: " + getPntrToArgument(i)->getPntrToAction()->getName());
+     512             :       // cppcheck-suppress nullPointerRedundantCheck
+     513           3 :       if (!(a->getPbc().isOrthorombic()))
+     514           3 :         log.printf("  WARNING: EDS Virial should have a orthorombic cell\n");
+     515             :     }
+     516           1 :     log.printf("done.\n");
+     517           1 :     addComponent("pressure");
+     518           1 :     componentIsNotPeriodic("pressure");
+     519           1 :     value_pressure_ = getPntrToComponent("pressure");
+     520             :   }
+     521             : 
+     522           8 :   if (b_mean && !b_freeze_)
+     523             :   {
+     524           0 :     error("EDS keyword MEAN can only be used along with keyword FREEZE");
+     525             :   }
+     526             : 
+     527           8 :   if (in_restart_name_ != "")
+     528             :   {
+     529           2 :     b_restart_ = true;
+     530           2 :     log.printf("  reading simulation information from file: %s\n", in_restart_name_.c_str());
+     531           2 :     readInRestart(b_mean);
+     532             :   }
+     533             :   else
+     534             :   {
+     535             : 
+     536           6 :     if (temp >= 0.0)
+     537           6 :       kbt_ = plumed.getAtoms().getKBoltzmann() * temp;
+     538             :     else
+     539           0 :       kbt_ = plumed.getAtoms().getKbT();
+     540             : 
+     541             :     // in driver, this results in kbt of 0
+     542           6 :     if (kbt_ == 0)
+     543             :     {
+     544           0 :       error("  Unable to determine valid kBT. "
+     545             :             "Could be because you are runnning from driver or MD didn't give temperature.\n"
+     546             :             "Consider setting temperature manually with the TEMP keyword.");
+     547             :       kbt_ = 1;
+     548             :     }
+     549             : 
+     550           6 :     log.printf("  kBT = %f\n", kbt_);
+     551           6 :     log.printf("  Updating every %i steps\n", update_period_);
+     552             : 
+     553           6 :     if (!b_c_values_)
+     554             :     {
+     555           5 :       log.printf("  with centers:");
+     556          14 :       for (unsigned int i = 0; i < ncvs_; ++i)
+     557             :       {
+     558           9 :         log.printf(" %f ", center_[i]);
+     559             :       }
+     560             :     }
+     561             :     else
+     562             :     {
+     563           1 :       log.printf("  with actions centers:");
+     564           2 :       for (unsigned int i = 0; i < ncvs_; ++i)
+     565             :       {
+     566           1 :         log.printf(" %s ", center_values_[i]->getName().c_str());
+     567             :         // add dependency on these actions
+     568           1 :         addDependency(center_values_[i]->getPntrToAction());
+     569             :       }
+     570             :     }
+     571             : 
+     572           6 :     log.printf("\n  with initial ranges / rates:\n");
+     573          16 :     for (unsigned int i = 0; i < max_coupling_range_.size(); ++i)
+     574             :     {
+     575             :       // this is just an empirical guess. Bigger range, bigger grads. Less frequent updates, bigger changes
+     576             :       //
+     577             :       // using the current maxing out scheme, max_coupling_range is the biggest step that can be taken in any given interval
+     578          10 :       max_coupling_range_[i] *= kbt_;
+     579          10 :       max_coupling_grad_[i] = max_coupling_range_[i];
+     580          10 :       log.printf("    %f / %f\n", max_coupling_range_[i], max_coupling_grad_[i]);
+     581             :     }
+     582             : 
+     583           6 :     if (seed_ > 0)
+     584             :     {
+     585           2 :       log.printf("  setting random seed = %i", seed_);
+     586           2 :       rand_.setSeed(seed_);
+     587             :     }
+     588             : 
+     589          16 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     590          10 :       if (target_coupling_[i] != 0.0)
+     591           1 :         b_adaptive_ = false;
+     592             : 
+     593           6 :     if (!b_adaptive_)
+     594             :     {
+     595           1 :       if (b_ramp_)
+     596             :       {
+     597           1 :         log.printf("  ramping up coupling constants over %i steps\n", update_period_);
+     598             :       }
+     599             : 
+     600           1 :       log.printf("  with starting coupling constants");
+     601           2 :       for (unsigned int i = 0; i < set_coupling_.size(); ++i)
+     602           1 :         log.printf(" %f", set_coupling_[i]);
+     603           1 :       log.printf("\n");
+     604           1 :       log.printf("  and final coupling constants");
+     605           2 :       for (unsigned int i = 0; i < target_coupling_.size(); ++i)
+     606           1 :         log.printf(" %f", target_coupling_[i]);
+     607           1 :       log.printf("\n");
+     608             :     }
+     609             : 
+     610             :     // now do setup
+     611           6 :     if (b_ramp_)
+     612             :     {
+     613           1 :       update_period_ *= -1;
+     614             :     }
+     615             : 
+     616          16 :     for (unsigned int i = 0; i < set_coupling_.size(); ++i)
+     617          10 :       current_coupling_[i] = set_coupling_[i];
+     618             : 
+     619             :     // if b_adaptive_, then first half will be used for equilibrating and second half for statistics
+     620           6 :     if (update_period_ > 0)
+     621             :     {
+     622           5 :       update_period_ /= 2;
+     623             :     }
+     624             :   }
+     625             : 
+     626           8 :   if (b_freeze_)
+     627             :   {
+     628           1 :     b_adaptive_ = false;
+     629           1 :     update_period_ = 0;
+     630           1 :     if (b_mean)
+     631             :     {
+     632           1 :       log.printf("  freezing bias at the average level from the restart file\n");
+     633             :     }
+     634             :     else
+     635             :     {
+     636           0 :       log.printf("  freezing bias at current level\n");
+     637             :     }
+     638             :   }
+     639             : 
+     640           8 :   if (multi_prop_ == -1.0)
+     641             :   {
+     642           5 :     log.printf("  Will update each dimension stochastically with probability 1 / number of CVs\n");
+     643           5 :     multi_prop_ = 1.0 / ncvs_;
+     644             :   }
+     645           3 :   else if (multi_prop_ > 0 && multi_prop_ <= 1.0)
+     646             :   {
+     647           3 :     log.printf("  Will update each dimension stochastically with probability %f\n", multi_prop_);
+     648             :   }
+     649             :   else
+     650             :   {
+     651           0 :     error("  MULTI_PROP must be between 0 and 1\n");
+     652             :   }
+     653             : 
+     654           8 :   if (out_restart_name_.length() > 0)
+     655             :   {
+     656           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());
+     657           8 :     b_write_restart_ = true;
+     658           8 :     setupOutRestart();
+     659             :   }
+     660             : 
+     661          16 :   log << "  Bibliography " << plumed.cite("White and Voth, J. Chem. Theory Comput. 10 (8), 3023-3030 (2014)") << "\n";
+     662          24 :   log << "  Bibliography " << plumed.cite("G. M. Hocky, T. Dannenhoffer-Lafage, G. A. Voth, J. Chem. Theory Comput. 13 (9), 4593-4603 (2017)") << "\n";
+     663           8 : }
+     664             : 
+     665           2 : void EDS::readInRestart(const bool b_mean)
+     666             : {
+     667           2 :   int adaptive_i = 0;
+     668             : 
+     669           2 :   in_restart_.open(in_restart_name_);
+     670             : 
+     671           4 :   if (in_restart_.FieldExist("kbt"))
+     672             :   {
+     673           2 :     in_restart_.scanField("kbt", kbt_);
+     674             :   }
+     675             :   else
+     676             :   {
+     677           0 :     error("No field 'kbt' in restart file");
+     678             :   }
+     679           2 :   log.printf("  with kBT = %f\n", kbt_);
+     680             : 
+     681           4 :   if (in_restart_.FieldExist("update_period"))
+     682             :   {
+     683           2 :     in_restart_.scanField("update_period", update_period_);
+     684             :   }
+     685             :   else
+     686             :   {
+     687           0 :     error("No field 'update_period' in restart file");
+     688             :   }
+     689           2 :   log.printf("  Updating every %i steps\n", update_period_);
+     690             : 
+     691           4 :   if (in_restart_.FieldExist("adaptive"))
+     692             :   {
+     693             :     // note, no version of scanField for boolean
+     694           2 :     in_restart_.scanField("adaptive", adaptive_i);
+     695             :   }
+     696             :   else
+     697             :   {
+     698           0 :     error("No field 'adaptive' in restart file");
+     699             :   }
+     700           2 :   b_adaptive_ = bool(adaptive_i);
+     701             : 
+     702           4 :   if (in_restart_.FieldExist("seed"))
+     703             :   {
+     704           2 :     in_restart_.scanField("seed", seed_);
+     705             :   }
+     706             :   else
+     707             :   {
+     708           0 :     error("No field 'seed' in restart file");
+     709             :   }
+     710           2 :   if (seed_ > 0)
+     711             :   {
+     712           0 :     log.printf("  setting random seed = %i", seed_);
+     713           0 :     rand_.setSeed(seed_);
+     714             :   }
+     715             : 
+     716             :   double time, tmp;
+     717           2 :   std::vector<double> avg_bias = std::vector<double>(center_.size());
+     718             :   unsigned int N = 0;
+     719             :   std::string cv_name;
+     720             : 
+     721          24 :   while (in_restart_.scanField("time", time))
+     722             :   {
+     723             : 
+     724          20 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     725             :     {
+     726             :       cv_name = getPntrToArgument(i)->getName();
+     727          20 :       in_restart_.scanField(cv_name + "_center", set_coupling_[i]);
+     728          20 :       in_restart_.scanField(cv_name + "_set", set_coupling_[i]);
+     729          20 :       in_restart_.scanField(cv_name + "_target", target_coupling_[i]);
+     730          20 :       in_restart_.scanField(cv_name + "_coupling", current_coupling_[i]);
+     731          20 :       in_restart_.scanField(cv_name + "_maxrange", max_coupling_range_[i]);
+     732          20 :       in_restart_.scanField(cv_name + "_maxgrad", max_coupling_grad_[i]);
+     733          20 :       in_restart_.scanField(cv_name + "_accum", coupling_accum_[i]);
+     734          10 :       in_restart_.scanField(cv_name + "_mean", means_[i]);
+     735          20 :       if (in_restart_.FieldExist(cv_name + "_pseudovirial"))
+     736             :       {
+     737           0 :         if (b_virial_)
+     738           0 :           in_restart_.scanField(cv_name + "_pseudovirial", pseudo_virial_[i]);
+     739             :         else // discard the field
+     740           0 :           in_restart_.scanField(cv_name + "_pseudovirial", tmp);
+     741             :       }
+     742             :       // unused due to difference between covar/nocovar
+     743          20 :       in_restart_.scanField(cv_name + "_std", tmp);
+     744             : 
+     745          10 :       avg_bias[i] += current_coupling_[i];
+     746             :     }
+     747          10 :     N++;
+     748             : 
+     749          10 :     in_restart_.scanField();
+     750             :   }
+     751             : 
+     752           2 :   log.printf("  with centers:");
+     753           4 :   for (unsigned int i = 0; i < center_.size(); ++i)
+     754             :   {
+     755           2 :     log.printf(" %f", center_[i]);
+     756             :   }
+     757           2 :   log.printf("\n  and scaling:");
+     758           4 :   for (unsigned int i = 0; i < scale_.size(); ++i)
+     759             :   {
+     760           2 :     log.printf(" %f", scale_[i]);
+     761             :   }
+     762             : 
+     763           2 :   log.printf("\n  with initial ranges / rates:\n");
+     764           4 :   for (unsigned int i = 0; i < max_coupling_range_.size(); ++i)
+     765             :   {
+     766           2 :     log.printf("    %f / %f\n", max_coupling_range_[i], max_coupling_grad_[i]);
+     767             :   }
+     768             : 
+     769           2 :   if (!b_adaptive_ && update_period_ < 0)
+     770             :   {
+     771           0 :     log.printf("  ramping up coupling constants over %i steps\n", -update_period_);
+     772             :   }
+     773             : 
+     774           2 :   if (b_mean)
+     775             :   {
+     776           1 :     log.printf("Loaded in averages for coupling constants...\n");
+     777           2 :     for (unsigned int i = 0; i < current_coupling_.size(); ++i)
+     778           1 :       current_coupling_[i] = avg_bias[i] / N;
+     779           2 :     for (unsigned int i = 0; i < current_coupling_.size(); ++i)
+     780           1 :       set_coupling_[i] = avg_bias[i] / N;
+     781             :   }
+     782             : 
+     783           2 :   log.printf("  with current coupling constants:\n    ");
+     784           4 :   for (unsigned int i = 0; i < current_coupling_.size(); ++i)
+     785           2 :     log.printf(" %f", current_coupling_[i]);
+     786           2 :   log.printf("\n");
+     787           2 :   log.printf("  with initial coupling constants:\n    ");
+     788           4 :   for (unsigned int i = 0; i < set_coupling_.size(); ++i)
+     789           2 :     log.printf(" %f", set_coupling_[i]);
+     790           2 :   log.printf("\n");
+     791           2 :   log.printf("  and final coupling constants:\n    ");
+     792           4 :   for (unsigned int i = 0; i < target_coupling_.size(); ++i)
+     793           2 :     log.printf(" %f", target_coupling_[i]);
+     794           2 :   log.printf("\n");
+     795             : 
+     796           2 :   in_restart_.close();
+     797           2 : }
+     798             : 
+     799           8 : void EDS::setupOutRestart()
+     800             : {
+     801           8 :   out_restart_.link(*this);
+     802           8 :   out_restart_.fmtField(fmt_);
+     803           8 :   out_restart_.open(out_restart_name_);
+     804             :   out_restart_.setHeavyFlush();
+     805             : 
+     806          16 :   out_restart_.addConstantField("adaptive").printField("adaptive", b_adaptive_);
+     807          16 :   out_restart_.addConstantField("update_period").printField("update_period", update_period_);
+     808          16 :   out_restart_.addConstantField("seed").printField("seed", seed_);
+     809          16 :   out_restart_.addConstantField("kbt").printField("kbt", kbt_);
+     810           8 : }
+     811             : 
+     812          27 : void EDS::writeOutRestart()
+     813             : {
+     814             :   std::string cv_name;
+     815          27 :   out_restart_.printField("time", getTimeStep() * getStep());
+     816             : 
+     817          66 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     818             :   {
+     819             :     cv_name = getPntrToArgument(i)->getName();
+     820          78 :     out_restart_.printField(cv_name + "_center", center_[i]);
+     821          78 :     out_restart_.printField(cv_name + "_set", set_coupling_[i]);
+     822          78 :     out_restart_.printField(cv_name + "_target", target_coupling_[i]);
+     823          78 :     out_restart_.printField(cv_name + "_coupling", current_coupling_[i]);
+     824          78 :     out_restart_.printField(cv_name + "_maxrange", max_coupling_range_[i]);
+     825          78 :     out_restart_.printField(cv_name + "_maxgrad", max_coupling_grad_[i]);
+     826          78 :     out_restart_.printField(cv_name + "_accum", coupling_accum_[i]);
+     827          39 :     out_restart_.printField(cv_name + "_mean", means_[i]);
+     828          39 :     if (b_virial_)
+     829          18 :       out_restart_.printField(cv_name + "_pseudovirial", pseudo_virial_[i]);
+     830          39 :     if (!b_covar_ && !b_lm_)
+     831          42 :       out_restart_.printField(cv_name + "_std", ssds_[i] / (fmax(1, update_calls_ - 1)));
+     832             :     else
+     833          36 :       out_restart_.printField(cv_name + "_std", covar_(i, i) / (fmax(1, update_calls_ - 1)));
+     834             :   }
+     835          27 :   out_restart_.printField();
+     836          27 : }
+     837             : 
+     838          40 : void EDS::calculate()
+     839             : {
+     840             : 
+     841             :   // get center values from action if necessary
+     842          40 :   if (b_c_values_)
+     843          10 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     844           5 :       center_[i] = center_values_[i]->get();
+     845             : 
+     846          40 :   apply_bias();
+     847          40 : }
+     848             : 
+     849          40 : void EDS::apply_bias()
+     850             : {
+     851             :   // Compute linear force as in "restraint"
+     852             :   double ene = 0, totf2 = 0, cv, m, f;
+     853             : 
+     854         100 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     855             :   {
+     856          60 :     cv = difference(i, center_[i], getArgument(i));
+     857          60 :     m = current_coupling_[i];
+     858          60 :     f = -m;
+     859          60 :     ene += m * cv;
+     860             :     setOutputForce(i, f);
+     861          60 :     totf2 += f * f;
+     862             :   }
+     863             : 
+     864             :   setBias(ene);
+     865          40 :   value_force2_->set(totf2);
+     866          40 : }
+     867             : 
+     868          12 : void EDS::update_statistics()
+     869             : {
+     870             :   double s, N, w = 1.0;
+     871          12 :   std::vector<double> deltas(ncvs_);
+     872             : 
+     873             :   // update weight max, if necessary
+     874          12 :   if (b_weights_)
+     875             :   {
+     876           2 :     w = logweights_->getLogWeight();
+     877           2 :     if (max_logweight_ < w)
+     878             :     {
+     879             :       // we have new max. Need to shift existing values
+     880           0 :       wsum_ *= exp(max_logweight_ - w);
+     881           0 :       max_logweight_ = w;
+     882             :     }
+     883             :     // convert to weight
+     884           2 :     w = exp(w - max_logweight_);
+     885           2 :     wsum_ += w;
+     886             :     N = wsum_;
+     887             :   }
+     888             :   else
+     889             :   {
+     890          10 :     N = fmax(1, update_calls_);
+     891             :   }
+     892             : 
+     893             :   // Welford, West, and Hanso online variance method
+     894             :   // with weights (default =  1.0)
+     895          32 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     896             :   {
+     897          20 :     deltas[i] = difference(i, means_[i], getArgument(i)) * w;
+     898          20 :     means_[i] += deltas[i] / N;
+     899          20 :     if (!b_covar_ && !b_lm_)
+     900           8 :       ssds_[i] += deltas[i] * difference(i, means_[i], getArgument(i));
+     901             :   }
+     902          12 :   if (b_covar_ || b_lm_)
+     903             :   {
+     904          16 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     905             :     {
+     906          36 :       for (unsigned int j = i; j < ncvs_; ++j)
+     907             :       {
+     908          24 :         s = (N - 1) * deltas[i] * deltas[j] / N / N - covar_(i, j) / N;
+     909          24 :         covar_(i, j) += s;
+     910             :         // do this so we don't double count
+     911          24 :         covar_(j, i) = covar_(i, j);
+     912             :       }
+     913             :     }
+     914             :   }
+     915          12 :   if (b_virial_)
+     916           2 :     update_pseudo_virial();
+     917          12 : }
+     918             : 
+     919           8 : void EDS::reset_statistics()
+     920             : {
+     921          20 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     922             :   {
+     923          12 :     means_[i] = 0;
+     924          12 :     if (!b_covar_ && !b_lm_)
+     925           6 :       ssds_[i] = 0;
+     926             :   }
+     927           8 :   if (b_covar_ || b_lm_)
+     928           8 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     929          24 :       for (unsigned int j = 0; j < ncvs_; ++j)
+     930          18 :         covar_(i, j) = 0;
+     931           8 :   if (b_virial_)
+     932             :   {
+     933           4 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     934           3 :       pseudo_virial_[i] = 0;
+     935           1 :     pseudo_virial_sum_ = 0;
+     936             :   }
+     937           8 :   if (b_weights_)
+     938             :   {
+     939           2 :     wsum_ = 0;
+     940           2 :     max_logweight_ = 0;
+     941             :   }
+     942           8 : }
+     943             : 
+     944           1 : void EDS::calc_lm_step_size()
+     945             : {
+     946             :   // calulcate step size
+     947             :   // uses scale here, which by default is center
+     948             : 
+     949           1 :   mult(covar_, covar_, covar2_);
+     950           4 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     951             :   {
+     952           3 :     differences_[i] = difference(i, center_[i], means_[i]);
+     953           3 :     covar2_[i][i] += lm_mixing_par_ * covar2_[i][i];
+     954             :   }
+     955             : 
+     956             :   // "step_size_vec" = 2*inv(covar*covar+ lambda diag(covar*covar))*covar*(mean-center)
+     957           1 :   mult(covar_, differences_, alpha_vector_);
+     958           1 :   Invert(covar2_, lm_inv_);
+     959           1 :   mult(lm_inv_, alpha_vector_, alpha_vector_2_);
+     960             : 
+     961           4 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     962             :   {
+     963           3 :     step_size_[i] = 2 * alpha_vector_2_[i] / kbt_ / scale_[i];
+     964             :   }
+     965           1 : }
+     966             : 
+     967           1 : void EDS::calc_covar_step_size()
+     968             : {
+     969             :   // calulcate step size
+     970             :   // uses scale here, which by default is center
+     971             :   double tmp;
+     972           4 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     973             :   {
+     974             :     tmp = 0;
+     975          12 :     for (unsigned int j = 0; j < ncvs_; ++j)
+     976           9 :       tmp += difference(i, center_[i], means_[i]) * covar_(i, j);
+     977           3 :     step_size_[i] = 2 * tmp / kbt_ / scale_[i] * update_calls_ / fmax(1, update_calls_ - 1);
+     978             :   }
+     979           1 : }
+     980             : 
+     981           6 : void EDS::calc_ssd_step_size()
+     982             : {
+     983             :   double tmp;
+     984          12 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     985             :   {
+     986           6 :     tmp = 2. * difference(i, center_[i], means_[i]) * ssds_[i] / fmax(1, update_calls_ - 1);
+     987           6 :     step_size_[i] = tmp / kbt_ / scale_[i];
+     988             :   }
+     989           6 : }
+     990             : 
+     991           2 : void EDS::update_pseudo_virial()
+     992             : {
+     993             :   // We want to compute the bias force on each atom times the position
+     994             :   //  of the atoms.
+     995             :   double p, netp = 0, netpv = 0;
+     996             :   double volume = 0;
+     997           8 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     998             :   {
+     999             :     // checked in setup to ensure this cast is valid.
+    1000           6 :     ActionAtomistic *cv = dynamic_cast<ActionAtomistic *>(getPntrToArgument(i)->getPntrToAction());
+    1001             :     Tensor &v(cv->modifyVirial());
+    1002           6 :     Tensor box(cv->getBox());
+    1003             :     const unsigned int natoms = cv->getNumberOfAtoms();
+    1004           6 :     if (!volume)
+    1005           2 :       volume = box.determinant();
+    1006             : 
+    1007             :     // pressure contribution is -dBias / dV
+    1008             :     // dBias / dV = alpha / w * dCV / dV
+    1009             :     // to get partial of CV wrt to volume
+    1010             :     // dCV/dV = sum dCV/dvij * vij / V
+    1011             :     // where vij is box element
+    1012             :     // add diagonal of virial tensor to get net pressure
+    1013             :     // TODO: replace this with adjugate (Jacobi's Formula)   for non-orthorombic case(?)
+    1014           6 :     p = v(0, 0) * box(0, 0) + v(1, 1) * box(1, 1) + v(2, 2) * box(2, 2);
+    1015           6 :     p /= volume;
+    1016             : 
+    1017           6 :     netp += p;
+    1018             : 
+    1019             :     // now scale for correct units in EDS algorithm
+    1020           6 :     p *= (volume) / (kbt_ * natoms);
+    1021             : 
+    1022             :     // compute running mean of scaled
+    1023           6 :     if (set_coupling_[i] != 0)
+    1024           0 :       pseudo_virial_[i] = (p - pseudo_virial_[i]) / (fmax(1, update_calls_));
+    1025             :     else
+    1026           6 :       pseudo_virial_[i] = 0;
+    1027             :     // update net pressure
+    1028           6 :     netpv += pseudo_virial_[i];
+    1029             :   }
+    1030             :   // update pressure
+    1031           2 :   value_pressure_->set(netp);
+    1032           2 :   pseudo_virial_sum_ = netpv;
+    1033           2 : }
+    1034             : 
+    1035           8 : void EDS::update_bias()
+    1036             : {
+    1037           8 :   log.flush();
+    1038           8 :   if (b_lm_)
+    1039           1 :     calc_lm_step_size();
+    1040           7 :   else if (b_covar_)
+    1041           1 :     calc_covar_step_size();
+    1042             :   else
+    1043           6 :     calc_ssd_step_size();
+    1044             : 
+    1045          20 :   for (unsigned int i = 0; i < ncvs_; ++i)
+    1046             :   {
+    1047             : 
+    1048             :     // multidimesional stochastic step
+    1049          12 :     if (ncvs_ == 1 || (rand_.RandU01() < (multi_prop_)))
+    1050             :     {
+    1051             : 
+    1052          12 :       if (b_virial_)
+    1053             :       {
+    1054             :         // apply virial regularization
+    1055             :         //  P * dP/dcoupling
+    1056             :         //  coupling is already included in virial term due to plumed propogating from bias to forces
+    1057             :         //  thus we need to divide by it to get the derivative (since force is linear in coupling)
+    1058           3 :         if (fabs(set_coupling_[i]) > 0.000000001) // my heuristic for if EDS has started to prevent / 0
+    1059             :           // scale^2 here is to align units
+    1060           0 :           step_size_[i] -= 2 * scale_[i] * scale_[i] * virial_scaling_ * pseudo_virial_sum_ * pseudo_virial_sum_ / set_coupling_[i];
+    1061             :       }
+    1062          12 :       if (step_size_[i] == 0)
+    1063           4 :         continue;
+    1064             : 
+    1065             :       // clip gradient
+    1066           8 :       step_size_[i] = copysign(fmin(fabs(step_size_[i]), max_coupling_grad_[i]), step_size_[i]);
+    1067           8 :       coupling_accum_[i] += step_size_[i] * step_size_[i];
+    1068             : 
+    1069             :       // equation 5 in White and Voth, JCTC 2014
+    1070             :       // no negative sign because it's in step_size
+    1071           8 :       set_coupling_[i] += step_size_[i] * max_coupling_range_[i] / sqrt(coupling_accum_[i]);
+    1072           8 :       coupling_rate_[i] = (set_coupling_[i] - current_coupling_[i]) / update_period_;
+    1073             :     }
+    1074             :     else
+    1075             :     {
+    1076             :       // do not change the bias
+    1077           0 :       coupling_rate_[i] = 0;
+    1078             :     }
+    1079             :   }
+    1080             : 
+    1081             :   // reset means/vars
+    1082           8 :   reset_statistics();
+    1083           8 : }
+    1084             : 
+    1085          40 : void EDS::update()
+    1086             : {
+    1087             :   // adjust parameters according to EDS recipe
+    1088          40 :   update_calls_++;
+    1089             : 
+    1090             :   // if we aren't wating for the bias to equilibrate, set flag to collect data
+    1091             :   // want statistics before writing restart
+    1092          40 :   if (!b_equil_ && update_period_ > 0)
+    1093          12 :     update_statistics();
+    1094             : 
+    1095             :   // write restart with correct statistics before bias update
+    1096             :   // check if we're ramping or doing normal updates and then restart if needed. The ramping check
+    1097             :   // is complicated because we could be frozen, finished ramping or not ramping.
+    1098             :   // The + 2 is so we have an extra line showing that the bias isn't changing (for my sanity and yours)
+    1099          40 :   if (b_write_restart_)
+    1100             :   {
+    1101          40 :     if (getStep() == 0 ||
+    1102          32 :         ((update_period_ < 0 && !b_freeze_ && update_calls_ <= fabs(update_period_) + 2) ||
+    1103          24 :          (update_period_ > 0 && update_calls_ % update_period_ == 0)))
+    1104          27 :       writeOutRestart();
+    1105             :   }
+    1106             : 
+    1107             :   int b_finished_equil_flag = 1;
+    1108             : 
+    1109             :   // assume forces already applied and saved
+    1110             :   // are we ramping to a constant value and not done equilibrating?
+    1111          40 :   if (update_period_ < 0)
+    1112             :   {
+    1113           5 :     if (update_calls_ <= fabs(update_period_) && !b_freeze_)
+    1114             :     {
+    1115           4 :       for (unsigned int i = 0; i < ncvs_; ++i)
+    1116           2 :         current_coupling_[i] += (target_coupling_[i] - set_coupling_[i]) / fabs(update_period_);
+    1117             :     }
+    1118             :     // make sure we don't reset update calls
+    1119             :     b_finished_equil_flag = 0;
+    1120             :   }
+    1121          35 :   else if (update_period_ == 0)
+    1122             :   { // do we have a no-update case?
+    1123             :     // not updating
+    1124             :     // pass
+    1125             :   }
+    1126          30 :   else if (b_equil_)
+    1127             :   {
+    1128             :     // equilibrating
+    1129             :     // check if we've reached the setpoint
+    1130          48 :     for (unsigned int i = 0; i < ncvs_; ++i)
+    1131             :     {
+    1132          30 :       if (coupling_rate_[i] == 0 || pow(current_coupling_[i] - set_coupling_[i], 2) < pow(coupling_rate_[i], 2))
+    1133             :       {
+    1134          14 :         b_finished_equil_flag &= 1;
+    1135             :       }
+    1136             :       else
+    1137             :       {
+    1138          16 :         current_coupling_[i] += coupling_rate_[i];
+    1139             :         b_finished_equil_flag = 0;
+    1140             :       }
+    1141             :     }
+    1142             :   }
+    1143             : 
+    1144             :   // reduce all the flags
+    1145          40 :   if (b_equil_ && b_finished_equil_flag)
+    1146             :   {
+    1147          11 :     b_equil_ = false;
+    1148          11 :     update_calls_ = 0;
+    1149             :   }
+    1150             : 
+    1151             :   // Now we update coupling constant, if necessary
+    1152          40 :   if (!b_equil_ && update_period_ > 0 && update_calls_ == update_period_ && !b_freeze_)
+    1153             :   {
+    1154           8 :     update_bias();
+    1155           8 :     update_calls_ = 0;
+    1156           8 :     avg_coupling_count_++;
+    1157           8 :     b_equil_ = true; // back to equilibration now
+    1158             :   }                  // close update if
+    1159             : 
+    1160             :   // pass couplings out so they are accessible
+    1161         100 :   for (unsigned int i = 0; i < ncvs_; ++i)
+    1162             :   {
+    1163          60 :     out_coupling_[i]->set(current_coupling_[i]);
+    1164             :   }
+    1165          40 : }
+    1166             : 
+    1167          16 : EDS::~EDS()
+    1168             : {
+    1169           8 :   out_restart_.close();
+    1170          24 : }
+    1171             : 
+    1172           0 : void EDS::turnOnDerivatives()
+    1173             : {
+    1174             :   // do nothing
+    1175             :   // this is to avoid errors triggered when a bias is used as a CV
+    1176             :   // (This is done in ExtendedLagrangian.cpp)
+    1177           0 : }
+    1178             : 
+    1179             : }
+    1180             : } // close the 2 namespaces
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/eds/index-sort-f.html b/coverage/eds/index-sort-f.html new file mode 100644 index 0000000000..0c661c0320 --- /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:45248892.6 %
Date:2024-06-10 08:19:14Functions:202387.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EDS.cpp +
92.6%92.6%
+
92.6 %452 / 48887.0 %20 / 23
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/eds/index-sort-l.html b/coverage/eds/index-sort-l.html new file mode 100644 index 0000000000..9436db0d68 --- /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:45248892.6 %
Date:2024-06-10 08:19:14Functions:202387.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EDS.cpp +
92.6%92.6%
+
92.6 %452 / 48887.0 %20 / 23
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/eds/index.html b/coverage/eds/index.html new file mode 100644 index 0000000000..26c263fa32 --- /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:45248892.6 %
Date:2024-06-10 08:19:14Functions:202387.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EDS.cpp +
92.6%92.6%
+
92.6 %452 / 48887.0 %20 / 23
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9fa9e2cf98 --- /dev/null +++ b/coverage/fisst/FISST.cpp.func-sort-c.html @@ -0,0 +1,161 @@ + + + + + + + + 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-06-10 08:19:14Functions:182281.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst5FISST13readInRestartEv0
_ZN4PLMD5fisst5FISST17turnOnDerivativesEv0
_ZN4PLMD5fisst5FISSTC2ERKNS_13ActionOptionsE0
_ZN4PLMD5fisst5FISSTD2Ev0
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe1676createERKNS_13ActionOptionsE2
_ZN4PLMD5fisst5FISST15setupOutRestartEv2
_ZN4PLMD5fisst5FISST18setupOutObservableEv2
_ZN4PLMD5fisst5FISSTC1ERKNS_13ActionOptionsE2
_ZN4PLMD5fisst5FISSTD0Ev2
_ZN4PLMD5fisst5FISSTD1Ev2
_ZN4PLMD5fisst5FISST16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD5fisst5FISST25compute_observable_weightEv8
_ZN4PLMD5fisst5FISST10apply_biasEv10
_ZN4PLMD5fisst5FISST11update_biasEv10
_ZN4PLMD5fisst5FISST15writeOutRestartEv10
_ZN4PLMD5fisst5FISST17update_statisticsEv10
_ZN4PLMD5fisst5FISST18writeOutObservableEv10
_ZN4PLMD5fisst5FISST6updateEv10
_ZN4PLMD5fisst5FISST9calculateEv10
_ZN4PLMD5fisst5FISST21NormalizeForceWeightsEv12
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe167C2Ev3473
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe167D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/fisst/FISST.cpp.func.html b/coverage/fisst/FISST.cpp.func.html new file mode 100644 index 0000000000..67e020e975 --- /dev/null +++ b/coverage/fisst/FISST.cpp.func.html @@ -0,0 +1,161 @@ + + + + + + + + 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-06-10 08:19:14Functions:182281.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe1676createERKNS_13ActionOptionsE2
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe167C2Ev3473
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe167D2Ev3473
_ZN4PLMD5fisst5FISST10apply_biasEv10
_ZN4PLMD5fisst5FISST11update_biasEv10
_ZN4PLMD5fisst5FISST13readInRestartEv0
_ZN4PLMD5fisst5FISST15setupOutRestartEv2
_ZN4PLMD5fisst5FISST15writeOutRestartEv10
_ZN4PLMD5fisst5FISST16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD5fisst5FISST17turnOnDerivativesEv0
_ZN4PLMD5fisst5FISST17update_statisticsEv10
_ZN4PLMD5fisst5FISST18setupOutObservableEv2
_ZN4PLMD5fisst5FISST18writeOutObservableEv10
_ZN4PLMD5fisst5FISST21NormalizeForceWeightsEv12
_ZN4PLMD5fisst5FISST25compute_observable_weightEv8
_ZN4PLMD5fisst5FISST6updateEv10
_ZN4PLMD5fisst5FISST9calculateEv10
_ZN4PLMD5fisst5FISSTC1ERKNS_13ActionOptionsE2
_ZN4PLMD5fisst5FISSTC2ERKNS_13ActionOptionsE0
_ZN4PLMD5fisst5FISSTD0Ev2
_ZN4PLMD5fisst5FISSTD1Ev2
_ZN4PLMD5fisst5FISSTD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/fisst/FISST.cpp.gcov.html b/coverage/fisst/FISST.cpp.gcov.html new file mode 100644 index 0000000000..90ac2aa369 --- /dev/null +++ b/coverage/fisst/FISST.cpp.gcov.html @@ -0,0 +1,739 @@ + + + + + + + + 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-06-10 08:19:14Functions:182281.8 %
+
+ + + + + + + + +

+
          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 "core/Atoms.h"
+      20             : #include "core/PlumedMain.h"
+      21             : #include "tools/File.h"
+      22             : #include "tools/Matrix.h"
+      23             : #include "tools/Random.h"
+      24             : #include "legendre_rule_fast.h"
+      25             : 
+      26             : #include <iostream>
+      27             : 
+      28             : 
+      29             : using namespace PLMD;
+      30             : using namespace bias;
+      31             : 
+      32             : //namespace is lowercase to match
+      33             : //module names being all lowercase
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace fisst {
+      37             : 
+      38             : //+PLUMEDOC FISSTMOD_BIAS FISST
+      39             : /*
+      40             : Compute and apply the optimal linear force on an observable to enhance sampling of conformational distributions over a range of applied forces.
+      41             : 
+      42             : This method is described in \cite Hartmann-FISST-2019
+      43             : 
+      44             : If the system's Hamiltonian is given by:
+      45             : \f[
+      46             :     H(\vec{p},\vec{q}) = \sum_{j} \frac{p_j^2}{2m_j} + U(\vec{q}),
+      47             : \f]
+      48             : 
+      49             : This bias modifies the Hamiltonian to be:
+      50             : \f[
+      51             :   H'(\vec{p},\vec{q}) = H(\vec{p},\vec{q}) - \bar{F} Q
+      52             : \f]
+      53             : 
+      54             : where for CV \f$Q\f$, a coupling constant \f${\bar{F}}\f$ is determined
+      55             : adaptively according to the FISST algorithm.
+      56             : 
+      57             : Specifically,
+      58             : \f[
+      59             : \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},
+      60             : \f]
+      61             : 
+      62             : 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).
+      63             : 
+      64             : The target for \f$w(F)=1/Z_q(F)\f$, where
+      65             : \f[
+      66             :     Z_q(F) \equiv \int d\vec{q} e^{-\beta U(\vec{q}) + \beta F Q(\vec{q})}.
+      67             : \f]
+      68             : 
+      69             : 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):
+      70             : \f[
+      71             :     \langle A \rangle_F = \frac{1}{T} \sum_t W_F(\vec{q}_t) A(\vec{q}_t).
+      72             : \f]
+      73             : 
+      74             : 
+      75             : \par Examples
+      76             : 
+      77             : 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.
+      78             : 
+      79             : \plumedfile
+      80             : UNITS LENGTH=A TIME=fs ENERGY=kcal/mol
+      81             : 
+      82             : b1: GROUP ATOMS=1
+      83             : b2: GROUP ATOMS=12
+      84             : 
+      85             : dend: DISTANCE ATOMS=b1,b2
+      86             : 
+      87             : #The conversion factor is 69.4786 pN = 1 kcal/mol/Angstrom
+      88             : 
+      89             : #0 pN to 100 pN
+      90             : 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
+      91             : 
+      92             : PRINT ARG=dend,f.dend_fbar,f.bias,f.force2 FILE=pull.colvar.txt STRIDE=1000
+      93             : \endplumedfile
+      94             : 
+      95             : 
+      96             : */
+      97             : //+ENDPLUMEDOC
+      98             : 
+      99             : 
+     100             : class FISST : public Bias {
+     101             : 
+     102             : 
+     103             : private:
+     104             :   /*We will get this and store it once, since on-the-fly changing number of CVs will be fatal*/
+     105             :   const unsigned int ncvs_;
+     106             :   std::vector<double> center_;
+     107             :   std::vector<double> current_avg_force_;
+     108             : 
+     109             :   std::vector<double> forces_;
+     110             :   std::vector<double> force_weight_;
+     111             :   std::vector<double> gauss_weight_;
+     112             :   std::vector<double> partition_estimate_;
+     113             :   std::vector<double> observable_weight_;
+     114             : 
+     115             :   std::string in_restart_name_;
+     116             :   std::string out_restart_name_;
+     117             :   std::string out_observable_name_;
+     118             :   std::string fmt_;
+     119             :   std::string initial_weight_dist_;
+     120             :   OFile out_restart_;
+     121             :   OFile out_observable_;
+     122             :   IFile in_restart_;
+     123             :   bool b_freeze_;
+     124             :   bool b_adaptive_;
+     125             :   bool b_restart_;
+     126             :   bool b_write_restart_;
+     127             :   bool b_write_observable_;
+     128             :   bool b_first_restart_sample_;
+     129             :   int period_;
+     130             :   int reset_period_;
+     131             :   int observable_freq_;
+     132             :   int n_interpolation_;
+     133             :   int n_samples_;
+     134             :   double kbt_;
+     135             :   double beta_;
+     136             :   //change min_force and max_force to vectors if going to do more than one cv
+     137             :   double max_force_;
+     138             :   double min_force_;
+     139             :   double initial_weight_rate_;
+     140             :   double threshold_;
+     141             :   Random rand_;
+     142             : 
+     143             : 
+     144             :   Value* value_force2_;
+     145             :   void readInRestart();
+     146             :   void NormalizeForceWeights();
+     147             :   /*setup output restart*/
+     148             :   void setupOutRestart();
+     149             :   void setupOutObservable();
+     150             :   /*write output restart*/
+     151             :   void writeOutRestart();
+     152             :   void writeOutObservable();
+     153             :   void update_statistics();
+     154             :   void update_bias();
+     155             :   void apply_bias();
+     156             :   void compute_observable_weight();
+     157             : 
+     158             : public:
+     159             :   explicit FISST(const ActionOptions&);
+     160             :   void calculate();
+     161             :   void update();
+     162             :   void turnOnDerivatives();
+     163             :   static void registerKeywords(Keywords& keys);
+     164             :   ~FISST();
+     165             : };
+     166             : 
+     167       10423 : PLUMED_REGISTER_ACTION(FISST,"FISST")
+     168             : 
+     169           3 : void FISST::registerKeywords(Keywords& keys) {
+     170           3 :   Bias::registerKeywords(keys);
+     171           3 :   keys.use("ARG");
+     172           6 :   keys.add("compulsory","PERIOD","Steps corresponding to the learning rate");
+     173           6 :   keys.add("optional","RESET_PERIOD","Reset the learning statistics every time this number of steps comes around.");
+     174           6 :   keys.add("compulsory","NINTERPOLATE","Number of grid points on which to do interpolation.");
+     175           6 :   keys.add("compulsory","MIN_FORCE","Minimum force (per CV) to use for sampling. Units: [Energy]/[CV]  (can be negative).");
+     176           6 :   keys.add("compulsory","MAX_FORCE","Maximum force (per CV) to use for sampling.");
+     177           6 :   keys.add("compulsory","CENTER","0","The CV value at which the applied bias energy will be zero");
+     178           6 :   keys.add("optional","KBT","The system temperature in units of KB*T. If not provided will be taken from MD code (if available)");
+     179             : 
+     180           9 :   keys.add("optional","INITIAL_WEIGHT_DIST","Starting distribution for the force weights (options: UNIFORM, EXP, GAUSS).");
+     181           9 :   keys.add("optional","INITIAL_WEIGHT_RATE","Rate of decay for exponential and gaussian distributions. W(F)~exp(-r |F|^d).");
+     182             : 
+     183           6 :   keys.add("optional","RESTART_FMT","the format that should be used to output real numbers in FISST restarts.");
+     184           6 :   keys.add("optional","OUT_RESTART","Output file for all information needed to continue FISST simulation."
+     185             :            "If you have the RESTART directive set (global or for FISST), this file will be appended to."
+     186             :            "Note that the header will be printed again if appending.");
+     187           6 :   keys.add("optional","IN_RESTART","Read this file to continue an FISST simulation. "
+     188             :            "If same as OUT_RESTART and you have not set the RESTART directive, the file will be backed-up and overwritten with new output."
+     189             :            "If you do have the RESTART flag set and it is the same name as OUT_RESTART, this file will be appended.");
+     190           6 :   keys.add("optional","OUT_OBSERVABLE","Output file putting weights needed to compute observables at different force values."
+     191             :            "If you have the RESTART directive set (global or for FISST), this file will be appended to. "
+     192             :            "Note that the header will be printed again if appending.");
+     193           6 :   keys.add("optional","OBSERVABLE_FREQ","How often to write out observable weights (default=period).");
+     194           6 :   keys.addFlag("FREEZE",false,"Fix bias weights at current level (only used for restarting).");
+     195           3 :   keys.use("RESTART");
+     196           6 :   keys.addOutputComponent("force2","default","squared value of force from the bias.");
+     197           6 :   keys.addOutputComponent("_fbar","default", "For each named CV biased, there will be a corresponding output CV_fbar storing the current linear bias prefactor.");
+     198           3 : }
+     199             : 
+     200           2 : FISST::FISST(const ActionOptions&ao):
+     201             :   PLUMED_BIAS_INIT(ao),
+     202           2 :   ncvs_(getNumberOfArguments()),
+     203           0 :   current_avg_force_(ncvs_,0.0),
+     204           2 :   center_(ncvs_,0.0),
+     205             :   //change min_force and max_force to vectors if going to do more than one cv
+     206           2 :   min_force_(0.0),
+     207           2 :   max_force_(0.0),
+     208           2 :   in_restart_name_(""),
+     209           2 :   out_restart_name_(""),
+     210           2 :   out_observable_name_(""),
+     211           2 :   fmt_("%e"),
+     212           2 :   b_freeze_(false),
+     213           2 :   b_restart_(false),
+     214           2 :   b_write_restart_(false),
+     215           2 :   b_write_observable_(false),
+     216           2 :   b_first_restart_sample_(true),
+     217           2 :   n_interpolation_(0),
+     218           2 :   n_samples_(0),
+     219           2 :   initial_weight_rate_(0),
+     220           2 :   initial_weight_dist_("UNIFORM"),
+     221           2 :   period_(0),
+     222           2 :   reset_period_(0),
+     223           2 :   observable_freq_(0),
+     224           2 :   kbt_(0.0),
+     225           6 :   value_force2_(NULL)
+     226             : {
+     227           2 :   if(ncvs_==0)
+     228           0 :     error("Must specify at least one CV with ARG");
+     229             : 
+     230             :   //temporary
+     231           2 :   if(ncvs_>1)
+     232           0 :     error("FISST only supports using one CV right now");
+     233             : 
+     234           2 :   addComponent("force2");
+     235           2 :   componentIsNotPeriodic("force2");
+     236           2 :   value_force2_ = getPntrToComponent("force2");
+     237             : 
+     238           4 :   for(unsigned int i = 0; i<ncvs_; i++) {
+     239           2 :     std::string comp = getPntrToArgument(i)->getName() + "_fbar";
+     240           2 :     addComponent(comp);
+     241           2 :     componentIsNotPeriodic(comp);
+     242             :   }
+     243             : 
+     244           2 :   parseVector("CENTER",center_);
+     245             :   //change min_force and max_force to vectors if going to do more than one cv
+     246           2 :   parse("MIN_FORCE",min_force_);
+     247           2 :   parse("MAX_FORCE",max_force_);
+     248           2 :   parse("PERIOD",period_);
+     249           2 :   parse("RESET_PERIOD",reset_period_);
+     250           2 :   parse("INITIAL_WEIGHT_DIST",initial_weight_dist_);
+     251           2 :   parse("INITIAL_WEIGHT_RATE",initial_weight_rate_);
+     252           2 :   parse("OBSERVABLE_FREQ",observable_freq_);
+     253           2 :   parse("NINTERPOLATE",n_interpolation_);
+     254           2 :   parseFlag("FREEZE",b_freeze_);
+     255           2 :   parse("KBT",kbt_);
+     256           2 :   parse("RESTART_FMT", fmt_);
+     257           2 :   fmt_ = " " + fmt_;//add space since parse strips them
+     258           2 :   parse("OUT_RESTART",out_restart_name_);
+     259           2 :   parse("OUT_OBSERVABLE",out_observable_name_);
+     260           2 :   parse("IN_RESTART",in_restart_name_);
+     261           2 :   checkRead();
+     262             : 
+     263           2 :   if(center_.size() != ncvs_)
+     264           0 :     error("Must have same number of CENTER arguments as ARG arguments");
+     265             : 
+     266           2 :   if(in_restart_name_ != "") {
+     267           0 :     b_restart_ = true;
+     268           0 :     log.printf("  reading simulation information from file: %s\n",in_restart_name_.c_str());
+     269           0 :     readInRestart();
+     270             :   } else {
+     271             : 
+     272           2 :     if(! kbt_ > 0.0)
+     273           2 :       kbt_ = plumed.getAtoms().getKbT();
+     274             : 
+     275             :     //in driver, this results in kbt of 0
+     276           2 :     if(kbt_ == 0) {
+     277           0 :       error("  Unable to determine valid kBT. "
+     278             :             "Could be because you are runnning from driver or MD didn't give temperature.\n"
+     279             :             "Consider setting temperature manually with the KBT keyword.");
+     280             :     }
+     281             : 
+     282           2 :     log.printf("  kBT = %f\n",kbt_);
+     283           2 :     log.printf("  Updating with a time scale of %i steps\n",period_);
+     284             : 
+     285           2 :     log.printf("  Using centers for CVs of:");
+     286           4 :     for(unsigned int i = 0; i< ncvs_; i++) {
+     287           2 :       log.printf(" %f ",center_[i]);
+     288             :     }
+     289           2 :     log.printf("\n");
+     290           2 :     observable_weight_.resize(n_interpolation_);
+     291          64 :     for(unsigned int i = 0; i<n_interpolation_; i++) observable_weight_[i] = 1.0;
+     292             : 
+     293           2 :     forces_.resize(n_interpolation_);
+     294           2 :     force_weight_.resize(n_interpolation_);
+     295             :     //using code from the MIST project
+     296           2 :     gauss_weight_.resize(n_interpolation_);
+     297           2 :     legendre_compute_glr(n_interpolation_, &forces_[0], &gauss_weight_[0]);
+     298           2 :     rescale(min_force_, max_force_, n_interpolation_, &forces_[0], &gauss_weight_[0]);
+     299             : 
+     300           2 :     log.printf("Using weight distribution %s with rate %f\n",initial_weight_dist_.c_str(),initial_weight_rate_);
+     301           2 :     if(initial_weight_dist_ == "UNIFORM" ) {
+     302          32 :       for(unsigned int i = 0; i<n_interpolation_; i++) force_weight_[i] = 1.0;
+     303             :     }
+     304           1 :     else if (initial_weight_dist_ == "EXP" ) {
+     305          32 :       for(unsigned int i = 0; i<n_interpolation_; i++) force_weight_[i] = exp(-fabs(forces_[i])*initial_weight_rate_);
+     306             :     }
+     307           0 :     else if (initial_weight_dist_ == "GAUSS" ) {
+     308           0 :       for(unsigned int i = 0; i<n_interpolation_; i++) force_weight_[i] = exp(-pow(forces_[i],2)*initial_weight_rate_);
+     309             :     }
+     310             :     else {
+     311           0 :       error("  Specified weight distribution is not from the allowed list.");
+     312             : 
+     313             :     }
+     314             : 
+     315           2 :     partition_estimate_.resize(n_interpolation_);
+     316           2 :     NormalizeForceWeights();
+     317             :     double sum = 0.0;
+     318          64 :     for(unsigned int i = 0; i<n_interpolation_; i++) {
+     319             :       //setting partition estimate as 1/w_i
+     320          62 :       partition_estimate_[i] = 1/force_weight_[i];
+     321          62 :       log.printf("force/gauss weight/force_weight: %i %f %f %f\n",i,forces_[i],gauss_weight_[i],force_weight_[i]);
+     322          62 :       sum+=gauss_weight_[i]*force_weight_[i];
+     323             :     }
+     324           2 :     log.printf("--Sum_i w_i g_i: %f\n",sum);
+     325             : 
+     326             :   }
+     327             : 
+     328             :   //set inverse temperature
+     329           2 :   beta_ = 1/kbt_;
+     330             : 
+     331           2 :   if(b_freeze_ && b_restart_) {
+     332           0 :     log.printf("  freezing weights read in from the restart file\n");
+     333             :   }
+     334             : 
+     335           2 :   if(out_restart_name_.length()>0) {
+     336           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());
+     337           2 :     b_write_restart_ = true;
+     338           2 :     setupOutRestart();
+     339             :   }
+     340           2 :   if(out_observable_name_.length()>0) {
+     341           2 :     if(observable_freq_==0) observable_freq_ = period_;
+     342           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());
+     343           2 :     b_write_observable_ = true;
+     344           2 :     setupOutObservable();
+     345             :   }
+     346             : 
+     347             :   //add citation later:
+     348             :   //log<<"  Bibliography "<<plumed.cite("")<<"\n";
+     349           2 : }
+     350             : 
+     351          12 : void FISST::NormalizeForceWeights() {
+     352             :   double denom = 0.0;
+     353             : 
+     354         384 :   for(unsigned i=0; i<n_interpolation_; i++)
+     355         372 :     denom += gauss_weight_[i] * force_weight_[i];
+     356             : 
+     357         384 :   for(unsigned i=0; i<n_interpolation_; i++)
+     358         372 :     force_weight_[i] /= denom;
+     359          12 : }
+     360             : 
+     361           0 : void FISST::readInRestart() {
+     362           0 :   in_restart_.open(in_restart_name_);
+     363             : 
+     364           0 :   if(in_restart_.FieldExist("kbt")) {
+     365           0 :     in_restart_.scanField("kbt",kbt_);
+     366           0 :   } else { error("No field 'kbt' in restart file"); }
+     367           0 :   log.printf("  with kBT = %f\n",kbt_);
+     368             : 
+     369           0 :   if(in_restart_.FieldExist("period")) {
+     370           0 :     in_restart_.scanField("period",period_);
+     371           0 :   } else { error("No field 'period' in restart file"); }
+     372           0 :   log.printf("  Updating every %i steps\n",period_);
+     373             : 
+     374             : //this one can be optional
+     375           0 :   if(in_restart_.FieldExist("reset_period")) {
+     376           0 :     in_restart_.scanField("reset_period",reset_period_);
+     377             :   }
+     378           0 :   log.printf("  Resetting statistics every %i steps\n",reset_period_);
+     379             : 
+     380           0 :   if(in_restart_.FieldExist("n_interpolation")) {
+     381           0 :     in_restart_.scanField("n_interpolation",n_interpolation_);
+     382           0 :   } else { error("No field 'n_interpolation' in restart file"); }
+     383             : 
+     384           0 :   if(in_restart_.FieldExist("min_force")) {
+     385           0 :     in_restart_.scanField("min_force",min_force_);
+     386           0 :   } else { error("No field 'min_force' in restart file"); }
+     387           0 :   if(in_restart_.FieldExist("max_force")) {
+     388           0 :     in_restart_.scanField("max_force",max_force_);
+     389           0 :   } else { error("No field 'max_force' in restart file"); }
+     390           0 :   log.printf("  with forces from min_force=%e to max_force=%e over %i bins\n",min_force_,max_force_,n_interpolation_);
+     391             : 
+     392             :   unsigned int N = 0;
+     393             :   std::string cv_name;
+     394             :   double tmp, time;
+     395             : 
+     396           0 :   while(in_restart_.scanField("time",time)) {
+     397           0 :     in_restart_.scanField("nsamples",n_samples_);
+     398             : 
+     399           0 :     observable_weight_.resize(n_interpolation_);
+     400           0 :     partition_estimate_.resize(n_interpolation_);
+     401           0 :     force_weight_.resize(n_interpolation_);
+     402           0 :     gauss_weight_.resize(n_interpolation_);
+     403           0 :     forces_.resize(n_interpolation_);
+     404             : 
+     405           0 :     for(unsigned int i = 0; i<ncvs_; ++i) {
+     406             :       cv_name = getPntrToArgument(i)->getName();
+     407           0 :       in_restart_.scanField(cv_name,tmp);
+     408           0 :       for(unsigned int j =0; j<n_interpolation_; ++j) {
+     409           0 :         in_restart_.scanField(cv_name + "_f"+std::to_string(j),forces_[j]);
+     410           0 :         in_restart_.scanField(cv_name + "_g"+std::to_string(j),gauss_weight_[j]);
+     411           0 :         in_restart_.scanField(cv_name + "_w"+std::to_string(j),force_weight_[j]);
+     412           0 :         in_restart_.scanField(cv_name + "_z"+std::to_string(j),partition_estimate_[j]);
+     413             :       }
+     414             :     }
+     415             :     N++;
+     416             : 
+     417           0 :     in_restart_.scanField();
+     418             :   }
+     419             : 
+     420             :   double sum = 0.0;
+     421           0 :   for(unsigned int j =0; j<n_interpolation_; ++j) {
+     422             :     //clear observable weight, which will be set later
+     423           0 :     observable_weight_[j] = 1.0;
+     424             : 
+     425             :     //setting partition estimate as 1/w_i
+     426           0 :     log.printf("force/gauss weight/force_weight: %i %e %e %e\n",j,forces_[j],gauss_weight_[j],force_weight_[j]);
+     427           0 :     sum+=gauss_weight_[j]*force_weight_[j];
+     428             :   }
+     429           0 :   log.printf("--Sum_i w_i g_i: %f\n",sum);
+     430             : 
+     431           0 :   in_restart_.close();
+     432           0 : }
+     433             : 
+     434           2 : void FISST::setupOutObservable() {
+     435           2 :   out_observable_.link(*this);
+     436           2 :   out_observable_.fmtField(fmt_);
+     437           2 :   out_observable_.open(out_observable_name_);
+     438             :   out_observable_.setHeavyFlush();
+     439             : 
+     440           4 :   out_observable_.addConstantField("kbt").printField("kbt",kbt_);
+     441           4 :   out_observable_.addConstantField("n_interpolation").printField("n_interpolation",n_interpolation_);
+     442           4 :   out_observable_.addConstantField("period").printField("period",period_);
+     443           4 :   out_observable_.addConstantField("min_force").printField("min_force",min_force_);
+     444           4 :   out_observable_.addConstantField("max_force").printField("max_force",max_force_);
+     445           2 : }
+     446             : 
+     447           2 : void FISST::setupOutRestart() {
+     448           2 :   out_restart_.link(*this);
+     449           2 :   out_restart_.fmtField(fmt_);
+     450           2 :   out_restart_.open(out_restart_name_);
+     451             :   out_restart_.setHeavyFlush();
+     452             : 
+     453           4 :   out_restart_.addConstantField("kbt").printField("kbt",kbt_);
+     454           4 :   out_restart_.addConstantField("n_interpolation").printField("n_interpolation",n_interpolation_);
+     455           4 :   out_restart_.addConstantField("period").printField("period",period_);
+     456           2 :   if(reset_period_>0) out_restart_.addConstantField("reset_period").printField("reset_period",reset_period_);
+     457           4 :   out_restart_.addConstantField("min_force").printField("min_force",min_force_);
+     458           4 :   out_restart_.addConstantField("max_force").printField("max_force",max_force_);
+     459           2 : }
+     460             : 
+     461          10 : void FISST::writeOutRestart() {
+     462             :   std::string cv_name;
+     463          10 :   out_restart_.printField("time",getTimeStep()*getStep());
+     464          10 :   out_restart_.printField("nsamples",n_samples_);
+     465             : 
+     466          20 :   for(unsigned int i = 0; i<ncvs_; ++i) {
+     467             :     cv_name = getPntrToArgument(i)->getName();
+     468          10 :     double Q_i = difference(i, center_[i], getArgument(i));
+     469          10 :     out_restart_.printField(cv_name,Q_i);
+     470         320 :     for(int j = 0; j < n_interpolation_; j++ ) {
+     471             : //have to update this for multiple cvs
+     472         620 :       out_restart_.printField(cv_name + "_f"+std::to_string(j),forces_[j]);
+     473         620 :       out_restart_.printField(cv_name + "_g"+std::to_string(j),gauss_weight_[j]);
+     474         620 :       out_restart_.printField(cv_name + "_w"+std::to_string(j),force_weight_[j]);
+     475         620 :       out_restart_.printField(cv_name + "_z"+std::to_string(j),partition_estimate_[j]);
+     476             :     }
+     477             :   }
+     478          10 :   out_restart_.printField();
+     479          10 : }
+     480             : 
+     481          10 : void FISST::writeOutObservable() {
+     482             :   std::string cv_name;
+     483          10 :   out_observable_.printField("time",getTimeStep()*getStep());
+     484          10 :   out_observable_.printField("nsamples",n_samples_);
+     485             : 
+     486          20 :   for(unsigned int i = 0; i<ncvs_; ++i) {
+     487             :     cv_name = getPntrToArgument(i)->getName();
+     488          10 :     double Q_i = difference(i, center_[i], getArgument(i));
+     489          10 :     out_observable_.printField(cv_name,Q_i);
+     490          10 :     out_observable_.printField(cv_name + "_fbar",current_avg_force_[i]);
+     491         320 :     for(int j = 0; j < n_interpolation_; j++ ) {
+     492             : //have to update this for multiple cvs
+     493         620 :       out_observable_.printField(cv_name + "_f"+std::to_string(j),forces_[j]);
+     494         620 :       out_observable_.printField(cv_name + "_ow"+std::to_string(j),observable_weight_[j]);
+     495             :     }
+     496             :   }
+     497          10 :   out_observable_.printField();
+     498          10 : }
+     499             : 
+     500             : 
+     501          10 : void FISST::calculate() {
+     502          10 :   if(getStep() == 0 ) {
+     503           2 :     if(b_write_restart_) writeOutRestart();
+     504           2 :     if(b_write_observable_) writeOutObservable();
+     505             :   }
+     506             : 
+     507          10 :   if(! b_freeze_) {
+     508          10 :     if(b_restart_ && b_first_restart_sample_) {
+     509             :       //dont' update statistics if restarting and first sample
+     510           0 :       b_first_restart_sample_ = false;
+     511             :     }
+     512             :     else {
+     513          10 :       update_statistics();
+     514             :     }
+     515             :   }
+     516          10 :   update_bias();
+     517          10 :   apply_bias();
+     518             : 
+     519             :   //check about writing restart file
+     520          10 :   if(getStep()>0 && getStep()%period_==0) {
+     521           8 :     if(b_write_restart_) writeOutRestart();
+     522             :   }
+     523          10 :   if(getStep()>0 && getStep()%observable_freq_==0) {
+     524           8 :     if(b_write_observable_) {
+     525           8 :       compute_observable_weight();
+     526           8 :       writeOutObservable();
+     527             :     }
+     528             :   }
+     529          10 : }
+     530             : 
+     531             : 
+     532          10 : void FISST::apply_bias() {
+     533             :   //Compute linear force as in "restraint"
+     534             :   double ene = 0, totf2 = 0, cv, m, f;
+     535             : 
+     536          20 :   for(unsigned int i = 0; i < ncvs_; ++i) {
+     537          10 :     cv = difference(i, center_[i], getArgument(i));
+     538          10 :     double fbar = current_avg_force_[i];
+     539          10 :     ene -= fbar*cv;
+     540             :     setOutputForce(i,fbar);
+     541          10 :     totf2 += fbar*fbar;
+     542             : 
+     543          10 :     std::string fbar_name_ = getPntrToArgument(i)->getName() + "_fbar";
+     544          10 :     Value* fbar_ = getPntrToComponent(fbar_name_);
+     545             :     fbar_->set(fbar);
+     546             :   };
+     547             : 
+     548             :   setBias(ene);
+     549          10 :   value_force2_->set(totf2);
+     550             :   //log.flush();
+     551          10 : }
+     552             : 
+     553          10 : void FISST::update_statistics()  {
+     554             : //get stride is for multiple time stepping
+     555          10 :   double dt=getTimeStep()*getStride();
+     556          10 :   double h = dt/(period_*getTimeStep());
+     557             :   double fbar_denum_integral = 0.0;
+     558             : 
+     559          10 :   int step = getStep();
+     560          10 :   if(reset_period_>0 && step>0 && step%reset_period_==0) {
+     561           0 :     n_samples_=1;
+     562             :   }
+     563             :   else {
+     564          10 :     n_samples_++;
+     565             :   }
+     566          10 :   double d_n_samples = (double)n_samples_;
+     567             : 
+     568          20 :   for(unsigned int i = 0; i < ncvs_; ++i) {
+     569          10 :     double Q_i = difference(i, center_[i], getArgument(i));
+     570         320 :     for(unsigned int j=0; j<n_interpolation_; j++)
+     571             :     {
+     572             :       //if multiple cvs, these need to be updated to have 2 columns
+     573         310 :       double f_j = forces_[j];
+     574         310 :       double w_j = force_weight_[j];
+     575         310 :       double g_j = gauss_weight_[j];
+     576             : 
+     577         310 :       fbar_denum_integral += g_j * w_j * exp(beta_*f_j * Q_i);
+     578             :     }
+     579             : 
+     580         320 :     for(unsigned int j=0; j<n_interpolation_; j++)
+     581             :     {
+     582         310 :       double f_j = forces_[j];
+     583         310 :       double sample_weight = exp(beta_*f_j * Q_i) / fbar_denum_integral;
+     584             : 
+     585         310 :       partition_estimate_[j] = sample_weight/d_n_samples + partition_estimate_[j]*(d_n_samples-1)/(d_n_samples);
+     586             : 
+     587         310 :       double w_jn = force_weight_[j];
+     588         310 :       double z_jn = partition_estimate_[j];
+     589             : 
+     590         310 :       double w_jp1 = (1.0 - h) * w_jn + h / z_jn;
+     591         310 :       force_weight_[j] = w_jp1;
+     592             :     }
+     593             :   }
+     594             : 
+     595             :   // make sure that the weights are normalised
+     596          10 :   NormalizeForceWeights();
+     597          10 : }
+     598             : 
+     599             : 
+     600          10 : void FISST::update_bias()
+     601             : {
+     602          20 :   for(unsigned int i = 0; i < ncvs_; ++i) {
+     603          10 :     double Q_i = difference(i, center_[i], getArgument(i));
+     604             :     double fbar_num_integral = 0.0;
+     605             :     double fbar_denum_integral = 0.0;
+     606             : 
+     607         320 :     for(unsigned int j=0; j<n_interpolation_; j++ ) {
+     608         310 :       double f_j = forces_[j];
+     609         310 :       double w_j = force_weight_[j];
+     610         310 :       double g_j = gauss_weight_[j];
+     611             : 
+     612         310 :       fbar_num_integral += g_j * f_j * w_j * exp(beta_*f_j*Q_i);
+     613         310 :       fbar_denum_integral += g_j * w_j * exp(beta_*f_j*Q_i);
+     614             :     }
+     615             : 
+     616          10 :     current_avg_force_[i] = fbar_num_integral/fbar_denum_integral;
+     617             :   }
+     618          10 : }
+     619             : 
+     620           8 : void FISST::compute_observable_weight() {
+     621           8 :   double obs_num = (max_force_ - min_force_);
+     622             : 
+     623          16 :   for(unsigned int i = 0; i < ncvs_; ++i) {
+     624           8 :     double Q_i = difference(i, center_[i], getArgument(i));
+     625             : 
+     626         256 :     for(unsigned int j=0; j<n_interpolation_; j++ ) {
+     627         248 :       double z_j = partition_estimate_[j];
+     628         248 :       double f_j = forces_[j];
+     629             :       double denum_integral = 0.0;
+     630             : 
+     631        7936 :       for( unsigned int k=0; k<n_interpolation_; k++ ) {
+     632        7688 :         double f_k = forces_[k];
+     633        7688 :         double w_k = force_weight_[k];
+     634        7688 :         double g_k = gauss_weight_[k];
+     635             : 
+     636        7688 :         denum_integral += g_k * w_k * exp(beta_*(f_k-f_j)*Q_i);
+     637             :       }
+     638         248 :       observable_weight_[j] = obs_num/(denum_integral*z_j);
+     639             :     }
+     640             :   }
+     641           8 : }
+     642             : 
+     643             : 
+     644             : 
+     645          10 : void FISST::update() {
+     646             :   //pass
+     647          10 : }
+     648             : 
+     649           4 : FISST::~FISST() {
+     650           2 :   out_restart_.close();
+     651           2 :   out_observable_.close();
+     652           6 : }
+     653             : 
+     654           0 : void FISST::turnOnDerivatives() {
+     655             :   // do nothing
+     656             :   // this is to avoid errors triggered when a bias is used as a CV
+     657             :   // (This is done in ExtendedLagrangian.cpp)
+     658           0 : }
+     659             : 
+     660             : 
+     661             : }
+     662             : }//close the 2 namespaces
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/fisst/index-sort-f.html b/coverage/fisst/index-sort-f.html new file mode 100644 index 0000000000..e020f342bf --- /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-06-10 08:19:14Functions:242982.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FISST.cpp +
80.2%80.2%
+
80.2 %247 / 30881.8 %18 / 22
legendre_rule_fast.cpp +
77.4%77.4%
+
77.4 %72 / 9385.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/fisst/index-sort-l.html b/coverage/fisst/index-sort-l.html new file mode 100644 index 0000000000..8ee5034550 --- /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-06-10 08:19:14Functions:242982.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 / 30881.8 %18 / 22
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/fisst/index.html b/coverage/fisst/index.html new file mode 100644 index 0000000000..e92382d11e --- /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-06-10 08:19:14Functions:242982.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FISST.cpp +
80.2%80.2%
+
80.2 %247 / 30881.8 %18 / 22
legendre_rule_fast.cpp +
77.4%77.4%
+
77.4 %72 / 9385.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ea958de6c9 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..993b242646 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..3f76960966 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..7b858eafe1 --- /dev/null +++ b/coverage/function/Combine.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:444793.6 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7CombineC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe906createERKNS_13ActionOptionsE137
_ZN4PLMD8function7CombineC1ERKNS_13ActionOptionsE137
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE138
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe90C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe90D2Ev3473
_ZN4PLMD8function7Combine9calculateEv7887
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Combine.cpp.func.html b/coverage/function/Combine.cpp.func.html new file mode 100644 index 0000000000..fdcbf9ba0e --- /dev/null +++ b/coverage/function/Combine.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:444793.6 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe906createERKNS_13ActionOptionsE137
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe90C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe90D2Ev3473
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE138
_ZN4PLMD8function7Combine9calculateEv7887
_ZN4PLMD8function7CombineC1ERKNS_13ActionOptionsE137
_ZN4PLMD8function7CombineC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Combine.cpp.gcov.html b/coverage/function/Combine.cpp.gcov.html new file mode 100644 index 0000000000..6c2e725f8c --- /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:444793.6 %
Date:2024-06-10 08:19:14Functions: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 "Function.h"
+      23             : #include "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       10690 : PLUMED_REGISTER_ACTION(Combine,"COMBINE")
+      91             : 
+      92         138 : void Combine::registerKeywords(Keywords& keys) {
+      93         138 :   Function::registerKeywords(keys);
+      94         276 :   keys.use("ARG"); keys.use("PERIODIC");
+      95         276 :   keys.add("compulsory","COEFFICIENTS","1.0","the coefficients of the arguments in your function");
+      96         276 :   keys.add("compulsory","PARAMETERS","0.0","the parameters of the arguments in your function");
+      97         276 :   keys.add("compulsory","POWERS","1.0","the powers to which you are raising each of the arguments in your function");
+      98         276 :   keys.addFlag("NORMALIZE",false,"normalize all the coefficients so that in total they are equal to one");
+      99         138 : }
+     100             : 
+     101         137 : Combine::Combine(const ActionOptions&ao):
+     102             :   Action(ao),
+     103             :   Function(ao),
+     104         137 :   normalize(false),
+     105         277 :   coefficients(getNumberOfArguments(),1.0),
+     106         140 :   parameters(getNumberOfArguments(),0.0),
+     107         277 :   powers(getNumberOfArguments(),1.0)
+     108             : {
+     109         273 :   parseVector("COEFFICIENTS",coefficients);
+     110         136 :   if(coefficients.size()!=static_cast<unsigned>(getNumberOfArguments()))
+     111           0 :     error("Size of COEFFICIENTS array should be the same as number for arguments");
+     112             : 
+     113         271 :   parseVector("PARAMETERS",parameters);
+     114         135 :   if(parameters.size()!=static_cast<unsigned>(getNumberOfArguments()))
+     115           0 :     error("Size of PARAMETERS array should be the same as number for arguments");
+     116             : 
+     117         269 :   parseVector("POWERS",powers);
+     118         134 :   if(powers.size()!=static_cast<unsigned>(getNumberOfArguments()))
+     119           0 :     error("Size of POWERS array should be the same as number for arguments");
+     120             : 
+     121         137 :   parseFlag("NORMALIZE",normalize);
+     122             : 
+     123         134 :   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         134 :   addValueWithDerivatives();
+     130         134 :   checkRead();
+     131             : 
+     132         134 :   log.printf("  with coefficients:");
+     133         404 :   for(unsigned i=0; i<coefficients.size(); i++) log.printf(" %f",coefficients[i]);
+     134         134 :   log.printf("\n");
+     135         134 :   log.printf("  with parameters:");
+     136         404 :   for(unsigned i=0; i<parameters.size(); i++) log.printf(" %f",parameters[i]);
+     137         134 :   log.printf("\n");
+     138         134 :   log.printf("  and powers:");
+     139         404 :   for(unsigned i=0; i<powers.size(); i++) log.printf(" %f",powers[i]);
+     140         134 :   log.printf("\n");
+     141         140 : }
+     142             : 
+     143        7887 : void Combine::calculate() {
+     144        7887 :   double combine=0.0;
+     145       20242 :   for(unsigned i=0; i<coefficients.size(); ++i) {
+     146       12355 :     double cv = (getArgument(i)-parameters[i]);
+     147       12355 :     combine+=coefficients[i]*std::pow(cv,powers[i]);
+     148       12355 :     setDerivative(i,coefficients[i]*powers[i]*std::pow(cv,powers[i]-1.0));
+     149             :   };
+     150        7887 :   setValue(combine);
+     151        7887 : }
+     152             : 
+     153             : }
+     154             : }
+     155             : 
+     156             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..8bca576ea6 --- /dev/null +++ b/coverage/function/Custom.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:586195.1 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6CustomC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe1796createERKNS_13ActionOptionsE46
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe2096createERKNS_13ActionOptionsE387
_ZN4PLMD8function6CustomC1ERKNS_13ActionOptionsE433
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE435
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe179C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe179D2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe209C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe209D2Ev3473
_ZN4PLMD8function6Custom9calculateEv39143
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Custom.cpp.func.html b/coverage/function/Custom.cpp.func.html new file mode 100644 index 0000000000..d8b3990568 --- /dev/null +++ b/coverage/function/Custom.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:586195.1 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe1796createERKNS_13ActionOptionsE46
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe179C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe179D2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe2096createERKNS_13ActionOptionsE387
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe209C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe209D2Ev3473
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE435
_ZN4PLMD8function6Custom9calculateEv39143
_ZN4PLMD8function6CustomC1ERKNS_13ActionOptionsE433
_ZN4PLMD8function6CustomC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Custom.cpp.gcov.html b/coverage/function/Custom.cpp.gcov.html new file mode 100644 index 0000000000..3dcec0fec7 --- /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:586195.1 %
Date:2024-06-10 08:19:14Functions:91090.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 "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       10511 : 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       11193 : PLUMED_REGISTER_ACTION(Custom,"MATHEVAL")
+     210             : 
+     211         435 : void Custom::registerKeywords(Keywords& keys) {
+     212         435 :   Function::registerKeywords(keys);
+     213         870 :   keys.use("ARG"); keys.use("PERIODIC");
+     214         870 :   keys.add("compulsory","FUNC","the function you wish to evaluate");
+     215         870 :   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         435 : }
+     217             : 
+     218         433 : Custom::Custom(const ActionOptions&ao):
+     219             :   Action(ao),
+     220             :   Function(ao),
+     221         433 :   expression_deriv(getNumberOfArguments()),
+     222         433 :   values(getNumberOfArguments()),
+     223         433 :   names(getNumberOfArguments()),
+     224         433 :   lepton_ref(getNumberOfArguments(),nullptr),
+     225        1299 :   lepton_ref_deriv(getNumberOfArguments()*getNumberOfArguments(),nullptr)
+     226             : {
+     227         866 :   parseVector("VAR",var);
+     228         433 :   if(var.size()==0) {
+     229         420 :     var.resize(getNumberOfArguments());
+     230         420 :     if(getNumberOfArguments()>3)
+     231           0 :       error("Using more than 3 arguments you should explicitly write their names with VAR");
+     232         420 :     if(var.size()>0) var[0]="x";
+     233         420 :     if(var.size()>1) var[1]="y";
+     234         420 :     if(var.size()>2) var[2]="z";
+     235             :   }
+     236         433 :   if(var.size()!=getNumberOfArguments())
+     237           0 :     error("Size of VAR array should be the same as number of arguments");
+     238         433 :   parse("FUNC",func);
+     239         433 :   addValueWithDerivatives();
+     240         433 :   checkRead();
+     241             : 
+     242         433 :   log.printf("  with function : %s\n",func.c_str());
+     243         433 :   log.printf("  with variables :");
+     244         966 :   for(unsigned i=0; i<var.size(); i++) log.printf(" %s",var[i].c_str());
+     245         433 :   log.printf("\n");
+     246             : 
+     247         433 :   lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(lepton::Constants());
+     248         433 :   log<<"  function as parsed by lepton: "<<pe<<"\n";
+     249         433 :   expression=pe.createCompiledExpression();
+     250         940 :   for(auto &p: expression.getVariables()) {
+     251         507 :     if(std::find(var.begin(),var.end(),p)==var.end()) {
+     252           0 :       error("variable " + p + " is not defined");
+     253             :     }
+     254             :   }
+     255         433 :   log<<"  derivatives as computed by lepton:\n";
+     256         966 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     257        1066 :     lepton::ParsedExpression pe=lepton::Parser::parse(func).differentiate(var[i]).optimize(lepton::Constants());
+     258         533 :     log<<"    "<<pe<<"\n";
+     259         533 :     expression_deriv[i]=pe.createCompiledExpression();
+     260             :   }
+     261             : 
+     262         966 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     263             :     try {
+     264         533 :       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         966 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     271        1524 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     272             :       try {
+     273         991 :         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         433 : }
+     281             : 
+     282       39143 : void Custom::calculate() {
+     283       78927 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     284       39784 :     if(lepton_ref[i]) *lepton_ref[i]=getArgument(i);
+     285             :   }
+     286       39143 :   setValue(expression.evaluate());
+     287       78927 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     288       82326 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     289       42542 :       if(lepton_ref_deriv[i*getNumberOfArguments()+j]) *lepton_ref_deriv[i*getNumberOfArguments()+j]=getArgument(j);
+     290             :     }
+     291       39784 :     setDerivative(i,expression_deriv[i].evaluate());
+     292             :   }
+     293       39143 : }
+     294             : 
+     295             : }
+     296             : }
+     297             : 
+     298             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..2ecf34f7cf --- /dev/null +++ b/coverage/function/Ensemble.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:8213063.1 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe716createERKNS_13ActionOptionsE27
_ZN4PLMD8function8EnsembleC1ERKNS_13ActionOptionsE27
_ZN4PLMD8function8Ensemble16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD8function8Ensemble9calculateEv125
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe71C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe71D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Ensemble.cpp.func.html b/coverage/function/Ensemble.cpp.func.html new file mode 100644 index 0000000000..a5c1ff813b --- /dev/null +++ b/coverage/function/Ensemble.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:8213063.1 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe716createERKNS_13ActionOptionsE27
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe71C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe71D2Ev3473
_ZN4PLMD8function8Ensemble16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD8function8Ensemble9calculateEv125
_ZN4PLMD8function8EnsembleC1ERKNS_13ActionOptionsE27
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Ensemble.cpp.gcov.html b/coverage/function/Ensemble.cpp.gcov.html new file mode 100644 index 0000000000..ce9fe6c027 --- /dev/null +++ b/coverage/function/Ensemble.cpp.gcov.html @@ -0,0 +1,343 @@ + + + + + + + + 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:8213063.1 %
Date:2024-06-10 08:19:14Functions: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 "Function.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/Atoms.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       10473 : PLUMED_REGISTER_ACTION(Ensemble,"ENSEMBLE")
+      72             : 
+      73          28 : void Ensemble::registerKeywords(Keywords& keys) {
+      74          28 :   Function::registerKeywords(keys);
+      75          28 :   keys.use("ARG");
+      76          56 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the latest ARG as energy");
+      77          56 :   keys.addFlag("CENTRAL",false,"calculate a central moment instead of a standard moment");
+      78          56 :   keys.add("optional","TEMP","the system temperature - this is only needed if you are reweighting");
+      79          56 :   keys.add("optional","MOMENT","the moment you want to calculate in alternative to the mean or the variance");
+      80          56 :   keys.add("optional","POWER","the power of the mean (and moment)");
+      81          28 :   ActionWithValue::useCustomisableComponents(keys);
+      82          28 : }
+      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 :   double temp=0.0;
+      97          27 :   parse("TEMP",temp);
+      98          27 :   if(do_reweight) {
+      99          12 :     if(temp>0.0) kbt=plumed.getAtoms().getKBoltzmann()*temp;
+     100           0 :     else kbt=plumed.getAtoms().getKbT();
+     101          12 :     if(kbt==0.0) error("Unless the MD engine passes the temperature to plumed, with REWEIGHT you must specify TEMP");
+     102             :   }
+     103             : 
+     104          27 :   parse("MOMENT",moment);
+     105          27 :   if(moment==1) error("MOMENT can be any number but for 0 and 1");
+     106          27 :   if(moment!=0) do_moments=true;
+     107          27 :   parseFlag("CENTRAL", do_central);
+     108          27 :   if(!do_moments&&do_central) error("To calculate a CENTRAL moment you need to define for which MOMENT");
+     109             : 
+     110          27 :   parse("POWER",power);
+     111          27 :   if(power==1) error("POWER can be any number but for 0 and 1");
+     112          27 :   if(power!=0) do_powers=true;
+     113             : 
+     114          27 :   checkRead();
+     115             : 
+     116          27 :   master = (comm.Get_rank()==0);
+     117          27 :   ens_dim=0;
+     118          27 :   my_repl=0;
+     119          27 :   if(master) {
+     120          17 :     ens_dim=multi_sim_comm.Get_size();
+     121          17 :     my_repl=multi_sim_comm.Get_rank();
+     122             :   }
+     123          27 :   comm.Bcast(ens_dim,0);
+     124          27 :   comm.Bcast(my_repl,0);
+     125          27 :   if(ens_dim<2) log.printf("WARNING: ENSEMBLE with one replica is not doing any averaging!\n");
+     126             : 
+     127             :   // prepare output components, the number depending on reweighing or not
+     128          27 :   narg = getNumberOfArguments();
+     129          27 :   if(do_reweight) narg--;
+     130             : 
+     131             :   // these are the averages
+     132        3044 :   for(unsigned i=0; i<narg; i++) {
+     133        3017 :     std::string s=getPntrToArgument(i)->getName();
+     134        3017 :     addComponentWithDerivatives(s);
+     135        3017 :     getPntrToComponent(i)->setNotPeriodic();
+     136             :   }
+     137             :   // these are the moments
+     138          27 :   if(do_moments) {
+     139           0 :     for(unsigned i=0; i<narg; i++) {
+     140           0 :       std::string s=getPntrToArgument(i)->getName()+"_m";
+     141           0 :       addComponentWithDerivatives(s);
+     142           0 :       getPntrToComponent(i+narg)->setNotPeriodic();
+     143             :     }
+     144             :   }
+     145             : 
+     146          27 :   log.printf("  averaging over %u replicas.\n", ens_dim);
+     147          27 :   if(do_reweight) log.printf("  doing simple REWEIGHT using the latest ARGUMENT as energy.\n");
+     148          27 :   if(do_moments&&!do_central)  log.printf("  calculating also the %lf standard moment\n", moment);
+     149          27 :   if(do_moments&&do_central)   log.printf("  calculating also the %lf central moment\n", moment);
+     150          27 :   if(do_powers)                log.printf("  calculating the %lf power of the mean (and moment)\n", power);
+     151          27 : }
+     152             : 
+     153         125 : void Ensemble::calculate() {
+     154             :   double norm = 0.0;
+     155         125 :   double fact = 0.0;
+     156             : 
+     157             :   // calculate the weights either from BIAS
+     158         125 :   if(do_reweight) {
+     159             :     std::vector<double> bias;
+     160           0 :     bias.resize(ens_dim);
+     161           0 :     if(master) {
+     162           0 :       bias[my_repl] = getArgument(narg);
+     163           0 :       if(ens_dim>1) multi_sim_comm.Sum(&bias[0], ens_dim);
+     164             :     }
+     165           0 :     comm.Sum(&bias[0], ens_dim);
+     166           0 :     const double maxbias = *(std::max_element(bias.begin(), bias.end()));
+     167           0 :     for(unsigned i=0; i<ens_dim; ++i) {
+     168           0 :       bias[i] = exp((bias[i]-maxbias)/kbt);
+     169           0 :       norm += bias[i];
+     170             :     }
+     171           0 :     fact = bias[my_repl]/norm;
+     172             :     // or arithmetic ones
+     173             :   } else {
+     174         125 :     norm = static_cast<double>(ens_dim);
+     175         125 :     fact = 1.0/norm;
+     176             :   }
+     177             : 
+     178         125 :   const double fact_kbt = fact/kbt;
+     179             : 
+     180         125 :   std::vector<double> mean(narg);
+     181         125 :   std::vector<double> dmean(narg,fact);
+     182             :   // calculate the mean
+     183         125 :   if(master) {
+     184        2106 :     for(unsigned i=0; i<narg; ++i) mean[i] = fact*getArgument(i);
+     185          99 :     if(ens_dim>1) multi_sim_comm.Sum(&mean[0], narg);
+     186             :   }
+     187         125 :   comm.Sum(&mean[0], narg);
+     188             : 
+     189             :   std::vector<double> v_moment, dv_moment;
+     190             :   // calculate other moments
+     191         125 :   if(do_moments) {
+     192           0 :     v_moment.resize(narg);
+     193           0 :     dv_moment.resize(narg);
+     194             :     // standard moment
+     195           0 :     if(!do_central) {
+     196           0 :       if(master) {
+     197           0 :         for(unsigned i=0; i<narg; ++i) {
+     198           0 :           const double tmp = fact*std::pow(getArgument(i),moment-1);
+     199           0 :           v_moment[i]      = tmp*getArgument(i);
+     200           0 :           dv_moment[i]     = moment*tmp;
+     201             :         }
+     202           0 :         if(ens_dim>1) multi_sim_comm.Sum(&v_moment[0], narg);
+     203             :       } else {
+     204           0 :         for(unsigned i=0; i<narg; ++i) {
+     205           0 :           const double tmp = fact*std::pow(getArgument(i),moment-1);
+     206           0 :           dv_moment[i]     = moment*tmp;
+     207             :         }
+     208             :       }
+     209             :       // central moment
+     210             :     } else {
+     211           0 :       if(master) {
+     212           0 :         for(unsigned i=0; i<narg; ++i) {
+     213           0 :           const double tmp = std::pow(getArgument(i)-mean[i],moment-1);
+     214           0 :           v_moment[i]      = fact*tmp*(getArgument(i)-mean[i]);
+     215           0 :           dv_moment[i]     = moment*tmp*(fact-fact/norm);
+     216             :         }
+     217           0 :         if(ens_dim>1) multi_sim_comm.Sum(&v_moment[0], narg);
+     218             :       } else {
+     219           0 :         for(unsigned i=0; i<narg; ++i) {
+     220           0 :           const double tmp = std::pow(getArgument(i)-mean[i],moment-1);
+     221           0 :           dv_moment[i]     = moment*tmp*(fact-fact/norm);
+     222             :         }
+     223             :       }
+     224             :     }
+     225           0 :     comm.Sum(&v_moment[0], narg);
+     226             :   }
+     227             : 
+     228             :   // calculate powers of moments
+     229         125 :   if(do_powers) {
+     230          72 :     for(unsigned i=0; i<narg; ++i) {
+     231          48 :       const double tmp1 = std::pow(mean[i],power-1);
+     232          48 :       mean[i]          *= tmp1;
+     233          48 :       dmean[i]         *= power*tmp1;
+     234          48 :       if(do_moments) {
+     235           0 :         const double tmp2 = std::pow(v_moment[i],power-1);
+     236           0 :         v_moment[i]      *= tmp2;
+     237           0 :         dv_moment[i]     *= power*tmp2;
+     238             :       }
+     239             :     }
+     240             :   }
+     241             : 
+     242             :   // set components
+     243        3358 :   for(unsigned i=0; i<narg; ++i) {
+     244             :     // set mean
+     245        3233 :     Value* v=getPntrToComponent(i);
+     246        3233 :     v->set(mean[i]);
+     247        6466 :     setDerivative(v, i, dmean[i]);
+     248        3233 :     if(do_reweight) {
+     249           0 :       const double w_tmp = fact_kbt*(getArgument(i) - mean[i]);
+     250           0 :       setDerivative(v, narg, w_tmp);
+     251             :     }
+     252        3233 :     if(do_moments) {
+     253             :       // set moments
+     254           0 :       Value* u=getPntrToComponent(i+narg);
+     255           0 :       u->set(v_moment[i]);
+     256           0 :       setDerivative(u, i, dv_moment[i]);
+     257           0 :       if(do_reweight) {
+     258           0 :         const double w_tmp = fact_kbt*(pow(getArgument(i),moment) - v_moment[i]);
+     259           0 :         setDerivative(u, narg, w_tmp);
+     260             :       }
+     261             :     }
+     262             :   }
+     263         125 : }
+     264             : 
+     265             : }
+     266             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ccaeccdd99 --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:10113077.7 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function15FuncPathGeneralC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_128FuncPathGeneralRegisterMe1246createERKNS_13ActionOptionsE1
_ZN4PLMD8function15FuncPathGeneral13loadReferenceEv1
_ZN4PLMD8function15FuncPathGeneralC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function15FuncPathGeneral16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8function12_GLOBAL__N_128FuncPathGeneralRegisterMe124C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_128FuncPathGeneralRegisterMe124D2Ev3473
_ZN4PLMD8function15FuncPathGeneral7prepareEv175001
_ZN4PLMD8function15FuncPathGeneral9calculateEv175001
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.func.html b/coverage/function/FuncPathGeneral.cpp.func.html new file mode 100644 index 0000000000..d01178d73b --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:10113077.7 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_128FuncPathGeneralRegisterMe1246createERKNS_13ActionOptionsE1
_ZN4PLMD8function12_GLOBAL__N_128FuncPathGeneralRegisterMe124C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_128FuncPathGeneralRegisterMe124D2Ev3473
_ZN4PLMD8function15FuncPathGeneral13loadReferenceEv1
_ZN4PLMD8function15FuncPathGeneral16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8function15FuncPathGeneral7prepareEv175001
_ZN4PLMD8function15FuncPathGeneral9calculateEv175001
_ZN4PLMD8function15FuncPathGeneralC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function15FuncPathGeneralC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.gcov.html b/coverage/function/FuncPathGeneral.cpp.gcov.html new file mode 100644 index 0000000000..a60526adf4 --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.gcov.html @@ -0,0 +1,416 @@ + + + + + + + + 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:10113077.7 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ + + + + + + + +

+
          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 "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 (see \cite Hovan2019).
+      34             : 
+      35             : 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).
+      36             : The input file could be a colvar file generated with plumed driver on a trajectory containing the frames.
+      37             : 
+      38             : The metric for the path collective variables takes the following form:
+      39             : 
+      40             : \f[
+      41             : R[X - X_i] = \sum_{j=1}^M c_j^2 (x_j - x_{i,j})^2\,.
+      42             : \f]
+      43             : 
+      44             : Here, the coefficients \f$c_j\f$ determine the relative weights of the collective variables \f$c_j\f$ in the metric.
+      45             : 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.
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : This command calculates the PCVs using the values from the file COLVAR_TRAJ and the provided values for the lambda and the coefficients.
+      50             : 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.
+      51             : 
+      52             : \plumedfile
+      53             : FUNCPATHGENERAL ...
+      54             : LABEL=path
+      55             : LAMBDA=12.2
+      56             : REFERENCE=COLVAR_TRAJ
+      57             : COEFFICIENTS=0.3536,0.3536,0.3536,0.3536,0.7071
+      58             : ARG=d1,d2,d,t,drmsd
+      59             : ... FUNCPATHGENERAL
+      60             : \endplumedfile
+      61             : 
+      62             : The command below is a variation of the previous one, specifying a subset of the collective variables and using a neighbor list.
+      63             : The columns are zero-indexed.
+      64             : The neighbor list will include the 10 closest frames and will be recalculated every 20 steps.
+      65             : 
+      66             : \plumedfile
+      67             : FUNCPATHGENERAL ...
+      68             : LABEL=path
+      69             : LAMBDA=5.0
+      70             : REFERENCE=COLVAR_TRAJ
+      71             : COLUMNS=2,3,4
+      72             : COEFFICIENTS=0.3536,0.3536,0.3536
+      73             : ARG=d2,d,t
+      74             : NEIGH_SIZE=10
+      75             : NEIGH_STRIDE=20
+      76             : ... FUNCPATHGENERAL
+      77             : \endplumedfile
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : class FuncPathGeneral : public Function {
+      83             :   double lambda;
+      84             :   int neigh_size;
+      85             :   double neigh_stride;
+      86             : 
+      87             :   std::vector<double> coefficients;
+      88             :   std::vector< std::vector<double> > path_cv_values;
+      89             : 
+      90             :   // For faster calculation
+      91             :   std::vector<double> expdists;
+      92             : 
+      93             :   // For calculating derivatives
+      94             :   std::vector< std::vector<double> > numerators;
+      95             :   std::vector<double> s_path_ders;
+      96             :   std::vector<double> z_path_ders;
+      97             : 
+      98             :   // For handling periodicity
+      99             :   std::vector<double> domains;
+     100             : 
+     101             :   std::string reference;
+     102             :   std::vector<int> columns;
+     103             : 
+     104             :   std::vector< std::pair<int,double> > neighpair;
+     105             :   std::vector <Value*> allArguments;
+     106             : 
+     107             :   // Methods
+     108             :   void loadReference();
+     109             : 
+     110             :   struct pairordering {
+     111             :     bool operator ()(std::pair<int, double> const& a, std::pair<int, double> const& b) {
+     112           0 :       return (a).second < (b).second;
+     113             :     }
+     114             :   };
+     115             : 
+     116             : public:
+     117             :   explicit FuncPathGeneral(const ActionOptions&);
+     118             : // Active methods:
+     119             :   virtual void calculate();
+     120             :   virtual void prepare();
+     121             :   static void registerKeywords(Keywords& keys);
+     122             : };
+     123             : 
+     124       10421 : PLUMED_REGISTER_ACTION(FuncPathGeneral, "FUNCPATHGENERAL")
+     125             : 
+     126           1 : void FuncPathGeneral::loadReference() {
+     127           1 :   IFile input;
+     128           1 :   input.open(reference);
+     129           1 :   if (!input)
+     130           0 :     plumed_merror("Could not open the reference file!");
+     131          18 :   while (input)
+     132             :   {
+     133             :     std::vector<std::string> strings;
+     134          17 :     Tools::getParsedLine(input, strings);
+     135          17 :     if (strings.empty())
+     136             :       continue;
+     137             :     std::vector<double> colvarLine;
+     138             :     double value;
+     139          16 :     int max = columns.empty() ? strings.size() : columns.size();
+     140         128 :     for (int i = 0; i < max; ++i)
+     141             :     {
+     142         112 :       int col = columns.empty() ? i : columns[i];
+     143             :       // If no columns have been entered, ignore the first (time) and take the rest
+     144         112 :       if (columns.empty() && i == 0)
+     145          16 :         continue;
+     146             : 
+     147          96 :       Tools::convert(strings[col], value);
+     148          96 :       colvarLine.push_back(value);
+     149             :     }
+     150          16 :     path_cv_values.push_back(colvarLine);
+     151          17 :   }
+     152           1 : }
+     153             : 
+     154           2 : void FuncPathGeneral::registerKeywords(Keywords& keys) {
+     155           2 :   Function::registerKeywords(keys);
+     156           2 :   keys.use("ARG");
+     157           4 :   keys.add("compulsory", "LAMBDA", "Lambda parameter required for smoothing");
+     158           4 :   keys.add("compulsory", "COEFFICIENTS", "Coefficients to be assigned to the CVs");
+     159           4 :   keys.add("compulsory", "REFERENCE", "Colvar file needed to provide the CV milestones");
+     160           4 :   keys.add("optional", "COLUMNS", "List of columns in the reference colvar file specifying the CVs");
+     161           4 :   keys.add("optional", "NEIGH_SIZE", "Size of the neighbor list");
+     162           4 :   keys.add("optional", "NEIGH_STRIDE", "How often the neighbor list needs to be calculated in time units");
+     163           2 :   componentsAreNotOptional(keys);
+     164           4 :   keys.addOutputComponent("s", "default", "Position on the path");
+     165           4 :   keys.addOutputComponent("z", "default", "Distance from the path");
+     166           2 : }
+     167             : 
+     168           1 : FuncPathGeneral::FuncPathGeneral(const ActionOptions&ao):
+     169             :   Action(ao),
+     170             :   Function(ao),
+     171           1 :   neigh_size(-1),
+     172           1 :   neigh_stride(-1.)
+     173             : {
+     174           1 :   parse("LAMBDA", lambda);
+     175           1 :   parse("NEIGH_SIZE", neigh_size);
+     176           1 :   parse("NEIGH_STRIDE", neigh_stride);
+     177           1 :   parse("REFERENCE", reference);
+     178           1 :   parseVector("COEFFICIENTS", coefficients);
+     179           1 :   parseVector("COLUMNS", columns);
+     180           1 :   checkRead();
+     181           1 :   log.printf("  lambda is %f\n", lambda);
+     182           1 :   if (getNumberOfArguments() != coefficients.size())
+     183           0 :     plumed_merror("The numbers of coefficients and CVs are different!");
+     184           1 :   if (!columns.empty()) {
+     185           0 :     if (columns.size() != coefficients.size())
+     186           0 :       plumed_merror("The numbers of coefficients and columns are different!");
+     187             :   }
+     188           1 :   log.printf("  Consistency check completed! Your path cvs look good!\n");
+     189             : 
+     190             :   // Load the reference colvar file
+     191           1 :   loadReference();
+     192             : 
+     193             :   // Do some neighbour printout
+     194           1 :   if (neigh_stride > 0. || neigh_size > 0) {
+     195           0 :     if (static_cast<unsigned>(neigh_size) > path_cv_values.size()) {
+     196           0 :       log.printf(" List size required ( %d ) is too large: resizing to the maximum number of arg required: %d  \n", neigh_size, getNumberOfArguments());
+     197           0 :       neigh_size = path_cv_values.size();
+     198             :     }
+     199           0 :     log.printf("  Neighbour list enabled: \n");
+     200           0 :     log.printf("                 size   :  %d elements\n", neigh_size);
+     201           0 :     log.printf("                 stride :  %f time \n", neigh_stride);
+     202             :   } else {
+     203           1 :     log.printf("  Neighbour list NOT enabled \n");
+     204             :   }
+     205             : 
+     206           2 :   addComponentWithDerivatives("s"); componentIsNotPeriodic("s");
+     207           3 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     208             : 
+     209             :   // Initialise vectors
+     210           1 :   std::vector<double> temp (coefficients.size());
+     211          17 :   for (unsigned i = 0; i < path_cv_values.size(); ++i) {
+     212          16 :     numerators.push_back(temp);
+     213          16 :     expdists.push_back(0.);
+     214          16 :     s_path_ders.push_back(0.);
+     215          16 :     z_path_ders.push_back(0.);
+     216             :   }
+     217             : 
+     218             :   // Store the arguments
+     219           7 :   for (unsigned i=0; i<getNumberOfArguments(); i++)
+     220           6 :     allArguments.push_back(getPntrToArgument(i));
+     221             : 
+     222             :   // Get periodic domains, negative for not periodic, stores half the domain length (maximum difference)
+     223           7 :   for (unsigned i = 0; i < allArguments.size(); ++i) {
+     224           6 :     if (allArguments[i]->isPeriodic()) {
+     225             :       double min_lim, max_lim;
+     226           0 :       allArguments[i]->getDomain(min_lim, max_lim);
+     227           0 :       domains.push_back((max_lim - min_lim) / 2);
+     228             :     }
+     229             :     else
+     230           6 :       domains.push_back(-1.);
+     231             :   }
+     232           1 : }
+     233             : 
+     234             : // Calculator
+     235      175001 : void FuncPathGeneral::calculate() {
+     236             :   double s_path = 0.;
+     237             :   double partition = 0.;
+     238             :   double tmp, value, diff, expdist, s_der, z_der;
+     239             :   int ii;
+     240             : 
+     241             :   typedef std::vector< std::pair< int,double> >::iterator pairiter;
+     242             : 
+     243     2975001 :   for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     244     2800000 :     (*it).second = 0.;
+     245             :   }
+     246             : 
+     247      175001 :   if (neighpair.empty()) {
+     248             :     // Resize at the first step
+     249           1 :     neighpair.resize(path_cv_values.size());
+     250          17 :     for (unsigned i = 0; i < path_cv_values.size(); ++i)
+     251          16 :       neighpair[i].first = i;
+     252             :   }
+     253             : 
+     254      175001 :   Value* val_s_path=getPntrToComponent("s");
+     255      175001 :   Value* val_z_path=getPntrToComponent("z");
+     256             : 
+     257     1225007 :   for(unsigned j = 0; j < allArguments.size(); ++j) {
+     258     1050006 :     value = allArguments[j]->get();
+     259    17850102 :     for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     260    16800096 :       diff = (value - path_cv_values[(*it).first][j]);
+     261    16800096 :       if (domains[j] > 0) {
+     262           0 :         if (diff > domains[j])
+     263           0 :           diff -= 2 * domains[j];
+     264           0 :         if (diff < -domains[j])
+     265           0 :           diff += 2 * domains[j];
+     266             :       }
+     267    33600192 :       (*it).second += Tools::fastpow(coefficients[j] * diff, 2);
+     268    33600192 :       numerators[(*it).first][j] = 2 * Tools::fastpow(coefficients[j], 2) * diff;
+     269             :     }
+     270             :   }
+     271             : 
+     272     2975017 :   for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     273     2800016 :     expdist = std::exp(-lambda * (*it).second);
+     274     2800016 :     expdists[(*it).first] = expdist;
+     275     2800016 :     s_path += ((*it).first + 1) * expdist;
+     276     2800016 :     partition += expdist;
+     277             :   }
+     278             : 
+     279      175001 :   if(partition==0.0) partition=std::numeric_limits<double>::min();
+     280             : 
+     281      175001 :   s_path /= partition;
+     282             :   val_s_path->set(s_path);
+     283      175001 :   val_z_path->set(-(1. / lambda) * std::log(partition));
+     284             : 
+     285             :   // Derivatives
+     286     2975017 :   for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     287     2800016 :     ii = (*it).first;
+     288     2800016 :     tmp = lambda * expdists[ii] * (s_path - (ii + 1)) / partition;
+     289     2800016 :     s_path_ders[ii] = tmp;
+     290     2800016 :     z_path_ders[ii] = expdists[ii] / partition;
+     291             :   }
+     292     1225007 :   for (unsigned i = 0; i < coefficients.size(); ++i) {
+     293             :     s_der = 0.;
+     294             :     z_der = 0.;
+     295    17850102 :     for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     296    16800096 :       ii = (*it).first;
+     297    16800096 :       s_der += s_path_ders[ii] * numerators[ii][i];
+     298    16800096 :       z_der += z_path_ders[ii] * numerators[ii][i];
+     299             :     }
+     300             :     setDerivative(val_s_path, i, s_der);
+     301             :     setDerivative(val_z_path, i, z_der);
+     302             :   }
+     303      175001 : }
+     304             : 
+     305             : // Prepare the required arguments
+     306      175001 : void FuncPathGeneral::prepare() {
+     307             :   // Neighbour list: rank and activate the chain for the next step
+     308             : 
+     309             :   // Neighbour list: if neigh_size < 0 never sort and keep the full vector
+     310             :   // Neighbour list: if neigh_size > 0
+     311             :   //                 if the size is full -> sort the vector and decide the dependencies for next step
+     312             :   //                 if the size is not full -> check if next step will need the full dependency otherwise keep these dependencies
+     313             : 
+     314      175001 :   if (neigh_size > 0) {
+     315           0 :     if (neighpair.size() == path_cv_values.size()) {
+     316             :       // The complete round has been done: need to sort, shorten and give it a go
+     317             :       // Sort the values
+     318           0 :       std::sort(neighpair.begin(), neighpair.end(), pairordering());
+     319             :       // Resize the effective list
+     320           0 :       neighpair.resize(neigh_size);
+     321           0 :       log.printf("  NEIGHBOUR LIST NOW INCLUDES INDICES: ");
+     322           0 :       for (int i = 0; i < neigh_size; ++i)
+     323           0 :         log.printf(" %i ",neighpair[i].first);
+     324           0 :       log.printf(" \n");
+     325             :     } else {
+     326           0 :       if (int(getStep()) % int(neigh_stride / getTimeStep()) == 0) {
+     327           0 :         log.printf(" Time %f : recalculating full neighbour list \n", getStep() * getTimeStep());
+     328           0 :         neighpair.resize(path_cv_values.size());
+     329           0 :         for (unsigned i = 0; i < path_cv_values.size(); ++i)
+     330           0 :           neighpair[i].first = i;
+     331             :       }
+     332             :     }
+     333             :   }
+     334             : 
+     335      175001 :   requestArguments(allArguments);
+     336      175001 : }
+     337             : 
+     338             : }
+     339             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..d9353d5cf5 --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:758192.6 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function11FuncPathMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function11FuncPathMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe2186createERKNS_13ActionOptionsE2
_ZN4PLMD8function11FuncPathMSD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function11FuncPathMSD7prepareEv1092
_ZN4PLMD8function11FuncPathMSD9calculateEv1092
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe218C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe218D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/FuncPathMSD.cpp.func.html b/coverage/function/FuncPathMSD.cpp.func.html new file mode 100644 index 0000000000..be926e5ba1 --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:758192.6 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function11FuncPathMSD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function11FuncPathMSD7prepareEv1092
_ZN4PLMD8function11FuncPathMSD9calculateEv1092
_ZN4PLMD8function11FuncPathMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function11FuncPathMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe2186createERKNS_13ActionOptionsE2
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe218C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe218D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/FuncPathMSD.cpp.gcov.html b/coverage/function/FuncPathMSD.cpp.gcov.html new file mode 100644 index 0000000000..668f72b6c3 --- /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:758192.6 %
Date:2024-06-10 08:19:14Functions:7887.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             : 
+      23             : #include "Function.h"
+      24             : #include "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       10423 : PLUMED_REGISTER_ACTION(FuncPathMSD,"FUNCPATHMSD")
+     219             : 
+     220           3 : void FuncPathMSD::registerKeywords(Keywords& keys) {
+     221           3 :   Function::registerKeywords(keys);
+     222           3 :   keys.use("ARG");
+     223           6 :   keys.add("compulsory","LAMBDA","the lambda parameter is needed for smoothing, is in the units of plumed");
+     224           6 :   keys.add("optional","NEIGH_SIZE","size of the neighbor list");
+     225           6 :   keys.add("optional","NEIGH_STRIDE","how often the neighbor list needs to be calculated in time units");
+     226           3 :   componentsAreNotOptional(keys);
+     227           6 :   keys.addOutputComponent("s","default","the position on the path");
+     228           6 :   keys.addOutputComponent("z","default","the distance from the path");
+     229           3 : }
+     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.15
+
+ + + 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 0000000000..9859b255fb --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + 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:29032988.1 %
Date:2024-06-10 08:19:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12FuncSumHills9calculateEv0
_ZN4PLMD8function12FuncSumHillsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12FilesHandler12getMinMaxBinESt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESB_RS2_IjSaIjEERKSA_1
_ZN4PLMD8function12FilesHandler12getMinMaxBinESt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESB_RS2_IjSaIjEE4
_ZN4PLMD8function12FuncSumHills21checkFilesAreExistingERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE9
_ZN4PLMD8function12FuncSumHillsC1ERKNS_13ActionOptionsE9
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe1996createERKNS_13ActionOptionsE9
_ZN4PLMD8function12FuncSumHills16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8function12FilesHandlerC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKbRNS_6ActionERNS_3LogE14
_ZN4PLMD8function12FilesHandler9readBunchEPNS_18BiasRepresentationEi15
_ZN4PLMD8function5mylogEd900
_ZN4PLMD8function8mylogderEd1800
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe199C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe199D2Ev3473
_ZN4PLMD8function12FilesHandler11scanOneHillEPNS_18BiasRepresentationEPNS_5IFileE5578
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.func.html b/coverage/function/FuncSumHills.cpp.func.html new file mode 100644 index 0000000000..8baa01bd2f --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + 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:29032988.1 %
Date:2024-06-10 08:19:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12FilesHandler11scanOneHillEPNS_18BiasRepresentationEPNS_5IFileE5578
_ZN4PLMD8function12FilesHandler12getMinMaxBinESt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESB_RS2_IjSaIjEE4
_ZN4PLMD8function12FilesHandler12getMinMaxBinESt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESB_RS2_IjSaIjEERKSA_1
_ZN4PLMD8function12FilesHandler9readBunchEPNS_18BiasRepresentationEi15
_ZN4PLMD8function12FilesHandlerC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKbRNS_6ActionERNS_3LogE14
_ZN4PLMD8function12FuncSumHills16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8function12FuncSumHills21checkFilesAreExistingERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE9
_ZN4PLMD8function12FuncSumHills9calculateEv0
_ZN4PLMD8function12FuncSumHillsC1ERKNS_13ActionOptionsE9
_ZN4PLMD8function12FuncSumHillsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe1996createERKNS_13ActionOptionsE9
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe199C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe199D2Ev3473
_ZN4PLMD8function5mylogEd900
_ZN4PLMD8function8mylogderEd1800
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.gcov.html b/coverage/function/FuncSumHills.cpp.gcov.html new file mode 100644 index 0000000000..73eb5ae73a --- /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:29032988.1 %
Date:2024-06-10 08:19:14Functions:131586.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 "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(std::vector<Value*> vals, Communicator &cc, std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin);
+      64             :   void getMinMaxBin(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          15 :     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(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(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       10437 : PLUMED_REGISTER_ACTION(FuncSumHills,"FUNCSUMHILLS")
+     200             : 
+     201          10 : void FuncSumHills::registerKeywords(Keywords& keys) {
+     202          10 :   Function::registerKeywords(keys);
+     203          10 :   keys.use("ARG");
+     204          20 :   keys.add("optional","HILLSFILES"," source file for hills creation(may be the same as HILLS)"); // this can be a vector!
+     205          20 :   keys.add("optional","HISTOFILES"," source file for histogram creation(may be the same as HILLS)"); // also this can be a vector!
+     206          20 :   keys.add("optional","HISTOSIGMA"," sigmas for binning when the histogram correction is needed    ");
+     207          20 :   keys.add("optional","PROJ"," only with sumhills: the projection on the CVs");
+     208          20 :   keys.add("optional","KT"," only with sumhills: the kt factor when projection on CVs");
+     209          20 :   keys.add("optional","GRID_MIN","the lower bounds for the grid");
+     210          20 :   keys.add("optional","GRID_MAX","the upper bounds for the grid");
+     211          20 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     212          20 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     213          20 :   keys.add("optional","INTERVAL","set one dimensional INTERVAL");
+     214          20 :   keys.add("optional","OUTHILLS"," output file for hills ");
+     215          20 :   keys.add("optional","OUTHISTO"," output file for histogram ");
+     216          20 :   keys.add("optional","INITSTRIDE"," stride if you want an initial dump ");
+     217          20 :   keys.add("optional","STRIDE"," stride when you do it on the fly ");
+     218          20 :   keys.addFlag("ISCLTOOL",false,"use via plumed command line: calculate at read phase and then go");
+     219          20 :   keys.addFlag("PARALLELREAD",false,"read parallel HILLS file");
+     220          20 :   keys.addFlag("NEGBIAS",false,"dump  negative bias ( -bias )   instead of the free energy: needed in well tempered with flexible hills ");
+     221          20 :   keys.addFlag("NOHISTORY",false,"to be used with INITSTRIDE:  it splits the bias/histogram in pieces without previous history  ");
+     222          20 :   keys.addFlag("MINTOZERO",false,"translate the resulting bias/histogram to have the minimum to zero  ");
+     223          20 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     224          10 : }
+     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           0 :     log<<"  The number of bins will be estimated from GRID_SPACING\n";
+     267           9 :   } 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           9 :   if(gspacing.size()!=0) for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     272           0 :       if(gbin.size()==0) gbin.assign(getNumberOfArguments(),1);
+     273             :       double a,b;
+     274           0 :       Tools::convert(gmin[i],a);
+     275           0 :       Tools::convert(gmax[i],b);
+     276           0 :       unsigned n=((b-a)/gspacing[i])+1;
+     277           0 :       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           9 :   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           9 :   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.15
+
+ + + 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 0000000000..0a04fb3eb9 --- /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:394097.5 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8Function23addValueWithDerivativesEv570
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE664
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE678
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3168
_ZN4PLMD8function8Function5applyEv225022
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Function.cpp.func.html b/coverage/function/Function.cpp.func.html new file mode 100644 index 0000000000..7c49b450b1 --- /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:394097.5 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE678
_ZN4PLMD8function8Function23addValueWithDerivativesEv570
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3168
_ZN4PLMD8function8Function5applyEv225022
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE664
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Function.cpp.gcov.html b/coverage/function/Function.cpp.gcov.html new file mode 100644 index 0000000000..d7878c8401 --- /dev/null +++ b/coverage/function/Function.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + + 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:394097.5 %
Date:2024-06-10 08:19:14Functions: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         678 : void Function::registerKeywords(Keywords& keys) {
+      30         678 :   Action::registerKeywords(keys);
+      31         678 :   ActionWithValue::registerKeywords(keys);
+      32         678 :   ActionWithArguments::registerKeywords(keys);
+      33        1356 :   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         678 : }
+      35             : 
+      36         664 : Function::Function(const ActionOptions&ao):
+      37             :   Action(ao),
+      38             :   ActionWithValue(ao),
+      39         664 :   ActionWithArguments(ao)
+      40             : {
+      41         664 : }
+      42             : 
+      43         570 : void Function::addValueWithDerivatives() {
+      44         570 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      45         570 :   ActionWithValue::addValueWithDerivatives();
+      46         570 :   getPntrToValue()->resizeDerivatives(getNumberOfArguments());
+      47             : 
+      48        1140 :   if( keywords.exists("PERIODIC") ) {
+      49             :     std::vector<std::string> period;
+      50        1134 :     parseVector("PERIODIC",period);
+      51        1131 :     if(period.size()==1 && period[0]=="NO") {
+      52         564 :       setNotPeriodic();
+      53           3 :     } else if(period.size()==2) {
+      54           3 :       setPeriodic(period[0],period[1]);
+      55           0 :     } else error("missing PERIODIC keyword");
+      56         567 :   }
+      57         570 : }
+      58             : 
+      59        3168 : void Function::addComponentWithDerivatives( const std::string& name ) {
+      60        3168 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      61        3168 :   ActionWithValue::addComponentWithDerivatives(name);
+      62        3168 :   getPntrToComponent(name)->resizeDerivatives(getNumberOfArguments());
+      63        3168 : }
+      64             : 
+      65      225022 : void Function::apply()
+      66             : {
+      67      225022 :   const unsigned noa=getNumberOfArguments();
+      68      225022 :   const unsigned ncp=getNumberOfComponents();
+      69      225022 :   const unsigned cgs=comm.Get_size();
+      70             : 
+      71      225022 :   std::vector<double> f(noa,0.0);
+      72             : 
+      73             :   unsigned stride=1;
+      74             :   unsigned rank=0;
+      75      225022 :   if(ncp>4*cgs) {
+      76           6 :     stride=comm.Get_size();
+      77           6 :     rank=comm.Get_rank();
+      78             :   }
+      79             : 
+      80      225022 :   unsigned at_least_one_forced=0;
+      81      225022 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(f)
+      82             :   {
+      83             :     std::vector<double> omp_f(noa,0.0);
+      84             :     std::vector<double> forces(noa);
+      85             :     #pragma omp for reduction( + : at_least_one_forced)
+      86             :     for(unsigned i=rank; i<ncp; i+=stride) {
+      87             :       if(getPntrToComponent(i)->applyForce(forces)) {
+      88             :         at_least_one_forced+=1;
+      89             :         for(unsigned j=0; j<noa; j++) omp_f[j]+=forces[j];
+      90             :       }
+      91             :     }
+      92             :     #pragma omp critical
+      93             :     for(unsigned j=0; j<noa; j++) f[j]+=omp_f[j];
+      94             :   }
+      95             : 
+      96      225022 :   if(noa>0&&ncp>4*cgs) { comm.Sum(&f[0],noa); comm.Sum(at_least_one_forced); }
+      97             : 
+      98      290884 :   if(at_least_one_forced>0) for(unsigned i=0; i<noa; ++i) getPntrToArgument(i)->addForce(f[i]);
+      99      225022 : }
+     100             : 
+     101             : }
+     102             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..572670f33d --- /dev/null +++ b/coverage/function/Function.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + 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:7887.5 %
Date:2024-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionD2Ev664
_ZN4PLMD8function8Function13setDerivativeEid52168
_ZN4PLMD8function8Function22getNumberOfDerivativesEv3471287
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Function.h.func.html b/coverage/function/Function.h.func.html new file mode 100644 index 0000000000..0b8d716f63 --- /dev/null +++ b/coverage/function/Function.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + 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:7887.5 %
Date:2024-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function13setDerivativeEid52168
_ZN4PLMD8function8Function22getNumberOfDerivativesEv3471287
_ZN4PLMD8function8FunctionD2Ev664
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Function.h.gcov.html b/coverage/function/Function.h.gcov.html new file mode 100644 index 0000000000..1e024af10f --- /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:7887.5 %
Date:2024-06-10 08:19:14Functions: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_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         664 :   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       55078 :   v->addDerivative(i,d);
+      57           0 : }
+      58             : 
+      59             : inline
+      60       52168 : void Function::setDerivative(int i,double d) {
+      61       52168 :   setDerivative(getPntrToValue(),i,d);
+      62       52168 : }
+      63             : 
+      64             : inline
+      65     3471287 : unsigned Function::getNumberOfDerivatives() {
+      66     3471287 :   return getNumberOfArguments();
+      67             : }
+      68             : 
+      69             : }
+      70             : }
+      71             : 
+      72             : #endif
+      73             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b12a078d17 --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3232100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe886createERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsembleC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsemble16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function13LocalEnsemble9calculateEv40
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe88C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe88D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.func.html b/coverage/function/LocalEnsemble.cpp.func.html new file mode 100644 index 0000000000..d83702cd9a --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3232100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe886createERKNS_13ActionOptionsE2
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe88C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe88D2Ev3473
_ZN4PLMD8function13LocalEnsemble16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function13LocalEnsemble9calculateEv40
_ZN4PLMD8function13LocalEnsembleC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.gcov.html b/coverage/function/LocalEnsemble.cpp.gcov.html new file mode 100644 index 0000000000..ff7b9e3225 --- /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:3232100.0 %
Date:2024-06-10 08:19:14Functions: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 "Function.h"
+      23             : #include "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       10423 : PLUMED_REGISTER_ACTION(LocalEnsemble,"LOCALENSEMBLE")
+      89             : 
+      90           3 : void LocalEnsemble::registerKeywords(Keywords& keys) {
+      91           3 :   Function::registerKeywords(keys);
+      92           3 :   keys.use("ARG");
+      93           6 :   keys.add("compulsory","NUM","the number of local replicas");
+      94           3 :   useCustomisableComponents(keys);
+      95           3 : }
+      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.15
+
+ + + 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 0000000000..eddfadb885 --- /dev/null +++ b/coverage/function/Piecewise.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4747100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function9PiecewiseC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe796createERKNS_13ActionOptionsE3
_ZN4PLMD8function9PiecewiseC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function9Piecewise9calculateEv10
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe79C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe79D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Piecewise.cpp.func.html b/coverage/function/Piecewise.cpp.func.html new file mode 100644 index 0000000000..ee134eb3c4 --- /dev/null +++ b/coverage/function/Piecewise.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4747100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe796createERKNS_13ActionOptionsE3
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe79C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe79D2Ev3473
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function9Piecewise9calculateEv10
_ZN4PLMD8function9PiecewiseC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function9PiecewiseC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Piecewise.cpp.gcov.html b/coverage/function/Piecewise.cpp.gcov.html new file mode 100644 index 0000000000..7eaf62d891 --- /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:4747100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10424 : PLUMED_REGISTER_ACTION(Piecewise,"PIECEWISE")
+      80             : 
+      81           4 : void Piecewise::registerKeywords(Keywords& keys) {
+      82           4 :   Function::registerKeywords(keys);
+      83           4 :   keys.use("ARG");
+      84           8 :   keys.add("numbered","POINT","This keyword is used to specify the various points in the function above.");
+      85           8 :   keys.reset_style("POINT","compulsory");
+      86           4 :   componentsAreNotOptional(keys);
+      87           8 :   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           4 : }
+      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           5 :       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.15
+
+ + + 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 0000000000..a66b137241 --- /dev/null +++ b/coverage/function/Sort.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2727100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function4SortC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function4Sort9calculateEv11
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe646createERKNS_13ActionOptionsE12
_ZN4PLMD8function4SortC1ERKNS_13ActionOptionsE12
_ZN4PLMD8function4Sort16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe64C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe64D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Sort.cpp.func.html b/coverage/function/Sort.cpp.func.html new file mode 100644 index 0000000000..dd0bfdc065 --- /dev/null +++ b/coverage/function/Sort.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2727100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe646createERKNS_13ActionOptionsE12
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe64C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe64D2Ev3473
_ZN4PLMD8function4Sort16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD8function4Sort9calculateEv11
_ZN4PLMD8function4SortC1ERKNS_13ActionOptionsE12
_ZN4PLMD8function4SortC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Sort.cpp.gcov.html b/coverage/function/Sort.cpp.gcov.html new file mode 100644 index 0000000000..a014ee21ed --- /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:2727100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10442 : PLUMED_REGISTER_ACTION(Sort,"SORT")
+      65             : 
+      66          13 : void Sort::registerKeywords(Keywords& keys) {
+      67          13 :   Function::registerKeywords(keys);
+      68          13 :   keys.use("ARG");
+      69          13 :   useCustomisableComponents(keys);
+      70          13 : }
+      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.15
+
+ + + 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 0000000000..bb003204e5 --- /dev/null +++ b/coverage/function/Stats.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:9610096.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function5StatsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe706createERKNS_13ActionOptionsE31
_ZN4PLMD8function5StatsC1ERKNS_13ActionOptionsE31
_ZN4PLMD8function5Stats16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD8function5Stats9calculateEv122
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe70C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe70D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Stats.cpp.func.html b/coverage/function/Stats.cpp.func.html new file mode 100644 index 0000000000..2a3e5feef5 --- /dev/null +++ b/coverage/function/Stats.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:9610096.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe706createERKNS_13ActionOptionsE31
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe70C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe70D2Ev3473
_ZN4PLMD8function5Stats16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD8function5Stats9calculateEv122
_ZN4PLMD8function5StatsC1ERKNS_13ActionOptionsE31
_ZN4PLMD8function5StatsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Stats.cpp.gcov.html b/coverage/function/Stats.cpp.gcov.html new file mode 100644 index 0000000000..b76b60dec8 --- /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:9610096.0 %
Date:2024-06-10 08:19:14Functions: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 "Function.h"
+      23             : #include "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       10481 : PLUMED_REGISTER_ACTION(Stats,"STATS")
+      71             : 
+      72          32 : void Stats::registerKeywords(Keywords& keys) {
+      73          32 :   Function::registerKeywords(keys);
+      74          32 :   keys.use("ARG");
+      75          64 :   keys.add("optional","PARARG","the input for this action is the scalar output from one or more other actions without derivatives.");
+      76          64 :   keys.add("optional","PARAMETERS","the parameters of the arguments in your function");
+      77          64 :   keys.addFlag("SQDEVSUM",false,"calculates only SQDEVSUM");
+      78          64 :   keys.addFlag("SQDEV",false,"calculates and store the SQDEV as components");
+      79          64 :   keys.addFlag("UPPERDISTS",false,"calculates and store the SQDEV as components");
+      80          64 :   keys.addOutputComponent("sqdevsum","default","the sum of the squared deviations between arguments and parameters");
+      81          64 :   keys.addOutputComponent("corr","default","the correlation between arguments and parameters");
+      82          64 :   keys.addOutputComponent("slope","default","the slope of a linear fit between arguments and parameters");
+      83          64 :   keys.addOutputComponent("intercept","default","the intercept of a linear fit between arguments and parameters");
+      84          64 :   keys.addOutputComponent("sqd","SQDEV","the squared deviations between arguments and parameters");
+      85          32 : }
+      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.15
+
+ + + 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 0000000000..0b9c7eaa7e --- /dev/null +++ b/coverage/function/Target.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:62722.2 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe1086createERKNS_13ActionOptionsE0
_ZN4PLMD8function6Target9calculateEv0
_ZN4PLMD8function6TargetC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function6TargetC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function6Target16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe108C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe108D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Target.cpp.func.html b/coverage/function/Target.cpp.func.html new file mode 100644 index 0000000000..fa8ead6f72 --- /dev/null +++ b/coverage/function/Target.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:62722.2 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe1086createERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe108C2Ev3473
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe108D2Ev3473
_ZN4PLMD8function6Target16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD8function6Target9calculateEv0
_ZN4PLMD8function6TargetC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function6TargetC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/Target.cpp.gcov.html b/coverage/function/Target.cpp.gcov.html new file mode 100644 index 0000000000..a21c9c000c --- /dev/null +++ b/coverage/function/Target.cpp.gcov.html @@ -0,0 +1,238 @@ + + + + + + + + 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:62722.2 %
Date:2024-06-10 08:19:14Functions:3742.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 "Function.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "tools/PDB.h"
+      25             : #include "reference/MetricRegister.h"
+      26             : #include "reference/ArgumentOnlyDistance.h"
+      27             : #include "core/Atoms.h"
+      28             : #include "core/PlumedMain.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace function {
+      32             : 
+      33             : //+PLUMEDOC DCOLVAR TARGET
+      34             : /*
+      35             : This function measures the Pythagorean distance from a particular structure measured in the space defined by some set of collective variables.
+      36             : 
+      37             : This collective variable can be used to calculate something akin to:
+      38             : 
+      39             : \f[
+      40             : d(X,X') = \vert X - X' \vert
+      41             : \f]
+      42             : 
+      43             : where \f$ X \f$ is the instantaneous values for a set of collective variables for the system and
+      44             : \f$ X' \f$ is the values that these self-same set of collective variables take in some reference structure provided as input.
+      45             : If we call our set of collective variables \f$\{s_i\}\f$ then this CV computes:
+      46             : 
+      47             : \f[
+      48             : d = \sqrt{ \sum_{i=1}^N (s_i - s_i^{(ref)})^2 }
+      49             : \f]
+      50             : 
+      51             : 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.
+      52             : 
+      53             : We can also calculate normalized euclidean differences using this action and the METRIC=NORM-EUCLIDEAN flag.  In other words,
+      54             : we can compute:
+      55             : 
+      56             : \f[
+      57             : d = \sqrt{ \sum_{i=1}^N \sigma_i (s_i - s_i^{(ref)})^2 }
+      58             : \f]
+      59             : 
+      60             : where \f$\sigma_i\f$ is a vector of weights.  Lastly, by using the METRIC=MAHALONOBIS we can compute Mahalonobis distances using:
+      61             : 
+      62             : \f[
+      63             : d = \left( \mathbf{s} - \mathbf{s}^{(ref)} \right)^T \mathbf{\Sigma} \left( \mathbf{s} - \mathbf{s}^{(ref)} \right)
+      64             : \f]
+      65             : 
+      66             : 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
+      67             : 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
+      68             : specified in the input.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : The following input calculates the distance between a reference configuration and the instantaneous position of the system in the trajectory.
+      73             : 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.
+      74             : 
+      75             : \plumedfile
+      76             : d1: DISTANCE ATOMS=1,2
+      77             : d2: DISTANCE ATOMS=3,4
+      78             : t1: TARGET REFERENCE=reference.pdb TYPE=EUCLIDEAN
+      79             : PRINT ARG=t1 FILE=colvar
+      80             : \endplumedfile
+      81             : 
+      82             : The contents of the file containing the reference structure (reference.pdb) is shown below.  As you can see you must provide information on the
+      83             : 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
+      84             : quantities take in the reference configuration.
+      85             : 
+      86             : \auxfile{reference.pdb}
+      87             : DESCRIPTION: a reference point.
+      88             : REMARK WEIGHT=1.0
+      89             : REMARK ARG=d1,d2
+      90             : REMARK d1=1.0 d2=1.0
+      91             : END
+      92             : \endauxfile
+      93             : 
+      94             : */
+      95             : //+ENDPLUMEDOC
+      96             : 
+      97             : class Target : public Function {
+      98             : private:
+      99             :   MultiValue myvals;
+     100             :   ReferenceValuePack mypack;
+     101             :   std::unique_ptr<PLMD::ArgumentOnlyDistance> target;
+     102             : public:
+     103             :   explicit Target(const ActionOptions&);
+     104             :   void calculate() override;
+     105             :   static void registerKeywords(Keywords& keys );
+     106             : };
+     107             : 
+     108       10419 : PLUMED_REGISTER_ACTION(Target,"TARGET")
+     109             : 
+     110           1 : void Target::registerKeywords(Keywords& keys) {
+     111           1 :   Function::registerKeywords(keys);
+     112           2 :   keys.add("compulsory","TYPE","EUCLIDEAN","the manner in which the distance should be calculated");
+     113           2 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure. In the PDB file the atomic "
+     114             :            "coordinates and box lengths should be in Angstroms unless you are working with natural units. "
+     115             :            "If you are working with natural units then the coordinates should be in your natural length unit. "
+     116             :            "The charges and masses of the atoms (if required) should be inserted in the beta and occupancy "
+     117             :            "columns respectively. For more details on the PDB file format visit http://www.wwpdb.org/docs.html");
+     118           1 : }
+     119             : 
+     120           0 : Target::Target(const ActionOptions&ao):
+     121             :   Action(ao),
+     122             :   Function(ao),
+     123           0 :   myvals(1,0),
+     124           0 :   mypack(0,0,myvals)
+     125             : {
+     126           0 :   std::string type; parse("TYPE",type);
+     127           0 :   std::string reference; parse("REFERENCE",reference);
+     128           0 :   checkRead(); PDB pdb;
+     129           0 :   if( !pdb.read(reference,plumed.getAtoms().usingNaturalUnits(),0.1/plumed.getAtoms().getUnits().getLength()) )
+     130           0 :     error("missing input file " + reference);
+     131             : 
+     132             :   // Use the base ActionWithArguments to expand things like a1.*
+     133           0 :   expandArgKeywordInPDB( pdb );
+     134             : 
+     135             :   // Generate the reference structure
+     136           0 :   target=metricRegister().create<ArgumentOnlyDistance>( type, pdb );
+     137             : 
+     138             :   // Get the argument names
+     139             :   std::vector<std::string> args_to_retrieve;
+     140           0 :   target->getArgumentRequests( args_to_retrieve, false );
+     141             : 
+     142             :   // Get the arguments
+     143             :   std::vector<Value*> myargs;
+     144           0 :   interpretArgumentList( args_to_retrieve, myargs );
+     145           0 :   requestArguments( myargs );
+     146             : 
+     147             :   // Now create packs
+     148           0 :   myvals.resize( 1, myargs.size() );
+     149           0 :   mypack.resize( myargs.size(), 0 );
+     150             : 
+     151             :   // Create the value
+     152           0 :   addValueWithDerivatives(); setNotPeriodic();
+     153           0 : }
+     154             : 
+     155           0 : void Target::calculate() {
+     156           0 :   mypack.clear(); double r=target->calculate( getArguments(), mypack, false ); setValue(r);
+     157           0 :   for(unsigned i=0; i<getNumberOfArguments(); i++) setDerivative( i, mypack.getArgumentDerivative(i) );
+     158           0 : }
+     159             : 
+     160             : }
+     161             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/index-sort-f.html b/coverage/function/index-sort-f.html new file mode 100644 index 0000000000..cfe908c755 --- /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:904105985.4 %
Date:2024-06-10 08:19:14Functions:8410084.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Target.cpp +
22.2%22.2%
+
22.2 %6 / 2742.9 %3 / 7
Function.cpp +
97.5%97.5%
+
97.5 %39 / 4083.3 %5 / 6
Combine.cpp +
93.6%93.6%
+
93.6 %44 / 4785.7 %6 / 7
LocalEnsemble.cpp +
100.0%
+
100.0 %32 / 3285.7 %6 / 7
Stats.cpp +
96.0%96.0%
+
96.0 %96 / 10085.7 %6 / 7
Piecewise.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
Ensemble.cpp +
63.1%63.1%
+
63.1 %82 / 13085.7 %6 / 7
Sort.cpp +
100.0%
+
100.0 %27 / 2785.7 %6 / 7
FuncSumHills.cpp +
88.1%88.1%
+
88.1 %290 / 32986.7 %13 / 15
FuncPathMSD.cpp +
92.6%92.6%
+
92.6 %75 / 8187.5 %7 / 8
FuncPathGeneral.cpp +
77.7%77.7%
+
77.7 %101 / 13088.9 %8 / 9
Custom.cpp +
95.1%95.1%
+
95.1 %58 / 6190.0 %9 / 10
Function.h +
87.5%87.5%
+
87.5 %7 / 8100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/index-sort-l.html b/coverage/function/index-sort-l.html new file mode 100644 index 0000000000..b6e8ca0132 --- /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:904105985.4 %
Date:2024-06-10 08:19:14Functions:8410084.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Target.cpp +
22.2%22.2%
+
22.2 %6 / 2742.9 %3 / 7
Ensemble.cpp +
63.1%63.1%
+
63.1 %82 / 13085.7 %6 / 7
FuncPathGeneral.cpp +
77.7%77.7%
+
77.7 %101 / 13088.9 %8 / 9
Function.h +
87.5%87.5%
+
87.5 %7 / 8100.0 %3 / 3
FuncSumHills.cpp +
88.1%88.1%
+
88.1 %290 / 32986.7 %13 / 15
FuncPathMSD.cpp +
92.6%92.6%
+
92.6 %75 / 8187.5 %7 / 8
Combine.cpp +
93.6%93.6%
+
93.6 %44 / 4785.7 %6 / 7
Custom.cpp +
95.1%95.1%
+
95.1 %58 / 6190.0 %9 / 10
Stats.cpp +
96.0%96.0%
+
96.0 %96 / 10085.7 %6 / 7
Function.cpp +
97.5%97.5%
+
97.5 %39 / 4083.3 %5 / 6
Sort.cpp +
100.0%
+
100.0 %27 / 2785.7 %6 / 7
LocalEnsemble.cpp +
100.0%
+
100.0 %32 / 3285.7 %6 / 7
Piecewise.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/function/index.html b/coverage/function/index.html new file mode 100644 index 0000000000..dc93b02e9c --- /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:904105985.4 %
Date:2024-06-10 08:19:14Functions:8410084.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Combine.cpp +
93.6%93.6%
+
93.6 %44 / 4785.7 %6 / 7
Custom.cpp +
95.1%95.1%
+
95.1 %58 / 6190.0 %9 / 10
Ensemble.cpp +
63.1%63.1%
+
63.1 %82 / 13085.7 %6 / 7
FuncPathGeneral.cpp +
77.7%77.7%
+
77.7 %101 / 13088.9 %8 / 9
FuncPathMSD.cpp +
92.6%92.6%
+
92.6 %75 / 8187.5 %7 / 8
FuncSumHills.cpp +
88.1%88.1%
+
88.1 %290 / 32986.7 %13 / 15
Function.cpp +
97.5%97.5%
+
97.5 %39 / 4083.3 %5 / 6
Function.h +
87.5%87.5%
+
87.5 %7 / 8100.0 %3 / 3
LocalEnsemble.cpp +
100.0%
+
100.0 %32 / 3285.7 %6 / 7
Piecewise.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
Sort.cpp +
100.0%
+
100.0 %27 / 2785.7 %6 / 7
Stats.cpp +
96.0%96.0%
+
96.0 %96 / 10085.7 %6 / 7
Target.cpp +
22.2%22.2%
+
22.2 %6 / 2742.9 %3 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..12fafb6583 --- /dev/null +++ b/coverage/funnel/FPS.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:10210696.2 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel9FUNNEL_PSC2ERKNS_13ActionOptionsE0
_ZN4PLMD6funnel9FUNNEL_PSD2Ev0
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe1206createERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PSC1ERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PSD0Ev5
_ZN4PLMD6funnel9FUNNEL_PSD1Ev5
_ZN4PLMD6funnel9FUNNEL_PS16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6funnel9FUNNEL_PS9calculateEv150
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe120C2Ev3473
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe120D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/funnel/FPS.cpp.func.html b/coverage/funnel/FPS.cpp.func.html new file mode 100644 index 0000000000..cfcfd6d66b --- /dev/null +++ b/coverage/funnel/FPS.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:10210696.2 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe1206createERKNS_13ActionOptionsE5
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe120C2Ev3473
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe120D2Ev3473
_ZN4PLMD6funnel9FUNNEL_PS16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6funnel9FUNNEL_PS9calculateEv150
_ZN4PLMD6funnel9FUNNEL_PSC1ERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PSC2ERKNS_13ActionOptionsE0
_ZN4PLMD6funnel9FUNNEL_PSD0Ev5
_ZN4PLMD6funnel9FUNNEL_PSD1Ev5
_ZN4PLMD6funnel9FUNNEL_PSD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/funnel/FPS.cpp.gcov.html b/coverage/funnel/FPS.cpp.gcov.html new file mode 100644 index 0000000000..12f40572ae --- /dev/null +++ b/coverage/funnel/FPS.cpp.gcov.html @@ -0,0 +1,409 @@ + + + + + + + + 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:10210696.2 %
Date:2024-06-10 08:19:14Functions:81080.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 "colvar/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 "core/PlumedMain.h"
+      18             : #include "core/Atoms.h"
+      19             : #include <iostream>
+      20             : #include "tools/RMSD.h"
+      21             : 
+      22             : using namespace std;
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace funnel {
+      26             : 
+      27             : //+PLUMEDOC FUNNELMOD_COLVAR FUNNEL_PS
+      28             : /*
+      29             : FUNNEL_PS implements the Funnel-Metadynamics (FM) technique in PLUMED 2.
+      30             : 
+      31             : Please read the FM \cite limongelli2013funnel \cite raniolo2020ligand papers to better understand the notions hereby reported.
+      32             : 
+      33             : This colvar evaluates the position of a ligand of interest with respect to a given line, built from the two points
+      34             : A and B, and should be used together with the \ref FUNNEL bias.
+      35             : The constructed line represents the axis of the funnel-shape restraint potential, which should be placed so
+      36             : as to include the portion of a macromolecule (i.e., protein, DNA, etc.) that should be explored.
+      37             : Since it is important that the position of the line is updated based on the motion of the macromolecule during
+      38             : the simulation, this colvar incorporates an alignment method. The latter uses the TYPE=OPTIMAL option to remove
+      39             : motions due to rotation and translation of the macromolecule with respect to a reference structure, which is
+      40             : provided by the user. In order to accomplish the task, an optimal alignment matrix is calculated using the
+      41             : Kearsley \cite kearsley algorithm.
+      42             : The reference structure should be given as a pdb file, containing only the atoms of the macromolecule or a
+      43             : selection of them (e.g., the protein CA atoms of secondary structures). In contrast to the methods reported in
+      44             : the \ref dists, the values reported in the occupancy and beta-factor columns of the pdb file are not important
+      45             : since they will be overwritten and replaced by the value 1.00 during the procedure. It is important to understand
+      46             : that all atoms in the file will be used for the alignment, even if they display 0.00 in the occupancy column.
+      47             : 
+      48             : The ligand can be represented by one single atom or the center of mass (COM) of a group of atoms that should be
+      49             : provided by the user.
+      50             : 
+      51             : By default FUNNEL_PS is computed taking into account periodic boundary conditions. Since PLUMED 2.5, molecules are
+      52             : rebuilt using a procedure that is equivalent to that done in \ref WHOLEMOLECULES. We note that this action is local
+      53             : to this colvar, thus it does not modify the coordinates stored in PLUMED. Moreover, FUNNEL_PS requires an ANCHOR atom
+      54             : to be specified in order to facilitate the reconstruction of periodic boundary conditions. This atom should be the
+      55             : closest macromolecule's atom to the ligand and it should reduce the risk of ligand "warping" in the simulation box.
+      56             : Nevertheless, we highly recommend to add to the PLUMED input file a custom line of \ref WHOLEMOLECULES, in order to
+      57             : be sure of reconstructing the ligand together with the macromolecule (please look the examples). In this case, the user
+      58             : can use the NOPBC flag to turn off the internal periodic boundary condition reconstruction.
+      59             : 
+      60             : FUNNEL_PS is divided in two components (fps.lp and fps.ld) which evaluate the projection of the ligand along the funnel line
+      61             : and the distance from it, respectively. The values attributed to these two components are then used together with the
+      62             : potential file created by the \ref FUNNEL bias to define if the ligand is within or not in the funnel-shape restraint
+      63             : potential. In the latter case, the potential will force the ligand to enter within the funnel boundaries.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : The following input tells plumed to print the FUNNEL_PS components for the COM of a ligand. The inputs are a reference structure,
+      68             : which is the structure used for the alignment, the COM of the molecule we want to track, and 2 points in the Cartesian space
+      69             : (i.e., x, y, and z) to draw the line representing the funnel axis.
+      70             : \plumedfile
+      71             : lig: COM ATOMS=2446,2447,2448,2449,2451
+      72             : fps: FUNNEL_PS REFERENCE=protein.pdb LIGAND=lig POINTS=5.3478,-0.7278,2.4746,7.3785,6.7364,-9.3624
+      73             : PRINT ARG=fps.lp,fps.ld
+      74             : \endplumedfile
+      75             : 
+      76             : It is recommended to add a line to force the reconstruction of the periodic boundary conditions. In the following example,
+      77             : \ref WHOLEMOLECULES was added to make sure that the ligand was reconstructed together with the protein. The list contains
+      78             : all the atoms reported in the start.pdb file followed by the ANCHOR atom and the ligand. All atoms should be contained in the
+      79             : same entity and the correct order.
+      80             : \plumedfile
+      81             : 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,
+      82             : 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,
+      83             : 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,
+      84             : 2911,2927,2948,2962,2472,3221,3224,3225,3228,3229,3231,3233,3235,3237
+      85             : lig: COM ATOMS=3221,3224,3225,3228,3229,3231,3233,3235,3237
+      86             : fps: FUNNEL_PS LIGAND=lig REFERENCE=start.pdb ANCHOR=2472 POINTS=4.724,5.369,4.069,4.597,5.721,4.343
+      87             : PRINT ARG=fps.lp,fps.ld
+      88             : \endplumedfile
+      89             : 
+      90             : */
+      91             : //+ENDPLUMEDOC
+      92             : 
+      93             : 
+      94             : class FUNNEL_PS : public Colvar {
+      95             : 
+      96             :   // Those are arrays that I created for the colvar
+      97             :   std::vector<AtomNumber> ligand_com;
+      98             :   std::vector<AtomNumber> anchor;
+      99             :   std::vector<AtomNumber> numbers;
+     100             :   bool pbc;
+     101             :   PLMD::RMSD* alignment;
+     102             :   PLMD::PDB* pdb;
+     103             :   bool squared;
+     104             : private:
+     105             :   vector<double> points;
+     106             : public:
+     107             :   explicit FUNNEL_PS(const ActionOptions&);
+     108             : // active methods:
+     109             :   virtual void calculate();
+     110             :   static void registerKeywords(Keywords& keys);
+     111             : // I need a method in RMSDCoreCalc and these were requested
+     112             :   std::vector<double> align;
+     113             :   std::vector<double> displace;
+     114             : // It is written no more desctructors, but an expert said it's necessary for imported variables (pdb and alignment) or else memory leak
+     115             :   ~FUNNEL_PS();
+     116             : };
+     117             : 
+     118             : using namespace std;
+     119             : 
+     120       10429 : PLUMED_REGISTER_ACTION(FUNNEL_PS,"FUNNEL_PS")
+     121             : 
+     122           6 : void FUNNEL_PS::registerKeywords(Keywords& keys) {
+     123           6 :   Colvar::registerKeywords( keys );
+     124          12 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the structure you would like to align.");
+     125          12 :   keys.add("atoms","LIGAND","This MUST be a single atom, normally the COM of the ligand");
+     126          12 :   keys.add("atoms","ANCHOR","Closest protein atom to the ligand, picked to avoid pbc problems during the simulation");
+     127          12 :   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.");
+     128          12 :   keys.addFlag("SQUARED-ROOT",false,"Used to initialize the creation of the alignment variable");
+     129          12 :   keys.addOutputComponent("lp","default","the position along the funnel line");
+     130          12 :   keys.addOutputComponent("ld","default","the distance from the funnel line");
+     131           6 : }
+     132             : 
+     133           5 : FUNNEL_PS::FUNNEL_PS(const ActionOptions&ao):
+     134             :   PLUMED_COLVAR_INIT(ao),
+     135           5 :   pbc(true),squared(true)
+     136             : {
+     137             :   string reference;
+     138          10 :   parse("REFERENCE",reference);
+     139             :   string type;
+     140           5 :   type.assign("OPTIMAL");
+     141          10 :   parseAtomList("LIGAND",ligand_com);
+     142           5 :   if(ligand_com.size()!=1)
+     143           0 :     error("Number of specified atoms should be one, normally the COM of the ligand");
+     144           5 :   parseVector("POINTS",points);
+     145           5 :   bool nopbc=!pbc;
+     146           5 :   parseFlag("NOPBC",nopbc);
+     147           5 :   pbc=!nopbc;
+     148             :   bool sq;
+     149           5 :   parseFlag("SQUARED-ROOT",sq);
+     150           5 :   if (sq) {
+     151           0 :     squared=false;
+     152             :   }
+     153           5 :   parseAtomList("ANCHOR",anchor);
+     154           5 :   checkRead();
+     155             : 
+     156           5 :   pdb = new PDB();
+     157             : 
+     158             :   // read everything in ang and transform to nm if we are not in natural units
+     159          10 :   if( !pdb->read(reference,plumed.getAtoms().usingNaturalUnits(),0.1/ActionAtomistic::atoms.getUnits().getLength()) )
+     160           0 :     error("missing input file " + reference );
+     161             : 
+     162           5 :   alignment = new RMSD();
+     163             : 
+     164             :   bool remove_com=true;
+     165             :   bool normalize_weights=true;
+     166             :   // here displace is a simple vector of ones
+     167           5 :   align=pdb->getOccupancy();
+     168       16195 :   for(unsigned i=0; i<align.size(); i++) {
+     169       16190 :     align[i]=1.;
+     170             :   } ;
+     171           5 :   displace=pdb->getBeta();
+     172       16195 :   for(unsigned i=0; i<displace.size(); i++) {
+     173       16190 :     displace[i]=1.;
+     174             :   } ;
+     175             :   // reset again to reimpose uniform weights (safe to disable this)
+     176           5 :   alignment->set(align,displace,pdb->getPositions(),type,remove_com,normalize_weights);
+     177             : 
+     178             : 
+     179             : 
+     180             :   // Array with inside both the structure to align and the atom to be aligned
+     181           5 :   numbers=pdb->getAtomNumbers();
+     182           5 :   numbers.push_back(anchor[0]);
+     183           5 :   numbers.push_back(ligand_com[0]);
+     184             : 
+     185           5 :   log.printf("  average from file %s\n",reference.c_str());
+     186           5 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     187             : 
+     188           5 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     189           0 :   else    log.printf("  without periodic boundary conditions\n");
+     190             : 
+     191           5 :   addComponentWithDerivatives("lp");
+     192           5 :   componentIsNotPeriodic("lp");
+     193           5 :   addComponentWithDerivatives("ld");
+     194           5 :   componentIsNotPeriodic("ld");
+     195             : 
+     196           5 :   requestAtoms( numbers );
+     197             : 
+     198           5 : }
+     199             : 
+     200          10 : FUNNEL_PS::~FUNNEL_PS() {
+     201           5 :   delete alignment;
+     202           5 :   delete pdb;
+     203          10 : }
+     204             : 
+     205             : // calculator
+     206         150 : void FUNNEL_PS::calculate() {
+     207             : 
+     208         150 :   if(pbc) makeWhole();
+     209             : 
+     210         150 :   Tensor Rotation;
+     211             :   Matrix<std::vector<Vector> > drotdpos(3,3);
+     212             :   std::vector<Vector> alignedpos;
+     213             :   std::vector<Vector> centeredpos;
+     214             :   std::vector<Vector> centeredref;
+     215             :   std::vector<Vector> ddistdpos;
+     216             : 
+     217             :   std::vector<Vector> buffer;
+     218             : 
+     219         150 :   Vector centerreference;
+     220         150 :   Vector centerpositions;
+     221             : 
+     222             :   // Created only to give the correct object to calc_FitElements
+     223             :   std::vector<Vector> sourceAllPositions;
+     224             :   std::vector<Vector> sourcePositions;
+     225             : 
+     226             :   // SourcePositions contains only the coordinates of the COM of the ligand, we need only this point
+     227         150 :   sourceAllPositions=getPositions();
+     228         150 :   sourcePositions=sourceAllPositions;
+     229         150 :   sourcePositions.resize(sourcePositions.size()-2);// just the protein
+     230             : 
+     231             :   // The two points that define the axis : this can be moved in the initialization
+     232         150 :   Vector p1 = VectorGeneric<3>(points[0],points[1],points[2]);
+     233         150 :   Vector p2 = VectorGeneric<3>(points[3],points[4],points[5]);
+     234         150 :   Vector s = p2 - p1;
+     235             : 
+     236             :   // I call the method calc_FitElements that initializes all feature that I need
+     237             :   // except for centerreference that I need to calculate from scratch
+     238             :   // Buffer has no meaning but I had to fulfill the requirements of calc_FitElements
+     239         150 :   double rmsd = alignment->calc_FitElements( sourcePositions, Rotation, drotdpos, buffer, centerpositions, squared);
+     240             : 
+     241             :   // To Plumed developers: it would be interesting to make the functions to calculate centers of mass public or protected
+     242         150 :   centerreference.zero();
+     243      485850 :   for(unsigned i=0; i<pdb->size(); i++) {
+     244      485700 :     centerreference+=pdb->getPositions()[i]*align[i]/align.size();
+     245             :   }
+     246             : 
+     247             :   /*
+     248             :   // I cancelled the additional lines in the library of RMSD.h, thus I am missing the center of the reference
+     249             :   // Creating variable kito to extract only the center of the reference, since no method is calling
+     250             :   // function getReferenceCenter()
+     251             :   PLMD::RMSDCoreData* kito; kito = new RMSDCoreData(align,displace,sourcePositions,pdb->getPositions());
+     252             :   centerreference = kito->getReferenceCenter();
+     253             :   delete kito;
+     254             :   */
+     255             : 
+     256             :   // DEBUG
+     257             :   /*    log.printf(" RMSD: %13.6lf\n",rmsd );
+     258             :       log.printf(" cpos: %13.6lf %13.6lf %13.6lf\n",centerpositions[0],centerpositions[1],centerpositions[2] );
+     259             :       log.printf(" Rotation: %13.6lf %13.6lf %13.6lf\n",Rotation[0][0],Rotation[0][1],Rotation[0][2] );
+     260             :       log.printf("           %13.6lf %13.6lf %13.6lf\n",Rotation[1][0],Rotation[1][1],Rotation[1][2] );
+     261             :       log.printf("           %13.6lf %13.6lf %13.6lf\n",Rotation[2][0],Rotation[2][1],Rotation[2][2] );
+     262             :   */
+     263             : 
+     264             :   // the position is   Rot(ligand-com_prot_md)+ com_prot_ref
+     265         150 :   Vector ligand_centered =getPositions().back()-centerpositions;
+     266         150 :   Vector ligand_aligned =matmul(Rotation,ligand_centered);
+     267         150 :   Vector v = ligand_aligned +centerreference -p1;
+     268             : 
+     269             :   // DEBUG
+     270             : //    log.printf(" ligando: %13.6lf %13.6lf %13.6lf\n",getPositions().back()[0],getPositions().back()[1],getPositions().back()[2] );
+     271             : 
+     272             :   //Projection vector v onto s
+     273             : 
+     274         150 :   Vector prj = (dotProduct(s,v)/dotProduct(s,s))*s;
+     275         150 :   const double prj_length = prj.modulo() ;
+     276             :   const double inv_prj_length = 1.0/prj_length;
+     277             : 
+     278         150 :   Vector height = v - prj;
+     279         150 :   const double prj_height = height.modulo() ;
+     280         150 :   const double inv_prj_height = 1.0/prj_height;
+     281             : 
+     282             :   // derivative of the prj: only on the com of the ligand
+     283         150 :   Vector der_prj;
+     284         150 :   der_prj=s/s.modulo();
+     285             : 
+     286             :   // derivative of the height: only on the com of the ligand
+     287         150 :   Vector der_height(inv_prj_height*(height[0]-(s[0]/s.modulo2())*dotProduct(height,s)),
+     288         150 :                     inv_prj_height*(height[1]-(s[1]/s.modulo2())*dotProduct(height,s)),
+     289         150 :                     inv_prj_height*(height[2]-(s[2]/s.modulo2())*dotProduct(height,s)));
+     290             : 
+     291         150 :   Value* valuelp=getPntrToComponent("lp");
+     292         150 :   Value* valueld=getPntrToComponent("ld");
+     293         150 :   valuelp->set(dotProduct(s,v)/s.modulo()); // this includes the sign
+     294             :   valueld->set(prj_height);
+     295             : 
+     296             :   // DEBUG
+     297             : //    log.printf(" Dopo: %13.6lf  %13.6lf\n",dotProduct(s,v)/s.modulo(),prj_height );
+     298             : 
+     299         150 :   setAtomsDerivatives(valuelp,getNumberOfAtoms()-1,matmul(transpose(Rotation),der_prj));
+     300         150 :   setAtomsDerivatives(valueld,getNumberOfAtoms()-1,matmul(transpose(Rotation),der_height));
+     301             : 
+     302         150 :   Vector der_h;
+     303         150 :   Vector der_l;
+     304         150 :   double weight=1./float(getNumberOfAtoms()-2.);
+     305             : 
+     306      485850 :   for(unsigned iat=0; iat<getNumberOfAtoms()-2; iat++) {
+     307      485700 :     der_h.zero();
+     308      485700 :     der_l.zero();
+     309     1942800 :     for(unsigned a=0; a<3; a++) {
+     310     5828400 :       for(unsigned b=0; b<3; b++) {
+     311    17485200 :         for(unsigned g=0; g<3; g++) {
+     312    13113900 :           der_h[a]+=der_height[b]*drotdpos[b][g][iat][a]*ligand_centered[g];
+     313    13113900 :           der_l[a]+=der_prj[b]*drotdpos[b][g][iat][a]*ligand_centered[g];
+     314             :         }
+     315     4371300 :         der_h[a]-=der_height[b]*Rotation[b][a]*weight;
+     316     4371300 :         der_l[a]-=der_prj[b]*Rotation[b][a]*weight;
+     317             :       }
+     318             :     }
+     319      485700 :     setAtomsDerivatives(valuelp,iat,der_l);
+     320      485700 :     setAtomsDerivatives(valueld,iat,der_h);
+     321             :   }
+     322             : 
+     323         150 :   setBoxDerivativesNoPbc(valuelp);
+     324         150 :   setBoxDerivativesNoPbc(valueld);
+     325             : 
+     326         150 : }
+     327             : 
+     328             : }
+     329             : }
+     330             : 
+     331             : 
+     332             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..520e545120 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe1436createERKNS_13ActionOptionsE4
_ZN4PLMD6funnel6FunnelC1ERKNS_13ActionOptionsE4
_ZN4PLMD6funnel6Funnel16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6funnel6Funnel9calculateEv120
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe143C2Ev3473
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe143D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.func.html b/coverage/funnel/Funnel.cpp.func.html new file mode 100644 index 0000000000..169da19696 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe1436createERKNS_13ActionOptionsE4
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe143C2Ev3473
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe143D2Ev3473
_ZN4PLMD6funnel6Funnel10createBIASERKdS3_S3_S3_S3_S3_S3_S3_S3_RKbS3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_3
_ZN4PLMD6funnel6Funnel16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6funnel6Funnel9calculateEv120
_ZN4PLMD6funnel6FunnelC1ERKNS_13ActionOptionsE4
_ZN4PLMD6funnel6FunnelC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.gcov.html b/coverage/funnel/Funnel.cpp.gcov.html new file mode 100644 index 0000000000..4230c9fd43 --- /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-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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 "bias/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       10427 : PLUMED_REGISTER_ACTION(Funnel,"FUNNEL")
+     144             : 
+     145           5 : void Funnel::registerKeywords(Keywords& keys) {
+     146           5 :   Bias::registerKeywords(keys);
+     147           5 :   keys.use("ARG");
+     148          10 :   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          10 :   keys.addFlag("SPARSE",false,"specifies that the external potential uses a sparse grid");
+     150          10 :   keys.addFlag("SPHERE",false, "The Funnel potential including the binding site can be spherical instead of a cone");
+     151          10 :   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          10 :   keys.add("optional","NBINS","number of bins along fps.lp");
+     158          10 :   keys.add("optional","NBINZ","number of bins along fps.ld");
+     159          10 :   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          10 :   keys.add("optional","KAPPA","constant to be used for the funnel-shape restraint potential");
+     161          10 :   keys.add("optional","RCYL","radius of the cylindrical section");
+     162          10 :   keys.add("optional","SAFETY","To be used in case the SPHERE flag is chosen, it regulates how much the potential extends (in nm)");
+     163          10 :   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          10 :   keys.add("optional","ALPHA","angle to change the width of the cone section");
+     165             :   //Defining compulsory arguments
+     166          10 :   keys.add("compulsory","MAXS","MAXS","maximum value assumed by fps.lp");
+     167          10 :   keys.add("compulsory","ZCC","ZCC","switching point between cylinder and cone");
+     168          10 :   keys.add("compulsory","FILE","name of the Funnel potential file");
+     169          10 :   keys.addFlag("WALKERS_MPI",false,"To be used when gromacs + multiple walkers are used");
+     170           5 : }
+     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             :   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.15
+
+ + + diff --git a/coverage/funnel/index-sort-f.html b/coverage/funnel/index-sort-f.html new file mode 100644 index 0000000000..94ef698394 --- /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:25425998.1 %
Date:2024-06-10 08:19:14Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.2%96.2%
+
96.2 %102 / 10680.0 %8 / 10
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15387.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/funnel/index-sort-l.html b/coverage/funnel/index-sort-l.html new file mode 100644 index 0000000000..bcd76e8e79 --- /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:25425998.1 %
Date:2024-06-10 08:19:14Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.2%96.2%
+
96.2 %102 / 10680.0 %8 / 10
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15387.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/funnel/index.html b/coverage/funnel/index.html new file mode 100644 index 0000000000..1b08d88cd1 --- /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:25425998.1 %
Date:2024-06-10 08:19:14Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.2%96.2%
+
96.2 %102 / 10680.0 %8 / 10
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15387.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gcov.css b/coverage/gcov.css new file mode 100644 index 0000000000..bfd0a83e10 --- /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: black; + 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 0000000000..75fa11fb96 --- /dev/null +++ b/coverage/generic/Debug.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:5757100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5DebugC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe636createERKNS_13ActionOptionsE6
_ZN4PLMD7generic5DebugC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic5Debug16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7generic5Debug5applyEv140
_ZN4PLMD7generic5Debug9calculateEv140
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe63C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe63D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Debug.cpp.func.html b/coverage/generic/Debug.cpp.func.html new file mode 100644 index 0000000000..e4df90a80e --- /dev/null +++ b/coverage/generic/Debug.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:5757100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe636createERKNS_13ActionOptionsE6
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe63C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe63D2Ev3473
_ZN4PLMD7generic5Debug16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7generic5Debug5applyEv140
_ZN4PLMD7generic5Debug9calculateEv140
_ZN4PLMD7generic5DebugC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic5DebugC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Debug.cpp.gcov.html b/coverage/generic/Debug.cpp.gcov.html new file mode 100644 index 0000000000..fb3b5c5f4d --- /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:5757100.0 %
Date:2024-06-10 08:19:14Functions: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             : #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       10431 : PLUMED_REGISTER_ACTION(Debug,"DEBUG")
+      64             : 
+      65           7 : void Debug::registerKeywords( Keywords& keys ) {
+      66           7 :   Action::registerKeywords( keys );
+      67           7 :   ActionPilot::registerKeywords(keys);
+      68          14 :   keys.add("compulsory","STRIDE","1","the frequency with which this action is to be performed");
+      69          14 :   keys.addFlag("logActivity",false,"write in the log which actions are inactive and which are inactive");
+      70          14 :   keys.addFlag("logRequestedAtoms",false,"write in the log which atoms have been requested at a given time");
+      71          14 :   keys.addFlag("NOVIRIAL",false,"switch off the virial contribution for the entirety of the simulation");
+      72          14 :   keys.addFlag("DETAILED_TIMERS",false,"switch on detailed timers");
+      73          14 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+      74           7 : }
+      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         115 :     for(const auto & p : actionSet) {
+     112         105 :       if(dynamic_cast<Debug*>(p.get()))continue;
+     113          90 :       if(p->isActive()) a++;
+     114             :     };
+     115          10 :     if(a>0) {
+     116           9 :       ofile<<"activity at step "<<getStep()<<": ";
+     117         107 :       for(const auto & p : actionSet) {
+     118          98 :         if(dynamic_cast<Debug*>(p.get()))continue;
+     119          85 :         if(p->isActive()) ofile.printf("+");
+     120          27 :         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          34 :     plumed.cmd("createFullList",&n);
+     130          34 :     plumed.cmd("getFullList",&l);
+     131         213 :     for(int i=0; i<n; i++) ofile.printf(" %d",l[i]);
+     132          17 :     ofile.printf("\n");
+     133          34 :     plumed.cmd("clearFullList");
+     134             :   }
+     135             : 
+     136         140 : }
+     137             : 
+     138             : }
+     139             : }
+     140             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7c2b288f87 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:11912198.3 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe1436createERKNS_13ActionOptionsE90
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE90
_ZN4PLMD7generic9DumpAtomsD0Ev90
_ZN4PLMD7generic9DumpAtomsD1Ev90
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE91
_ZN4PLMD7generic9DumpAtoms6updateEv790
_ZN4PLMD7generic9DumpAtoms5applyEv885
_ZN4PLMD7generic9DumpAtoms9calculateEv885
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe143C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe143D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.func.html b/coverage/generic/DumpAtoms.cpp.func.html new file mode 100644 index 0000000000..df1e13fc60 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:11912198.3 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe1436createERKNS_13ActionOptionsE90
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe143C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe143D2Ev3473
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE91
_ZN4PLMD7generic9DumpAtoms5applyEv885
_ZN4PLMD7generic9DumpAtoms6updateEv790
_ZN4PLMD7generic9DumpAtoms9calculateEv885
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE90
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD0Ev90
_ZN4PLMD7generic9DumpAtomsD1Ev90
_ZN4PLMD7generic9DumpAtomsD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.gcov.html b/coverage/generic/DumpAtoms.cpp.gcov.html new file mode 100644 index 0000000000..bd44246e9c --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.gcov.html @@ -0,0 +1,389 @@ + + + + + + + + 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:11912198.3 %
Date:2024-06-10 08:19:14Functions:101283.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 "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 "core/Atoms.h"
+      29             : #include "tools/Units.h"
+      30             : #include <cstdio>
+      31             : #include <memory>
+      32             : #include "core/GenericMolInfo.h"
+      33             : #include "core/ActionSet.h"
+      34             : #include "xdrfile/xdrfile_xtc.h"
+      35             : #include "xdrfile/xdrfile_trr.h"
+      36             : 
+      37             : 
+      38             : namespace PLMD
+      39             : {
+      40             : namespace generic {
+      41             : 
+      42             : //+PLUMEDOC PRINTANALYSIS DUMPATOMS
+      43             : /*
+      44             : Dump selected atoms on a file.
+      45             : 
+      46             : This command can be used to output the positions of a particular set of atoms.
+      47             : The atoms required are output in a xyz or gro formatted file.
+      48             : If PLUMED has been compiled with xdrfile support, then also xtc and trr files can be written.
+      49             : To this aim one should install xdrfile library (http://www.gromacs.org/Developer_Zone/Programming_Guide/XTC_Library).
+      50             : If the xdrfile library is installed properly the PLUMED configure script should be able to
+      51             : detect it and enable it.
+      52             : The type of file is automatically detected from the file extension, but can be also
+      53             : enforced with TYPE.
+      54             : Importantly, if your
+      55             : input file contains actions that edit the atoms position (e.g. \ref WHOLEMOLECULES)
+      56             : and the DUMPATOMS command appears after this instruction, then the edited
+      57             : atom positions are output.
+      58             : You can control the buffering of output using the \ref FLUSH keyword on a separate line.
+      59             : 
+      60             : Units of the printed file can be controlled with the UNITS keyword. By default PLUMED units as
+      61             : controlled in the \ref UNITS command are used, but one can override it e.g. with UNITS=A.
+      62             : Notice that gro/xtc/trr files can only contain coordinates in nm.
+      63             : 
+      64             : \par Examples
+      65             : 
+      66             : The following input instructs plumed to print out the positions of atoms
+      67             : 1-10 together with the position of the center of mass of atoms 11-20 every
+      68             : 10 steps to a file called file.xyz.
+      69             : \plumedfile
+      70             : COM ATOMS=11-20 LABEL=c1
+      71             : DUMPATOMS STRIDE=10 FILE=file.xyz ATOMS=1-10,c1
+      72             : \endplumedfile
+      73             : Notice that the coordinates in the xyz file will be expressed in nm, since these
+      74             : are the defaults units in PLUMED. If you want the xyz file to be expressed in A, you should use the
+      75             : following input
+      76             : \plumedfile
+      77             : COM ATOMS=11-20 LABEL=c1
+      78             : DUMPATOMS STRIDE=10 FILE=file.xyz ATOMS=1-10,c1 UNITS=A
+      79             : \endplumedfile
+      80             : As an alternative, you might want to set all the length used by PLUMED to Angstrom using the \ref UNITS
+      81             : action. However, this latter choice will affect all your input and output.
+      82             : 
+      83             : The following input is very similar but dumps a .gro (gromacs) file,
+      84             : which also contains atom and residue names.
+      85             : \plumedfile
+      86             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      87             : # this is required to have proper atom names:
+      88             : MOLINFO STRUCTURE=reference.pdb
+      89             : # if omitted, atoms will have "X" name...
+      90             : 
+      91             : COM ATOMS=11-20 LABEL=c1
+      92             : DUMPATOMS STRIDE=10 FILE=file.gro ATOMS=1-10,c1
+      93             : # notice that last atom is a virtual one and will not have
+      94             : # a correct name in the resulting gro file
+      95             : \endplumedfile
+      96             : 
+      97             : The `file.gro` will contain coordinates expressed in nm, since this is the convention for gro files.
+      98             : 
+      99             : In case you have compiled PLUMED with `xdrfile` library, you might even write xtc or trr files as follows
+     100             : \plumedfile
+     101             : COM ATOMS=11-20 LABEL=c1
+     102             : DUMPATOMS STRIDE=10 FILE=file.xtc ATOMS=1-10,c1
+     103             : \endplumedfile
+     104             : Notice that xtc files are significantly smaller than gro and xyz files.
+     105             : 
+     106             : Finally, consider that gro and xtc file store coordinates with limited precision set by the
+     107             : `PRECISION` keyword. Default value is 3, which means "3 digits after dot" in nm (1/1000 of a nm).
+     108             : The following will write a larger xtc file with high resolution coordinates:
+     109             : \plumedfile
+     110             : COM ATOMS=11-20 LABEL=c1
+     111             : DUMPATOMS STRIDE=10 FILE=file.xtc ATOMS=1-10,c1 PRECISION=7
+     112             : \endplumedfile
+     113             : 
+     114             : 
+     115             : 
+     116             : */
+     117             : //+ENDPLUMEDOC
+     118             : 
+     119             : class DumpAtoms:
+     120             :   public ActionAtomistic,
+     121             :   public ActionPilot
+     122             : {
+     123             :   OFile of;
+     124             :   double lenunit;
+     125             :   int iprecision;
+     126             :   std::vector<std::string> names;
+     127             :   std::vector<unsigned>    residueNumbers;
+     128             :   std::vector<std::string> residueNames;
+     129             :   std::string type;
+     130             :   std::string fmt_gro_pos;
+     131             :   std::string fmt_gro_box;
+     132             :   std::string fmt_xyz;
+     133             :   xdrfile::XDRFILE* xd;
+     134             : public:
+     135             :   explicit DumpAtoms(const ActionOptions&);
+     136             :   ~DumpAtoms();
+     137             :   static void registerKeywords( Keywords& keys );
+     138         885 :   void calculate() override {}
+     139         885 :   void apply() override {}
+     140             :   void update() override ;
+     141             : };
+     142             : 
+     143       10599 : PLUMED_REGISTER_ACTION(DumpAtoms,"DUMPATOMS")
+     144             : 
+     145          91 : void DumpAtoms::registerKeywords( Keywords& keys ) {
+     146          91 :   Action::registerKeywords( keys );
+     147          91 :   ActionPilot::registerKeywords( keys );
+     148          91 :   ActionAtomistic::registerKeywords( keys );
+     149         182 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+     150         182 :   keys.add("atoms", "ATOMS", "the atom indices whose positions you would like to print out");
+     151         182 :   keys.add("compulsory", "FILE", "file on which to output coordinates; extension is automatically detected");
+     152         182 :   keys.add("compulsory", "UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+     153         182 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+     154         182 :   keys.add("optional", "TYPE","file type, either xyz, gro, xtc, or trr, can override an automatically detected file extension");
+     155          91 :   keys.use("RESTART");
+     156          91 :   keys.use("UPDATE_FROM");
+     157          91 :   keys.use("UPDATE_UNTIL");
+     158          91 : }
+     159             : 
+     160          90 : DumpAtoms::DumpAtoms(const ActionOptions&ao):
+     161             :   Action(ao),
+     162             :   ActionAtomistic(ao),
+     163             :   ActionPilot(ao),
+     164          90 :   iprecision(3)
+     165             : {
+     166             :   std::vector<AtomNumber> atoms;
+     167             :   std::string file;
+     168         180 :   parse("FILE",file);
+     169          90 :   if(file.length()==0) error("name out output file was not specified");
+     170          90 :   type=Tools::extension(file);
+     171          90 :   log<<"  file name "<<file<<"\n";
+     172         179 :   if(type=="gro" || type=="xyz" || type=="xtc" || type=="trr") {
+     173          74 :     log<<"  file extension indicates a "<<type<<" file\n";
+     174             :   } else {
+     175          16 :     log<<"  file extension not detected, assuming xyz\n";
+     176             :     type="xyz";
+     177             :   }
+     178             :   std::string ntype;
+     179         180 :   parse("TYPE",ntype);
+     180          90 :   if(ntype.length()>0) {
+     181           5 :     if(ntype!="xyz" && ntype!="gro" && ntype!="xtc" && ntype!="trr"
+     182           0 :       ) error("TYPE cannot be understood");
+     183           2 :     log<<"  file type enforced to be "<<ntype<<"\n";
+     184             :     type=ntype;
+     185             :   }
+     186             : 
+     187             :   fmt_gro_pos="%8.3f";
+     188             :   fmt_gro_box="%12.7f";
+     189             :   fmt_xyz="%f";
+     190             : 
+     191             :   std::string precision;
+     192         180 :   parse("PRECISION",precision);
+     193          90 :   if(precision.length()>0) {
+     194           9 :     Tools::convert(precision,iprecision);
+     195           9 :     log<<"  with precision "<<iprecision<<"\n";
+     196             :     std::string a,b;
+     197           9 :     Tools::convert(iprecision+5,a);
+     198           9 :     Tools::convert(iprecision,b);
+     199          18 :     fmt_gro_pos="%"+a+"."+b+"f";
+     200             :     fmt_gro_box=fmt_gro_pos;
+     201             :     fmt_xyz=fmt_gro_box;
+     202             :   }
+     203             : 
+     204         180 :   parseAtomList("ATOMS",atoms);
+     205             : 
+     206         180 :   std::string unitname; parse("UNITS",unitname);
+     207          90 :   if(unitname!="PLUMED") {
+     208           4 :     Units myunit; myunit.setLength(unitname);
+     209           6 :     if(myunit.getLength()!=1.0 && type=="gro") error("gro files should be in nm");
+     210           6 :     if(myunit.getLength()!=1.0 && type=="xtc") error("xtc files should be in nm");
+     211           6 :     if(myunit.getLength()!=1.0 && type=="trr") error("trr files should be in nm");
+     212           4 :     lenunit=plumed.getAtoms().getUnits().getLength()/myunit.getLength();
+     213         164 :   } else if(type=="gro" || type=="xtc" || type=="trr") lenunit=plumed.getAtoms().getUnits().getLength();
+     214          30 :   else lenunit=1.0;
+     215             : 
+     216          90 :   checkRead();
+     217          90 :   of.link(*this);
+     218          90 :   of.open(file);
+     219             :   std::string path=of.getPath();
+     220          90 :   log<<"  Writing on file "<<path<<"\n";
+     221             :   std::string mode=of.getMode();
+     222          90 :   if(type=="xtc") {
+     223           6 :     of.close();
+     224           6 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     225          84 :   } else if(type=="trr") {
+     226           4 :     of.close();
+     227           4 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     228             :   }
+     229          90 :   log.printf("  printing the following atoms in %s :", unitname.c_str() );
+     230       18282 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial() );
+     231          90 :   log.printf("\n");
+     232          90 :   requestAtoms(atoms);
+     233          90 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     234          90 :   if( moldat ) {
+     235          54 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+     236          54 :     names.resize(atoms.size());
+     237        5587 :     for(unsigned i=0; i<atoms.size(); i++) if(atoms[i].index()<moldat->getPDBsize()) names[i]=moldat->getAtomName(atoms[i]);
+     238          54 :     residueNumbers.resize(atoms.size());
+     239        5587 :     for(unsigned i=0; i<residueNumbers.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNumbers[i]=moldat->getResidueNumber(atoms[i]);
+     240          54 :     residueNames.resize(atoms.size());
+     241        5587 :     for(unsigned i=0; i<residueNames.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNames[i]=moldat->getResidueName(atoms[i]);
+     242             :   }
+     243          90 : }
+     244             : 
+     245         790 : void DumpAtoms::update() {
+     246         790 :   if(type=="xyz") {
+     247         204 :     of.printf("%d\n",getNumberOfAtoms());
+     248         204 :     const Tensor & t(getPbc().getBox());
+     249         204 :     if(getPbc().isOrthorombic()) {
+     250         336 :       of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     251             :     } else {
+     252          72 :       of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),
+     253          36 :                 lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     254          36 :                 lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     255          36 :                 lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     256             :                );
+     257             :     }
+     258       35160 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     259             :       const char* defname="X";
+     260             :       const char* name=defname;
+     261       34956 :       if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
+     262       69912 :       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));
+     263             :     }
+     264         586 :   } else if(type=="gro") {
+     265         466 :     const Tensor & t(getPbc().getBox());
+     266         466 :     of.printf("Made with PLUMED t=%f\n",getTime()/plumed.getAtoms().getUnits().getTime());
+     267         466 :     of.printf("%d\n",getNumberOfAtoms());
+     268       38404 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     269             :       const char* defname="X";
+     270             :       const char* name=defname;
+     271             :       unsigned residueNumber=0;
+     272       37938 :       if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
+     273       37938 :       if(residueNumbers.size()>0) residueNumber=residueNumbers[i];
+     274       37938 :       std::string resname="";
+     275       37938 :       if(residueNames.size()>0) resname=residueNames[i];
+     276       75876 :       of.printf(("%5u%-5s%5s%5d"+fmt_gro_pos+fmt_gro_pos+fmt_gro_pos+"\n").c_str(),
+     277             :                 residueNumber%100000,resname.c_str(),name,getAbsoluteIndex(i).serial()%100000,
+     278       37938 :                 lenunit*getPosition(i)(0),lenunit*getPosition(i)(1),lenunit*getPosition(i)(2));
+     279             :     }
+     280         932 :     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(),
+     281         466 :               lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2),
+     282         466 :               lenunit*t(0,1),lenunit*t(0,2),lenunit*t(1,0),
+     283         466 :               lenunit*t(1,2),lenunit*t(2,0),lenunit*t(2,1));
+     284         168 :   } else if(type=="xtc" || type=="trr") {
+     285             :     xdrfile::matrix box;
+     286         120 :     const Tensor & t(getPbc().getBox());
+     287         120 :     int natoms=getNumberOfAtoms();
+     288         120 :     int step=getStep();
+     289         120 :     float time=getTime()/plumed.getAtoms().getUnits().getTime();
+     290         120 :     float precision=Tools::fastpow(10.0,iprecision);
+     291        1560 :     for(int i=0; i<3; i++) for(int j=0; j<3; j++) box[i][j]=lenunit*t(i,j);
+     292         120 :     auto pos = Tools::make_unique<xdrfile::rvec[]>(natoms);
+     293       25464 :     for(int i=0; i<natoms; i++) for(int j=0; j<3; j++) pos[i][j]=lenunit*getPosition(i)(j);
+     294         120 :     if(type=="xtc") {
+     295          72 :       write_xtc(xd,natoms,step,time,box,&pos[0],precision);
+     296          48 :     } else if(type=="trr") {
+     297          48 :       write_trr(xd,natoms,step,time,0.0,box,&pos[0],NULL,NULL);
+     298             :     }
+     299           0 :   } else plumed_merror("unknown file type "+type);
+     300         790 : }
+     301             : 
+     302         180 : DumpAtoms::~DumpAtoms() {
+     303          90 :   if(type=="xtc") {
+     304           6 :     xdrfile_close(xd);
+     305          84 :   } else if(type=="trr") {
+     306           4 :     xdrfile_close(xd);
+     307             :   }
+     308         270 : }
+     309             : 
+     310             : 
+     311             : }
+     312             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ceada69995 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:4747100.0 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe716createERKNS_13ActionOptionsE273
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE273
_ZN4PLMD7generic15DumpDerivativesD0Ev273
_ZN4PLMD7generic15DumpDerivativesD1Ev273
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE274
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe71C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe71D2Ev3473
_ZN4PLMD7generic15DumpDerivatives6updateEv13387
_ZN4PLMD7generic15DumpDerivatives5applyEv13402
_ZN4PLMD7generic15DumpDerivatives9calculateEv13444
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.func.html b/coverage/generic/DumpDerivatives.cpp.func.html new file mode 100644 index 0000000000..99c9408e94 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:4747100.0 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe716createERKNS_13ActionOptionsE273
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe71C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe71D2Ev3473
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE274
_ZN4PLMD7generic15DumpDerivatives5applyEv13402
_ZN4PLMD7generic15DumpDerivatives6updateEv13387
_ZN4PLMD7generic15DumpDerivatives9calculateEv13444
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE273
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD0Ev273
_ZN4PLMD7generic15DumpDerivativesD1Ev273
_ZN4PLMD7generic15DumpDerivativesD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.gcov.html b/coverage/generic/DumpDerivatives.cpp.gcov.html new file mode 100644 index 0000000000..7a5cdfb273 --- /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:4747100.0 %
Date:2024-06-10 08:19:14Functions:101283.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 "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       13444 :   void calculate() override {}
+      64             :   explicit DumpDerivatives(const ActionOptions&);
+      65             :   static void registerKeywords(Keywords& keys);
+      66       13402 :   void apply() override {}
+      67             :   void update() override;
+      68             :   ~DumpDerivatives();
+      69             : };
+      70             : 
+      71       10965 : PLUMED_REGISTER_ACTION(DumpDerivatives,"DUMPDERIVATIVES")
+      72             : 
+      73         274 : void DumpDerivatives::registerKeywords(Keywords& keys) {
+      74         274 :   Action::registerKeywords(keys);
+      75         274 :   ActionPilot::registerKeywords(keys);
+      76         274 :   ActionWithArguments::registerKeywords(keys);
+      77         274 :   keys.use("ARG");
+      78         548 :   keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
+      79         548 :   keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
+      80         548 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      81         274 :   keys.use("RESTART");
+      82         274 :   keys.use("UPDATE_FROM");
+      83         274 :   keys.use("UPDATE_UNTIL");
+      84         274 : }
+      85             : 
+      86         273 : DumpDerivatives::DumpDerivatives(const ActionOptions&ao):
+      87             :   Action(ao),
+      88             :   ActionPilot(ao),
+      89             :   ActionWithArguments(ao),
+      90         273 :   fmt("%15.10f")
+      91             : {
+      92         546 :   parse("FILE",file);
+      93         273 :   if( file.length()==0 ) error("name of output file was not specified");
+      94         273 :   parse("FMT",fmt);
+      95         273 :   fmt=" "+fmt;
+      96         273 :   of.link(*this);
+      97         273 :   of.open(file);
+      98         273 :   log.printf("  on file %s\n",file.c_str());
+      99         273 :   log.printf("  with format %s\n",fmt.c_str());
+     100             :   unsigned nargs=getNumberOfArguments();
+     101         273 :   if( nargs==0 ) error("no arguments specified");
+     102         273 :   (getPntrToArgument(0)->getPntrToAction())->turnOnDerivatives();
+     103         273 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     104         273 :   if( npar==0 ) error("one or more arguments has no derivatives");
+     105         854 :   for(unsigned i=1; i<nargs; i++) {
+     106         581 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+     107         581 :     if( npar!=getPntrToArgument(i)->getNumberOfDerivatives() ) error("the number of derivatives must be the same in all values being dumped");
+     108             :   }
+     109         273 :   checkRead();
+     110         273 : }
+     111             : 
+     112             : 
+     113       13387 : void DumpDerivatives::update() {
+     114       13387 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     115      872324 :   for(unsigned ipar=0; ipar<npar; ipar++) {
+     116      858937 :     of.fmtField(" %f");
+     117      858937 :     of.printField("time",getTime());
+     118      858937 :     of.printField("parameter",(int)ipar);
+     119     4087555 :     for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     120     3228618 :       of.fmtField(fmt);
+     121     3228618 :       of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getDerivative(ipar) );
+     122             :     }
+     123      858937 :     of.printField();
+     124             :   }
+     125       13387 : }
+     126             : 
+     127         546 : DumpDerivatives::~DumpDerivatives() {
+     128         819 : }
+     129             : 
+     130             : }
+     131             : 
+     132             : 
+     133             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..328c2c29cc --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:3838100.0 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpForcesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpForcesD2Ev0
_ZN4PLMD7generic10DumpForcesC1ERKNS_13ActionOptionsE28
_ZN4PLMD7generic10DumpForcesD0Ev28
_ZN4PLMD7generic10DumpForcesD1Ev28
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe696createERKNS_13ActionOptionsE28
_ZN4PLMD7generic10DumpForces16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD7generic10DumpForces5applyEv400
_ZN4PLMD7generic10DumpForces6updateEv400
_ZN4PLMD7generic10DumpForces9calculateEv400
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe69C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe69D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.func.html b/coverage/generic/DumpForces.cpp.func.html new file mode 100644 index 0000000000..cc8c7ae6e6 --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:3838100.0 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpForces16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD7generic10DumpForces5applyEv400
_ZN4PLMD7generic10DumpForces6updateEv400
_ZN4PLMD7generic10DumpForces9calculateEv400
_ZN4PLMD7generic10DumpForcesC1ERKNS_13ActionOptionsE28
_ZN4PLMD7generic10DumpForcesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpForcesD0Ev28
_ZN4PLMD7generic10DumpForcesD1Ev28
_ZN4PLMD7generic10DumpForcesD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe696createERKNS_13ActionOptionsE28
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe69C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe69D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.gcov.html b/coverage/generic/DumpForces.cpp.gcov.html new file mode 100644 index 0000000000..0fb639d545 --- /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:3838100.0 %
Date:2024-06-10 08:19:14Functions:101283.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 "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       10475 : PLUMED_REGISTER_ACTION(DumpForces,"DUMPFORCES")
+      70             : 
+      71          29 : void DumpForces::registerKeywords(Keywords& keys) {
+      72          29 :   Action::registerKeywords(keys);
+      73          29 :   ActionPilot::registerKeywords(keys);
+      74          29 :   ActionWithArguments::registerKeywords(keys);
+      75          29 :   keys.use("ARG");
+      76          58 :   keys.add("compulsory","STRIDE","1","the frequency with which the forces should be output");
+      77          58 :   keys.add("compulsory","FILE","the name of the file on which to output the forces");
+      78          58 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      79          29 :   keys.use("RESTART");
+      80          29 :   keys.use("UPDATE_FROM");
+      81          29 :   keys.use("UPDATE_UNTIL");
+      82          29 : }
+      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          84 : }
+     115             : 
+     116             : }
+     117             : 
+     118             : 
+     119             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9c1fed0ce7 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14DumpMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14DumpMassChargeD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe966createERKNS_13ActionOptionsE12
_ZN4PLMD7generic14DumpMassChargeC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic14DumpMassChargeD0Ev12
_ZN4PLMD7generic14DumpMassChargeD1Ev12
_ZN4PLMD7generic14DumpMassCharge16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7generic14DumpMassCharge5applyEv84
_ZN4PLMD7generic14DumpMassCharge6updateEv84
_ZN4PLMD7generic14DumpMassCharge7prepareEv84
_ZN4PLMD7generic14DumpMassCharge9calculateEv84
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe96C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe96D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.func.html b/coverage/generic/DumpMassCharge.cpp.func.html new file mode 100644 index 0000000000..26936001d3 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe966createERKNS_13ActionOptionsE12
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe96C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe96D2Ev3473
_ZN4PLMD7generic14DumpMassCharge16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7generic14DumpMassCharge5applyEv84
_ZN4PLMD7generic14DumpMassCharge6updateEv84
_ZN4PLMD7generic14DumpMassCharge7prepareEv84
_ZN4PLMD7generic14DumpMassCharge9calculateEv84
_ZN4PLMD7generic14DumpMassChargeC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic14DumpMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14DumpMassChargeD0Ev12
_ZN4PLMD7generic14DumpMassChargeD1Ev12
_ZN4PLMD7generic14DumpMassChargeD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.gcov.html b/coverage/generic/DumpMassCharge.cpp.gcov.html new file mode 100644 index 0000000000..d20c95ab93 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.gcov.html @@ -0,0 +1,265 @@ + + + + + + + + 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-06-10 08:19:14Functions:111384.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 "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/File.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/Atoms.h"
+      28             : 
+      29             : namespace PLMD
+      30             : {
+      31             : namespace generic {
+      32             : 
+      33             : //+PLUMEDOC PRINTANALYSIS DUMPMASSCHARGE
+      34             : /*
+      35             : Dump masses and charges on a selected file.
+      36             : 
+      37             : This command dumps a file containing charges and masses.
+      38             : It does so only once in the simulation (at first step).
+      39             : File can be recycled in the \ref driver tool.
+      40             : 
+      41             : Notice that masses and charges are only written once at the beginning
+      42             : of the simulation. In case no atom list is provided, charges and
+      43             : masses for all atoms are written.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : You can add the DUMPMASSCHARGE action at the end of the plumed.dat
+      48             : file that you use during an MD simulations:
+      49             : 
+      50             : \plumedfile
+      51             : c1: COM ATOMS=1-10
+      52             : c2: COM ATOMS=11-20
+      53             : DUMPATOMS ATOMS=c1,c2 FILE=coms.xyz STRIDE=100
+      54             : 
+      55             : DUMPMASSCHARGE FILE=mcfile
+      56             : \endplumedfile
+      57             : 
+      58             : In this way, you will be able to use the same masses while processing
+      59             : a trajectory from the \ref driver . To do so, you need to
+      60             : add the --mc flag on the driver command line, e.g.
+      61             : \verbatim
+      62             : plumed driver --mc mcfile --plumed plumed.dat --ixyz traj.xyz
+      63             : \endverbatim
+      64             : 
+      65             : With the following input you can dump only the charges for a specific
+      66             : group:
+      67             : 
+      68             : \plumedfile
+      69             : solute_ions: GROUP ATOMS=1-121,200-2012
+      70             : DUMPATOMS FILE=traj.gro ATOMS=solute_ions STRIDE=100
+      71             : DUMPMASSCHARGE FILE=mcfile ATOMS=solute_ions
+      72             : \endplumedfile
+      73             : 
+      74             : */
+      75             : //+ENDPLUMEDOC
+      76             : 
+      77             : class DumpMassCharge:
+      78             :   public ActionAtomistic,
+      79             :   public ActionPilot
+      80             : {
+      81             :   std::string file;
+      82             :   bool first;
+      83             :   bool second;
+      84             :   bool print_masses;
+      85             :   bool print_charges;
+      86             : public:
+      87             :   explicit DumpMassCharge(const ActionOptions&);
+      88             :   ~DumpMassCharge();
+      89             :   static void registerKeywords( Keywords& keys );
+      90             :   void prepare() override;
+      91          84 :   void calculate() override {}
+      92          84 :   void apply() override {}
+      93             :   void update() override;
+      94             : };
+      95             : 
+      96       10443 : PLUMED_REGISTER_ACTION(DumpMassCharge,"DUMPMASSCHARGE")
+      97             : 
+      98          13 : void DumpMassCharge::registerKeywords( Keywords& keys ) {
+      99          13 :   Action::registerKeywords( keys );
+     100          13 :   ActionPilot::registerKeywords( keys );
+     101          13 :   ActionAtomistic::registerKeywords( keys );
+     102          26 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+     103          26 :   keys.add("atoms", "ATOMS", "the atom indices whose charges and masses you would like to print out");
+     104          26 :   keys.add("compulsory", "FILE", "file on which to output charges and masses.");
+     105          26 :   keys.addFlag("ONLY_MASSES",false,"Only output masses to file");
+     106          26 :   keys.addFlag("ONLY_CHARGES",false,"Only output charges to file");
+     107          13 : }
+     108             : 
+     109          12 : DumpMassCharge::DumpMassCharge(const ActionOptions&ao):
+     110             :   Action(ao),
+     111             :   ActionAtomistic(ao),
+     112             :   ActionPilot(ao),
+     113          12 :   first(true),
+     114          12 :   second(true),
+     115          12 :   print_masses(true),
+     116          12 :   print_charges(true)
+     117             : {
+     118             :   std::vector<AtomNumber> atoms;
+     119          24 :   parse("FILE",file);
+     120          12 :   if(file.length()==0) error("name of output file was not specified");
+     121          12 :   log.printf("  output written to file %s\n",file.c_str());
+     122             : 
+     123          24 :   parseAtomList("ATOMS",atoms);
+     124             : 
+     125          12 :   if(atoms.size()==0) {
+     126         720 :     for(int i=0; i<plumed.getAtoms().getNatoms(); i++) {
+     127         712 :       atoms.push_back(AtomNumber::index(i));
+     128             :     }
+     129             :   }
+     130             : 
+     131          12 :   bool only_masses = false;
+     132          12 :   parseFlag("ONLY_MASSES",only_masses);
+     133          12 :   if(only_masses) {
+     134           1 :     print_charges = false;
+     135           1 :     log.printf("  only masses will be written to file\n");
+     136             :   }
+     137             : 
+     138          12 :   bool only_charges = false;
+     139          12 :   parseFlag("ONLY_CHARGES",only_charges);
+     140          12 :   if(only_charges) {
+     141           1 :     print_masses = false;
+     142           1 :     log.printf("  only charges will be written to file\n");
+     143             :   }
+     144             : 
+     145             : 
+     146          12 :   checkRead();
+     147             : 
+     148          12 :   log.printf("  printing the following atoms:" );
+     149        1004 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial() );
+     150          12 :   log.printf("\n");
+     151          12 :   requestAtoms(atoms);
+     152             : 
+     153          12 :   if(only_masses && only_charges) {
+     154           0 :     plumed_merror("using both ONLY_MASSES and ONLY_CHARGES doesn't make sense");
+     155             :   }
+     156             : 
+     157          12 : }
+     158             : 
+     159          84 : void DumpMassCharge::prepare() {
+     160          84 :   if(!first && second) {
+     161          12 :     requestAtoms(std::vector<AtomNumber>());
+     162          12 :     second=false;
+     163             :   }
+     164          84 : }
+     165             : 
+     166          84 : void DumpMassCharge::update() {
+     167          84 :   if(!first) return;
+     168          12 :   first=false;
+     169             : 
+     170          12 :   OFile of;
+     171          12 :   of.link(*this);
+     172          12 :   of.open(file);
+     173             : 
+     174        1004 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     175         992 :     int ii=getAbsoluteIndex(i).index();
+     176         992 :     of.printField("index",ii);
+     177        1876 :     if(print_masses) {of.printField("mass",getMass(i));}
+     178        1876 :     if(print_charges) {of.printField("charge",getCharge(i));}
+     179         992 :     of.printField();
+     180             :   }
+     181          12 : }
+     182             : 
+     183          24 : DumpMassCharge::~DumpMassCharge() {
+     184          24 : }
+     185             : 
+     186             : 
+     187             : }
+     188             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..f7d67dfb02 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:3939100.0 %
Date:2024-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpProjectionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpProjectionsD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe676createERKNS_13ActionOptionsE1
_ZN4PLMD7generic15DumpProjectionsC1ERKNS_13ActionOptionsE1
_ZN4PLMD7generic15DumpProjectionsD0Ev1
_ZN4PLMD7generic15DumpProjectionsD1Ev1
_ZN4PLMD7generic15DumpProjections16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7generic15DumpProjections5applyEv3
_ZN4PLMD7generic15DumpProjections6updateEv3
_ZN4PLMD7generic15DumpProjections9calculateEv3
_ZNK4PLMD7generic15DumpProjections19checkNeedsGradientsEv3
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe67C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe67D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.func.html b/coverage/generic/DumpProjections.cpp.func.html new file mode 100644 index 0000000000..3676d19595 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:3939100.0 %
Date:2024-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe676createERKNS_13ActionOptionsE1
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe67C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe67D2Ev3473
_ZN4PLMD7generic15DumpProjections16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7generic15DumpProjections5applyEv3
_ZN4PLMD7generic15DumpProjections6updateEv3
_ZN4PLMD7generic15DumpProjections9calculateEv3
_ZN4PLMD7generic15DumpProjectionsC1ERKNS_13ActionOptionsE1
_ZN4PLMD7generic15DumpProjectionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpProjectionsD0Ev1
_ZN4PLMD7generic15DumpProjectionsD1Ev1
_ZN4PLMD7generic15DumpProjectionsD2Ev0
_ZNK4PLMD7generic15DumpProjections19checkNeedsGradientsEv3
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.gcov.html b/coverage/generic/DumpProjections.cpp.gcov.html new file mode 100644 index 0000000000..d75c36a9ad --- /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:3939100.0 %
Date:2024-06-10 08:19:14Functions: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/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       10421 : PLUMED_REGISTER_ACTION(DumpProjections,"DUMPPROJECTIONS")
+      68             : 
+      69           2 : void DumpProjections::registerKeywords(Keywords& keys) {
+      70           2 :   Action::registerKeywords(keys);
+      71           2 :   ActionPilot::registerKeywords(keys);
+      72           2 :   ActionWithArguments::registerKeywords(keys);
+      73           2 :   keys.use("ARG");
+      74           4 :   keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
+      75           4 :   keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
+      76           4 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      77           2 :   keys.use("RESTART");
+      78           2 :   keys.use("UPDATE_FROM");
+      79           2 :   keys.use("UPDATE_UNTIL");
+      80           2 : }
+      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           3 : }
+     116             : 
+     117             : }
+     118             : 
+     119             : 
+     120             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bb8d61df64 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:12312796.9 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic20EffectiveEnergyDriftC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic20EffectiveEnergyDriftD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_133EffectiveEnergyDriftRegisterMe1216createERKNS_13ActionOptionsE9
_ZN4PLMD7generic20EffectiveEnergyDriftC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic20EffectiveEnergyDriftD0Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD1Ev9
_ZN4PLMD7generic20EffectiveEnergyDrift16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD7generic20EffectiveEnergyDrift5applyEv450
_ZN4PLMD7generic20EffectiveEnergyDrift6updateEv450
_ZN4PLMD7generic20EffectiveEnergyDrift9calculateEv450
_ZN4PLMD7generic12_GLOBAL__N_133EffectiveEnergyDriftRegisterMe121C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_133EffectiveEnergyDriftRegisterMe121D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.func.html b/coverage/generic/EffectiveEnergyDrift.cpp.func.html new file mode 100644 index 0000000000..a0eded9e4a --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:12312796.9 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_133EffectiveEnergyDriftRegisterMe1216createERKNS_13ActionOptionsE9
_ZN4PLMD7generic12_GLOBAL__N_133EffectiveEnergyDriftRegisterMe121C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_133EffectiveEnergyDriftRegisterMe121D2Ev3473
_ZN4PLMD7generic20EffectiveEnergyDrift16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD7generic20EffectiveEnergyDrift5applyEv450
_ZN4PLMD7generic20EffectiveEnergyDrift6updateEv450
_ZN4PLMD7generic20EffectiveEnergyDrift9calculateEv450
_ZN4PLMD7generic20EffectiveEnergyDriftC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic20EffectiveEnergyDriftC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic20EffectiveEnergyDriftD0Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD1Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html b/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html new file mode 100644 index 0000000000..ad1f7f1480 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html @@ -0,0 +1,410 @@ + + + + + + + + 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:12312796.9 %
Date:2024-06-10 08:19:14Functions:101283.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             : 
+      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/PlumedMain.h"
+      34             : #include "core/Atoms.h"
+      35             : 
+      36             : #include "tools/File.h"
+      37             : #include "tools/Pbc.h"
+      38             : 
+      39             : #include <algorithm>
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace generic {
+      43             : 
+      44             : //+PLUMEDOC GENERIC EFFECTIVE_ENERGY_DRIFT
+      45             : /*
+      46             : Print the effective energy drift described in Ref \cite Ferrarotti2015
+      47             : 
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : 
+      52             : This is to monitor the effective energy drift for a metadynamics
+      53             : simulation on the Debye-Huckel energy. Since this variable is very expensive,
+      54             : it could be conveniently computed every second step.
+      55             : \plumedfile
+      56             : dh: DHENERGY GROUPA=1-10 GROUPB=11-20 EPSILON=80.0 I=0.1 TEMP=300.0
+      57             : METAD ARG=dh HEIGHT=0.5 SIGMA=0.1 PACE=500 STRIDE=2
+      58             : EFFECTIVE_ENERGY_DRIFT PRINT_STRIDE=100 FILE=eff
+      59             : \endplumedfile
+      60             : 
+      61             : This is to monitor if a restraint is too stiff
+      62             : \plumedfile
+      63             : d: DISTANCE ATOMS=10,20
+      64             : RESTRAINT ARG=d KAPPA=100000 AT=0.6
+      65             : EFFECTIVE_ENERGY_DRIFT PRINT_STRIDE=100 FILE=eff
+      66             : \endplumedfile
+      67             : 
+      68             : */
+      69             : //+ENDPLUMEDOC
+      70             : 
+      71             : 
+      72             : class EffectiveEnergyDrift:
+      73             :   public ActionPilot {
+      74             :   OFile output;
+      75             :   long int printStride;
+      76             :   std::string fmt;
+      77             : 
+      78             :   double eed;
+      79             : 
+      80             :   Atoms& atoms;
+      81             :   std::vector<ActionWithValue*> biases;
+      82             : 
+      83             :   long int pDdStep;
+      84             :   int nLocalAtoms;
+      85             :   int pNLocalAtoms;
+      86             :   std::vector<int> pGatindex;
+      87             :   std::vector<Vector> positions;
+      88             :   std::vector<Vector> pPositions;
+      89             :   std::vector<Vector> forces;
+      90             :   std::vector<Vector> pForces;
+      91             :   Tensor box,pbox;
+      92             :   Tensor fbox,pfbox;
+      93             : 
+      94             :   const int nProc;
+      95             :   std::vector<int> indexCnt;
+      96             :   std::vector<int> indexDsp;
+      97             :   std::vector<int> dataCnt;
+      98             :   std::vector<int> dataDsp;
+      99             :   std::vector<int> indexS;
+     100             :   std::vector<int> indexR;
+     101             :   std::vector<double> dataS;
+     102             :   std::vector<double> dataR;
+     103             :   std::vector<int> backmap;
+     104             : 
+     105             :   double initialBias;
+     106             :   bool isFirstStep;
+     107             : 
+     108             :   bool ensemble;
+     109             : 
+     110             : public:
+     111             :   explicit EffectiveEnergyDrift(const ActionOptions&);
+     112             :   ~EffectiveEnergyDrift();
+     113             : 
+     114             :   static void registerKeywords( Keywords& keys );
+     115             : 
+     116         450 :   void calculate() override {};
+     117         450 :   void apply() override {};
+     118             :   void update() override;
+     119             : };
+     120             : 
+     121       10437 : PLUMED_REGISTER_ACTION(EffectiveEnergyDrift,"EFFECTIVE_ENERGY_DRIFT")
+     122             : 
+     123          10 : void EffectiveEnergyDrift::registerKeywords( Keywords& keys ) {
+     124          10 :   Action::registerKeywords( keys );
+     125          10 :   ActionPilot::registerKeywords( keys );
+     126             : 
+     127          20 :   keys.add("compulsory","STRIDE","1","should be set to 1. Effective energy drift computation has to be active at each step.");
+     128          20 :   keys.add("compulsory", "FILE", "file on which to output the effective energy drift.");
+     129          20 :   keys.add("compulsory", "PRINT_STRIDE", "frequency to which output the effective energy drift on FILE");
+     130          20 :   keys.addFlag("ENSEMBLE",false,"Set to TRUE if you want to average over multiple replicas.");
+     131          20 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     132          10 :   keys.use("RESTART");
+     133          10 :   keys.use("UPDATE_FROM");
+     134          10 :   keys.use("UPDATE_UNTIL");
+     135          10 : }
+     136             : 
+     137           9 : EffectiveEnergyDrift::EffectiveEnergyDrift(const ActionOptions&ao):
+     138             :   Action(ao),
+     139             :   ActionPilot(ao),
+     140           9 :   fmt("%f"),
+     141           9 :   eed(0.0),
+     142           9 :   atoms(plumed.getAtoms()),
+     143           9 :   nProc(plumed.comm.Get_size()),
+     144           9 :   initialBias(0.0),
+     145           9 :   isFirstStep(true),
+     146          27 :   ensemble(false)
+     147             : {
+     148             :   //stride must be == 1
+     149           9 :   if(getStride()!=1) error("EFFECTIVE_ENERGY_DRIFT must have STRIDE=1 to work properly");
+     150             : 
+     151             :   //parse and open FILE
+     152             :   std::string fileName;
+     153          18 :   parse("FILE",fileName);
+     154           9 :   if(fileName.length()==0) error("name out output file was not specified\n");
+     155           9 :   output.link(*this);
+     156           9 :   output.open(fileName);
+     157             : 
+     158             :   //parse PRINT_STRIDE
+     159           9 :   parse("PRINT_STRIDE",printStride);
+     160             : 
+     161             : 
+     162             :   //parse FMT
+     163           9 :   parse("FMT",fmt);
+     164           9 :   fmt=" "+fmt;
+     165           9 :   log.printf("  with format %s\n",fmt.c_str());
+     166             : 
+     167             :   //parse ENSEMBLE
+     168           9 :   ensemble=false;
+     169           9 :   parseFlag("ENSEMBLE",ensemble);
+     170           9 :   if(ensemble&&comm.Get_rank()==0) {
+     171           0 :     if(multi_sim_comm.Get_size()<2) error("You CANNOT run Replica-Averaged simulations without running multiple replicas!\n");
+     172             :   }
+     173             : 
+     174          18 :   log<<"Bibliography "<<cite("Ferrarotti, Bottaro, Perez-Villa, and Bussi, J. Chem. Theory Comput. 11, 139 (2015)")<<"\n";
+     175             : 
+     176             :   //construct biases from ActionWithValue with a component named bias
+     177           9 :   std::vector<ActionWithValue*> tmpActions=plumed.getActionSet().select<ActionWithValue*>();
+     178          27 :   for(unsigned i=0; i<tmpActions.size(); i++) if(tmpActions[i]->exists(tmpActions[i]->getLabel()+".bias")) biases.push_back(tmpActions[i]);
+     179             : 
+     180             :   //resize counters and displacements useful to communicate with MPI_Allgatherv
+     181           9 :   indexCnt.resize(nProc);
+     182           9 :   indexDsp.resize(nProc);
+     183           9 :   dataCnt.resize(nProc);
+     184           9 :   dataDsp.resize(nProc);
+     185             :   //resize the received buffers
+     186           9 :   indexR.resize(atoms.getNatoms());
+     187           9 :   dataR.resize(atoms.getNatoms()*6);
+     188           9 :   backmap.resize(atoms.getNatoms());
+     189           9 : }
+     190             : 
+     191          18 : EffectiveEnergyDrift::~EffectiveEnergyDrift() {
+     192             : 
+     193          18 : }
+     194             : 
+     195         450 : void EffectiveEnergyDrift::update() {
+     196         450 :   bool pbc=atoms.getPbc().isSet();
+     197             : 
+     198             :   //retrieve data of local atoms
+     199             :   const std::vector<int>& gatindex = atoms.getGatindex();
+     200         450 :   nLocalAtoms = gatindex.size();
+     201         450 :   atoms.getLocalPositions(positions);
+     202         450 :   atoms.getLocalForces(forces);
+     203         450 :   if(pbc) {
+     204         450 :     Tensor B=atoms.getPbc().getBox();
+     205         450 :     Tensor IB=atoms.getPbc().getInvBox();
+     206         450 :     #pragma omp parallel for
+     207             :     for(unsigned i=0; i<positions.size(); ++i) {
+     208             :       positions[i]=matmul(positions[i],IB);
+     209             :       forces[i]=matmul(B,forces[i]);
+     210             :     }
+     211         450 :     box=B;
+     212         450 :     fbox=matmul(transpose(inverse(box)),atoms.getVirial());
+     213             :   }
+     214             : 
+     215             :   //init stored data at the first step
+     216         450 :   if(isFirstStep) {
+     217           9 :     pDdStep=0;
+     218           9 :     pGatindex = atoms.getGatindex();
+     219           9 :     pNLocalAtoms = pGatindex.size();
+     220           9 :     pPositions=positions;
+     221           9 :     pForces=forces;
+     222           9 :     pbox=box;
+     223           9 :     pfbox=fbox;
+     224           9 :     initialBias=plumed.getBias();
+     225             : 
+     226           9 :     isFirstStep=false;
+     227             :   }
+     228             : 
+     229             :   //if the dd has changed we have to reshare the stored data
+     230         450 :   if(pDdStep<atoms.getDdStep() && nLocalAtoms<atoms.getNatoms()) {
+     231             :     //prepare the data to be sent
+     232         204 :     indexS.resize(pNLocalAtoms);
+     233         204 :     dataS.resize(pNLocalAtoms*6);
+     234             : 
+     235        5712 :     for(int i=0; i<pNLocalAtoms; i++) {
+     236        5508 :       indexS[i] = pGatindex[i];
+     237        5508 :       dataS[i*6] = pPositions[i][0];
+     238        5508 :       dataS[i*6+1] = pPositions[i][1];
+     239        5508 :       dataS[i*6+2] = pPositions[i][2];
+     240        5508 :       dataS[i*6+3] = pForces[i][0];
+     241        5508 :       dataS[i*6+4] = pForces[i][1];
+     242        5508 :       dataS[i*6+5] = pForces[i][2];
+     243             :     }
+     244             : 
+     245             :     //setup the counters and displacements for the communication
+     246         204 :     plumed.comm.Allgather(&pNLocalAtoms,1,&indexCnt[0],1);
+     247         204 :     indexDsp[0] = 0;
+     248        1020 :     for(int i=0; i<nProc; i++) {
+     249         816 :       dataCnt[i] = indexCnt[i]*6;
+     250             : 
+     251         816 :       if(i+1<nProc) indexDsp[i+1] = indexDsp[i]+indexCnt[i];
+     252         816 :       dataDsp[i] = indexDsp[i]*6;
+     253             :     }
+     254             : 
+     255             :     //share stored data
+     256         402 :     plumed.comm.Allgatherv((!indexS.empty()?&indexS[0]:NULL), pNLocalAtoms, &indexR[0], &indexCnt[0], &indexDsp[0]);
+     257         402 :     plumed.comm.Allgatherv((!dataS.empty()?&dataS[0]:NULL), pNLocalAtoms*6, &dataR[0], &dataCnt[0], &dataDsp[0]);
+     258             : 
+     259             :     //resize vectors to store the proper amount of data
+     260         204 :     pGatindex.resize(nLocalAtoms);
+     261         204 :     pPositions.resize(nLocalAtoms);
+     262         204 :     pForces.resize(nLocalAtoms);
+     263             : 
+     264             :     //compute backmap
+     265       22236 :     for(unsigned j=0; j<indexR.size(); j++) backmap[indexR[j]]=j;
+     266             : 
+     267             :     //fill the vectors pGatindex, pPositions and pForces
+     268        5712 :     for(int i=0; i<nLocalAtoms; i++) {
+     269        5508 :       int glb=backmap[gatindex[i]];
+     270        5508 :       pGatindex[i] = indexR[glb];
+     271        5508 :       pPositions[i][0] = dataR[glb*6];
+     272        5508 :       pPositions[i][1] = dataR[glb*6+1];
+     273        5508 :       pPositions[i][2] = dataR[glb*6+2];
+     274        5508 :       pForces[i][0] = dataR[glb*6+3];
+     275        5508 :       pForces[i][1] = dataR[glb*6+4];
+     276        5508 :       pForces[i][2] = dataR[glb*6+5];
+     277             :     }
+     278             :   }
+     279             : 
+     280             :   //compute the effective energy drift on local atoms
+     281             : 
+     282         450 :   double eed_tmp=eed;
+     283         450 :   #pragma omp parallel for reduction(+:eed_tmp)
+     284             :   for(int i=0; i<nLocalAtoms; i++) {
+     285             :     Vector dst=delta(pPositions[i],positions[i]);
+     286             :     if(pbc) for(unsigned k=0; k<3; k++) dst[k]=Tools::pbc(dst[k]);
+     287             :     eed_tmp += dotProduct(dst, forces[i]+pForces[i])*0.5;
+     288             :   }
+     289             : 
+     290         450 :   eed=eed_tmp;
+     291             : 
+     292         450 :   if(plumed.comm.Get_rank()==0) {
+     293        1950 :     for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++)
+     294        1350 :         eed-=0.5*(pfbox(i,j)+fbox(i,j))*(box(i,j)-pbox(i,j));
+     295             :   }
+     296             : 
+     297             : 
+     298             :   //print the effective energy drift on FILE with frequency PRINT_STRIDE
+     299         450 :   if(plumed.getStep()%printStride==0) {
+     300         450 :     double eedSum = eed;
+     301             :     double bias = 0.0;
+     302             : 
+     303             :     //we cannot just use plumed.getBias() because it will be ==0.0 if PRINT_STRIDE
+     304             :     //is not a multiple of the bias actions stride
+     305         900 :     for(unsigned i=0; i<biases.size(); i++) bias+=biases[i]->getOutputQuantity("bias");
+     306             : 
+     307         450 :     plumed.comm.Sum(&eedSum,1);
+     308             : 
+     309         450 :     double effective = eedSum+bias-initialBias-plumed.getWork();
+     310             :     // this is to take into account ensemble averaging
+     311         450 :     if(ensemble) {
+     312           0 :       if(plumed.comm.Get_rank()==0) plumed.multi_sim_comm.Sum(&effective,1);
+     313           0 :       else effective=0.;
+     314           0 :       plumed.comm.Sum(&effective,1);
+     315             :     }
+     316         450 :     output.fmtField(" %f");
+     317         450 :     output.printField("time",getTime());
+     318         450 :     output.fmtField(fmt);
+     319         450 :     output.printField("effective-energy",effective);
+     320         450 :     output.printField();
+     321             :   }
+     322             : 
+     323             :   //store the data of the current step
+     324         450 :   pDdStep = atoms.getDdStep();
+     325         450 :   pNLocalAtoms = nLocalAtoms;
+     326             :   pPositions.swap(positions);
+     327             :   pForces.swap(forces);
+     328         450 :   pbox=box;
+     329         450 :   pfbox=fbox;
+     330         450 : }
+     331             : 
+     332             : }
+     333             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..fc66e5305d --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:91181.8 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9EndPlumed5applyEv0
_ZN4PLMD7generic9EndPlumed9calculateEv0
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe656createERKNS_13ActionOptionsE259
_ZN4PLMD7generic9EndPlumedC2ERKNS_13ActionOptionsE259
_ZN4PLMD7generic9EndPlumed16registerKeywordsERNS_8KeywordsE260
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe65C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe65D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.func.html b/coverage/generic/EndPlumed.cpp.func.html new file mode 100644 index 0000000000..eddca192cd --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:91181.8 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe656createERKNS_13ActionOptionsE259
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe65C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe65D2Ev3473
_ZN4PLMD7generic9EndPlumed16registerKeywordsERNS_8KeywordsE260
_ZN4PLMD7generic9EndPlumed5applyEv0
_ZN4PLMD7generic9EndPlumed9calculateEv0
_ZN4PLMD7generic9EndPlumedC2ERKNS_13ActionOptionsE259
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.gcov.html b/coverage/generic/EndPlumed.cpp.gcov.html new file mode 100644 index 0000000000..bf4a92e6b8 --- /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:91181.8 %
Date:2024-06-10 08:19:14Functions:5771.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/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       10678 : PLUMED_REGISTER_ACTION(EndPlumed,"ENDPLUMED")
+      66             : 
+      67         260 : void EndPlumed::registerKeywords( Keywords& keys ) {
+      68         260 :   Action::registerKeywords( keys );
+      69         260 : }
+      70             : 
+      71         259 : EndPlumed::EndPlumed(const ActionOptions&ao):
+      72         259 :   Action(ao)
+      73             : {
+      74         259 :   checkRead();
+      75         259 :   plumed.setEndPlumed();
+      76         259 : }
+      77             : 
+      78             : }
+      79             : }
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9b0737ac42 --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:868996.6 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic13FitToTemplate22getNumberOfDerivativesEv0
_ZN4PLMD7generic13FitToTemplateC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe2016createERKNS_13ActionOptionsE9
_ZN4PLMD7generic13FitToTemplateC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic13FitToTemplate16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD7generic13FitToTemplate5applyEv108
_ZN4PLMD7generic13FitToTemplate9calculateEv108
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe201C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe201D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.func.html b/coverage/generic/FitToTemplate.cpp.func.html new file mode 100644 index 0000000000..4dd394f784 --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:868996.6 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe2016createERKNS_13ActionOptionsE9
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe201C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe201D2Ev3473
_ZN4PLMD7generic13FitToTemplate16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD7generic13FitToTemplate22getNumberOfDerivativesEv0
_ZN4PLMD7generic13FitToTemplate5applyEv108
_ZN4PLMD7generic13FitToTemplate9calculateEv108
_ZN4PLMD7generic13FitToTemplateC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic13FitToTemplateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.gcov.html b/coverage/generic/FitToTemplate.cpp.gcov.html new file mode 100644 index 0000000000..93d28517d9 --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.gcov.html @@ -0,0 +1,451 @@ + + + + + + + + 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:868996.6 %
Date:2024-06-10 08:19:14Functions: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/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/Atoms.h"
+      32             : #include "core/PlumedMain.h"
+      33             : #include "core/ActionSet.h"
+      34             : #include "core/GenericMolInfo.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<AtomNumber> 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             : 
+     192             : 
+     193             : public:
+     194             :   explicit FitToTemplate(const ActionOptions&ao);
+     195             :   static void registerKeywords( Keywords& keys );
+     196             :   void calculate() override;
+     197             :   void apply() override;
+     198           0 :   unsigned getNumberOfDerivatives() override {plumed_merror("You should not call this function");};
+     199             : };
+     200             : 
+     201       10437 : PLUMED_REGISTER_ACTION(FitToTemplate,"FIT_TO_TEMPLATE")
+     202             : 
+     203          10 : void FitToTemplate::registerKeywords( Keywords& keys ) {
+     204          10 :   Action::registerKeywords( keys );
+     205          10 :   ActionAtomistic::registerKeywords( keys );
+     206          20 :   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!");
+     207          20 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     208          20 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+     209          20 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     210          10 : }
+     211             : 
+     212           9 : FitToTemplate::FitToTemplate(const ActionOptions&ao):
+     213             :   Action(ao),
+     214             :   ActionPilot(ao),
+     215             :   ActionAtomistic(ao),
+     216             :   ActionWithValue(ao),
+     217          18 :   nopbc(false)
+     218             : {
+     219             :   std::string reference;
+     220           9 :   parse("REFERENCE",reference);
+     221           9 :   type.assign("SIMPLE");
+     222           9 :   parse("TYPE",type);
+     223             : 
+     224           9 :   parseFlag("NOPBC",nopbc);
+     225             : // if(type!="SIMPLE") error("Only TYPE=SIMPLE is implemented in FIT_TO_TEMPLATE");
+     226             : 
+     227           9 :   checkRead();
+     228             : 
+     229           9 :   PDB pdb;
+     230             : 
+     231             :   // read everything in ang and transform to nm if we are not in natural units
+     232          18 :   if( !pdb.read(reference,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength()) )
+     233           0 :     error("missing input file " + reference );
+     234             : 
+     235           9 :   requestAtoms(pdb.getAtomNumbers());
+     236           9 :   log.printf("  found %zu atoms in input \n",pdb.getAtomNumbers().size());
+     237           9 :   log.printf("  with indices : ");
+     238          42 :   for(unsigned i=0; i<pdb.getAtomNumbers().size(); ++i) {
+     239          33 :     if(i%25==0) log<<"\n";
+     240          33 :     log.printf("%d ",pdb.getAtomNumbers()[i].serial());
+     241             :   }
+     242           9 :   log.printf("\n");
+     243             : 
+     244           9 :   std::vector<Vector> positions=pdb.getPositions();
+     245           9 :   weights=pdb.getOccupancy();
+     246           9 :   aligned=pdb.getAtomNumbers();
+     247             : 
+     248             : 
+     249             :   // normalize weights
+     250          42 :   double n=0.0; for(unsigned i=0; i<weights.size(); ++i) n+=weights[i];
+     251           9 :   if(n==0.0) {
+     252           0 :     error("PDB file " + reference + " has zero weights. Please check the occupancy column.");
+     253             :   }
+     254           9 :   n=1.0/n;
+     255          42 :   for(unsigned i=0; i<weights.size(); ++i) weights[i]*=n;
+     256             : 
+     257             :   // normalize weights for rmsd calculation
+     258           9 :   std::vector<double> weights_measure=pdb.getBeta();
+     259          42 :   n=0.0; for(unsigned i=0; i<weights_measure.size(); ++i) n+=weights_measure[i]; n=1.0/n;
+     260          42 :   for(unsigned i=0; i<weights_measure.size(); ++i) weights_measure[i]*=n;
+     261             : 
+     262             :   // subtract the center
+     263          42 :   for(unsigned i=0; i<weights.size(); ++i) center+=positions[i]*weights[i];
+     264          42 :   for(unsigned i=0; i<weights.size(); ++i) positions[i]-=center;
+     265             : 
+     266          13 :   if(type=="OPTIMAL" or type=="OPTIMAL-FAST" ) {
+     267          10 :     rmsd=Tools::make_unique<RMSD>();
+     268           5 :     rmsd->set(weights,weights_measure,positions,type,false,false);// note: the reference is shifted now with center in the origin
+     269          10 :     log<<"  Method chosen for fitting: "<<rmsd->getMethod()<<" \n";
+     270             :   }
+     271           9 :   if(nopbc) {
+     272           1 :     log<<"  Ignoring PBCs when doing alignment, make sure your molecule is whole!<n";
+     273             :   }
+     274             :   // register the value of rmsd (might be useful sometimes)
+     275           9 :   addValue(); setNotPeriodic();
+     276             : 
+     277             :   // I remove this optimization now in order to use makeWhole()
+     278             :   // Notice that for FIT_TO_TEMPLATE TYPE=OPTIMAL a copy was made anyway
+     279             :   // (due to the need to store position to propagate forces on rotational matrix later)
+     280             :   // For FIT_TO_TEMPLATE TYPE=SIMPLE in principle we could use it and write an ad hoc
+     281             :   // version of makeWhole that only computes the center. Too lazy to do it now.
+     282             :   // In case we do it later, remember that uncommenting this line means that
+     283             :   // getPositions will not work anymore! GB
+     284             :   // doNotRetrieve();
+     285             : 
+     286             :   // this is required so as to allow modifyGlobalForce() to return correct
+     287             :   // also for forces that are not owned (and thus not zeored) by all processors.
+     288             :   allowToAccessGlobalForces();
+     289          18 : }
+     290             : 
+     291             : 
+     292         108 : void FitToTemplate::calculate() {
+     293             : 
+     294         108 :   if(!nopbc) makeWhole();
+     295             : 
+     296         108 :   if (type=="SIMPLE") {
+     297          48 :     Vector cc;
+     298             : 
+     299         144 :     for(unsigned i=0; i<aligned.size(); ++i) {
+     300          96 :       cc+=weights[i]*getPosition(i);
+     301             :     }
+     302             : 
+     303          48 :     shift=center-cc;
+     304          48 :     setValue(shift.modulo());
+     305        6420 :     for(unsigned i=0; i<getTotAtoms(); i++) {
+     306             :       Vector & ato (modifyGlobalPosition(AtomNumber::index(i)));
+     307        6372 :       ato+=shift;
+     308             :     }
+     309             :   }
+     310          60 :   else if( type=="OPTIMAL" or type=="OPTIMAL-FAST") {
+     311             :     // specific stuff that provides all that is needed
+     312          60 :     double r=rmsd->calc_FitElements( getPositions(), rotation,  drotdpos, centeredpositions, center_positions);
+     313          60 :     setValue(r);
+     314        8004 :     for(unsigned i=0; i<getTotAtoms(); i++) {
+     315             :       Vector & ato (modifyGlobalPosition(AtomNumber::index(i)));
+     316        7944 :       ato=matmul(rotation,ato-center_positions)+center;
+     317             :     }
+     318             : // rotate box
+     319             :     Pbc & pbc(modifyGlobalPbc());
+     320          60 :     pbc.setBox(matmul(pbc.getBox(),transpose(rotation)));
+     321             :   }
+     322             : 
+     323         108 : }
+     324             : 
+     325         108 : void FitToTemplate::apply() {
+     326         108 :   if (type=="SIMPLE") {
+     327          48 :     Vector totForce;
+     328        6420 :     for(unsigned i=0; i<getTotAtoms(); i++) {
+     329        6372 :       totForce+=modifyGlobalForce(AtomNumber::index(i));
+     330             :     }
+     331             :     Tensor & vv(modifyGlobalVirial());
+     332          48 :     vv+=Tensor(center,totForce);
+     333         144 :     for(unsigned i=0; i<aligned.size(); ++i) {
+     334             :       Vector & ff(modifyGlobalForce(aligned[i]));
+     335          96 :       ff-=totForce*weights[i];
+     336             :     }
+     337          60 :   } else if ( type=="OPTIMAL" or type=="OPTIMAL-FAST") {
+     338          60 :     Vector totForce;
+     339        8004 :     for(unsigned i=0; i<getTotAtoms(); i++) {
+     340             :       Vector & f(modifyGlobalForce(AtomNumber::index(i)));
+     341             : // rotate back forces
+     342        7944 :       f=matmul(transpose(rotation),f);
+     343             : // accumulate rotated c.o.m. forces - this is already in the non rotated reference frame
+     344        7944 :       totForce+=f;
+     345             :     }
+     346             :     Tensor& virial(modifyGlobalVirial());
+     347             : // notice that an extra Tensor(center,matmul(rotation,totForce)) is required to
+     348             : // compute the derivatives of the rotation with respect to center
+     349          60 :     Tensor ww=matmul(transpose(rotation),virial+Tensor(center,matmul(rotation,totForce)));
+     350             : // rotate back virial
+     351          60 :     virial=matmul(transpose(rotation),matmul(virial,rotation));
+     352             : 
+     353             : // now we compute the force due to alignment
+     354         360 :     for(unsigned i=0; i<aligned.size(); i++) {
+     355         300 :       Vector g;
+     356        1200 :       for(unsigned k=0; k<3; k++) {
+     357             : // this could be made faster computing only the diagonal of d
+     358         900 :         Tensor d=matmul(ww,RMSD::getMatrixFromDRot(drotdpos,i,k));
+     359         900 :         g[k]=(d(0,0)+d(1,1)+d(2,2));
+     360             :       }
+     361             : // here is the extra contribution
+     362         300 :       modifyGlobalForce(aligned[i])+=-g-weights[i]*totForce;
+     363             : // here it the contribution to the virial
+     364             : // notice that here we can use absolute positions since, for the alignment to be defined,
+     365             : // positions should be in one well defined periodic image
+     366         300 :       virial+=extProduct(getPosition(i),g);
+     367             :     }
+     368             : // finally, correction to the virial
+     369          60 :     virial+=extProduct(matmul(transpose(rotation),center),totForce);
+     370             :   }
+     371         108 : }
+     372             : 
+     373             : }
+     374             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..c789546229 --- /dev/null +++ b/coverage/generic/Flush.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:2020100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe796createERKNS_13ActionOptionsE17
_ZN4PLMD7generic5FlushC1ERKNS_13ActionOptionsE17
_ZN4PLMD7generic5Flush16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD7generic5Flush5applyEv561
_ZN4PLMD7generic5Flush6updateEv561
_ZN4PLMD7generic5Flush9calculateEv561
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe79C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe79D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Flush.cpp.func.html b/coverage/generic/Flush.cpp.func.html new file mode 100644 index 0000000000..1710d863d2 --- /dev/null +++ b/coverage/generic/Flush.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:2020100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe796createERKNS_13ActionOptionsE17
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe79C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe79D2Ev3473
_ZN4PLMD7generic5Flush16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD7generic5Flush5applyEv561
_ZN4PLMD7generic5Flush6updateEv561
_ZN4PLMD7generic5Flush9calculateEv561
_ZN4PLMD7generic5FlushC1ERKNS_13ActionOptionsE17
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Flush.cpp.gcov.html b/coverage/generic/Flush.cpp.gcov.html new file mode 100644 index 0000000000..18303ce375 --- /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:2020100.0 %
Date:2024-06-10 08:19:14Functions:88100.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        3941 :     for(const auto & p : actionSet)
+      75        3380 :       p->fflush();
+      76         561 :   }
+      77             : };
+      78             : 
+      79       10453 : PLUMED_REGISTER_ACTION(Flush,"FLUSH")
+      80             : 
+      81          18 : void Flush::registerKeywords( Keywords& keys ) {
+      82          18 :   Action::registerKeywords( keys );
+      83          18 :   ActionPilot::registerKeywords( keys );
+      84          36 :   keys.add("compulsory","STRIDE","the frequency with which all the open files should be flushed");
+      85          18 :   keys.remove("LABEL");
+      86          18 : }
+      87             : 
+      88             : }
+      89             : }
+      90             : 
+      91             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Group.cpp.func-sort-c.html b/coverage/generic/Group.cpp.func-sort-c.html new file mode 100644 index 0000000000..5930de088d --- /dev/null +++ b/coverage/generic/Group.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - generic/Group.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Group.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717397.3 %
Date:2024-06-10 08:19:14Functions:71163.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5Group5applyEv0
_ZN4PLMD7generic5Group9calculateEv0
_ZN4PLMD7generic5GroupC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5GroupD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe1436createERKNS_13ActionOptionsE119
_ZN4PLMD7generic5GroupC1ERKNS_13ActionOptionsE119
_ZN4PLMD7generic5GroupD0Ev119
_ZN4PLMD7generic5GroupD1Ev119
_ZN4PLMD7generic5Group16registerKeywordsERNS_8KeywordsE120
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe143C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe143D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Group.cpp.func.html b/coverage/generic/Group.cpp.func.html new file mode 100644 index 0000000000..0fa9321395 --- /dev/null +++ b/coverage/generic/Group.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - generic/Group.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Group.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717397.3 %
Date:2024-06-10 08:19:14Functions:71163.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe1436createERKNS_13ActionOptionsE119
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe143C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe143D2Ev3473
_ZN4PLMD7generic5Group16registerKeywordsERNS_8KeywordsE120
_ZN4PLMD7generic5Group5applyEv0
_ZN4PLMD7generic5Group9calculateEv0
_ZN4PLMD7generic5GroupC1ERKNS_13ActionOptionsE119
_ZN4PLMD7generic5GroupC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5GroupD0Ev119
_ZN4PLMD7generic5GroupD1Ev119
_ZN4PLMD7generic5GroupD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Group.cpp.gcov.html b/coverage/generic/Group.cpp.gcov.html new file mode 100644 index 0000000000..d12e424801 --- /dev/null +++ b/coverage/generic/Group.cpp.gcov.html @@ -0,0 +1,323 @@ + + + + + + + + LCOV - plumed test coverage - generic/Group.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Group.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717397.3 %
Date:2024-06-10 08:19:14Functions:71163.6 %
+
+ + + + + + + + +

+
          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 "core/ActionRegister.h"
+      24             : #include "core/ActionAtomistic.h"
+      25             : #include "core/Atoms.h"
+      26             : #include "tools/IFile.h"
+      27             : #include "tools/Tools.h"
+      28             : #include <string>
+      29             : #include <vector>
+      30             : #include <algorithm>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace generic {
+      34             : 
+      35             : //+PLUMEDOC GENERIC GROUP
+      36             : /*
+      37             : 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.
+      38             : 
+      39             : Atoms can be listed as comma separated numbers (i.e. `1,2,3,10,45,7,9`) , simple positive ranges
+      40             : (i.e. `20-40`), ranges with a stride either positive or negative (i.e. `20-40:2` or `80-50:-2`) or as
+      41             : comma separated combinations of all the former methods (`1,2,4,5,10-20,21-40:2,80-50:-2`).
+      42             : 
+      43             : Moreover, lists can be imported from ndx files (GROMACS format). Use `NDX_FILE` to set the name of
+      44             : the index file and `NDX_GROUP` to set the name of the group to be imported (default is first one).
+      45             : 
+      46             : It is also possible to remove atoms from a list and or sort them using keywords `REMOVE`, `SORT`, and `UNIQUE`.
+      47             : The flow is the following:
+      48             : - If `ATOMS` is present, then take the ordered list of atoms from the `ATOMS` keyword as a starting list.
+      49             : - Alternatively, if `NDX_FILE` is present, use the list obtained from the gromacs group.
+      50             : - If `REMOVE` is present, then remove the first occurrence of each of these atoms from the list.
+      51             :   If one tries to remove an atom that was not listed plumed adds a notice in the output.
+      52             :   An atom that is present twice in the original list might be removed twice.
+      53             : - If `SORT` is present, then the resulting list is sorted by increasing serial number.
+      54             : - If `UNIQUE` is present, then the resulting list is sorted by increasing serial number _and_ duplicate elements are removed.
+      55             : 
+      56             : Notice that this command just creates a shortcut, and does not imply any real calculation.
+      57             : So, having a huge group defined does not slow down your calculation in any way.
+      58             : It is just convenient to better organize input files. Might be used in combination with
+      59             : the \ref INCLUDE command so as to store long group definitions in a separate file.
+      60             : 
+      61             : 
+      62             : \par Examples
+      63             : 
+      64             : This command create a group of atoms containing atoms 1, 4, 7, 11 and 14 (labeled 'o'), and another containing
+      65             : atoms 2, 3, 5, 6, 8, 9, 12, and 13 (labeled 'h'):
+      66             : \plumedfile
+      67             : o: GROUP ATOMS=1,4,7,11,14
+      68             : h: GROUP ATOMS=2,3,5,6,8,9,12,13
+      69             : # compute the coordination among the two groups
+      70             : c: COORDINATION GROUPA=o GROUPB=h R_0=0.3
+      71             : # same could have been obtained without GROUP, just writing:
+      72             : # c: COORDINATION GROUPA=1,4,7,11,14 GROUPB=2,3,5,6,8,9,12,13
+      73             : 
+      74             : # print the coordination on file 'colvar'
+      75             : PRINT ARG=c FILE=colvar
+      76             : \endplumedfile
+      77             : 
+      78             : Groups can be conveniently stored in a separate file.
+      79             : E.g. one could create a file named `groups.dat` which reads
+      80             : \plumedfile
+      81             : #SETTINGS FILENAME=groups.dat
+      82             : # this is groups.dat
+      83             : o: GROUP ATOMS=1,4,7,11,14
+      84             : h: GROUP ATOMS=2,3,5,6,8,9,12,13
+      85             : \endplumedfile
+      86             : and then include it in the main 'plumed.dat' file
+      87             : \plumedfile
+      88             : INCLUDE FILE=groups.dat
+      89             : # compute the coordination among the two groups
+      90             : c: COORDINATION GROUPA=o GROUPB=h R_0=0.3
+      91             : # print the coordination on file 'colvar'
+      92             : PRINT ARG=c FILE=colvar
+      93             : \endplumedfile
+      94             : The `groups.dat` file could be very long and include lists of thousand atoms without cluttering the main plumed.dat file.
+      95             : 
+      96             : A GROMACS index file such as the one shown below:
+      97             : 
+      98             : \auxfile{index.ndx}
+      99             : [ Protein ]
+     100             : 1 3 5 7 9
+     101             : 2 4 6 8 10
+     102             : [ Group2 ]
+     103             : 30 31 32 33 34 35 36 37 38 39 40
+     104             : 5
+     105             : \endauxfile
+     106             : 
+     107             : can also be imported by using the GROUP keyword as shown below
+     108             : \plumedfile
+     109             : # import group named 'Protein' from file index.ndx
+     110             : pro: GROUP NDX_FILE=index.ndx NDX_GROUP=Protein
+     111             : # dump all the atoms of the protein on a trajectory file
+     112             : DUMPATOMS ATOMS=pro FILE=traj.gro
+     113             : \endplumedfile
+     114             : 
+     115             : A list can be edited with `REMOVE`. For instance, if you
+     116             : are using a water model with three atoms per molecule, you can
+     117             : easily construct the list of hydrogen atoms in this manner
+     118             : \plumedfile
+     119             : # take one atom every three, that is oxygens
+     120             : ox: GROUP ATOMS=1-90:3
+     121             : # take the remaining atoms, that is hydrogens
+     122             : hy: GROUP ATOMS=1-90 REMOVE=ox
+     123             : DUMPATOMS ATOMS=ox FILE=ox.gro
+     124             : DUMPATOMS ATOMS=hy FILE=hy.gro
+     125             : \endplumedfile
+     126             : 
+     127             : 
+     128             : */
+     129             : //+ENDPLUMEDOC
+     130             : 
+     131             : class Group:
+     132             :   public ActionAtomistic
+     133             : {
+     134             : 
+     135             : public:
+     136             :   explicit Group(const ActionOptions&ao);
+     137             :   ~Group();
+     138             :   static void registerKeywords( Keywords& keys );
+     139           0 :   void calculate() override {}
+     140           0 :   void apply() override {}
+     141             : };
+     142             : 
+     143       10657 : PLUMED_REGISTER_ACTION(Group,"GROUP")
+     144             : 
+     145         119 : Group::Group(const ActionOptions&ao):
+     146             :   Action(ao),
+     147         119 :   ActionAtomistic(ao)
+     148             : {
+     149             :   std::vector<AtomNumber> atoms;
+     150         238 :   parseAtomList("ATOMS",atoms);
+     151             :   std::string ndxfile,ndxgroup;
+     152         119 :   parse("NDX_FILE",ndxfile);
+     153         238 :   parse("NDX_GROUP",ndxgroup);
+     154         119 :   if(ndxfile.length()>0 && atoms.size()>0) error("either use explicit atom list or import from index file");
+     155         119 :   if(ndxfile.length()==0 && ndxgroup.size()>0) error("NDX_GROUP can be only used is NDX_FILE is also used");
+     156             : 
+     157         119 :   if(ndxfile.length()>0) {
+     158          35 :     if(ndxgroup.size()>0) log<<"  importing group '"+ndxgroup+"'";
+     159           1 :     else                  log<<"  importing first group";
+     160          18 :     log<<" from index file "<<ndxfile<<"\n";
+     161             : 
+     162          18 :     IFile ifile;
+     163          18 :     ifile.open(ndxfile);
+     164             :     std::string line;
+     165             :     std::string groupname;
+     166             :     bool firstgroup=true;
+     167             :     bool groupfound=false;
+     168        3835 :     while(ifile.getline(line)) {
+     169        3817 :       std::vector<std::string> words=Tools::getWords(line);
+     170        7739 :       if(words.size()>=3 && words[0]=="[" && words[2]=="]") {
+     171         164 :         if(groupname.length()>0) firstgroup=false;
+     172             :         groupname=words[1];
+     173         164 :         if(groupname==ndxgroup || ndxgroup.length()==0) groupfound=true;
+     174        3653 :       } else if(groupname==ndxgroup || (firstgroup && ndxgroup.length()==0)) {
+     175        6160 :         for(unsigned i=0; i<words.size(); i++) {
+     176        5760 :           AtomNumber at; Tools::convert(words[i],at);
+     177        5760 :           atoms.push_back(at);
+     178             :         }
+     179             :       }
+     180        3817 :     }
+     181          18 :     if(!groupfound) error("group has not been found in index file");
+     182          18 :   }
+     183             : 
+     184             :   std::vector<AtomNumber> remove;
+     185         238 :   parseAtomList("REMOVE",remove);
+     186         119 :   if(remove.size()>0) {
+     187             :     std::vector<AtomNumber> notfound;
+     188             :     unsigned k=0;
+     189           2 :     log<<"  removing these atoms from the list:";
+     190         114 :     for(unsigned i=0; i<remove.size(); i++) {
+     191         112 :       const auto it = find(atoms.begin(),atoms.end(),remove[i]);
+     192         112 :       if(it!=atoms.end()) {
+     193         111 :         if(k%25==0) log<<"\n";
+     194         111 :         log<<" "<<(*it).serial();
+     195         111 :         k++;
+     196             :         atoms.erase(it);
+     197           1 :       } else notfound.push_back(remove[i]);
+     198             :     }
+     199           2 :     log<<"\n";
+     200           2 :     if(notfound.size()>0) {
+     201           1 :       log<<"  the following atoms were not found:";
+     202           2 :       for(unsigned i=0; i<notfound.size(); i++) log<<" "<<notfound[i].serial();
+     203           1 :       log<<"\n";
+     204             :     }
+     205             :   }
+     206             : 
+     207         119 :   bool sortme=false;
+     208         119 :   parseFlag("SORT",sortme);
+     209         119 :   if(sortme) {
+     210           1 :     log<<"  atoms are sorted\n";
+     211           1 :     sort(atoms.begin(),atoms.end());
+     212             :   }
+     213         119 :   bool unique=false;
+     214         119 :   parseFlag("UNIQUE",unique);
+     215         119 :   if(unique) {
+     216           1 :     log<<"  sorting atoms and removing duplicates\n";
+     217           1 :     Tools::removeDuplicates(atoms);
+     218             :   }
+     219             : 
+     220         119 :   this->atoms.insertGroup(getLabel(),atoms);
+     221         119 :   log.printf("  list of atoms:");
+     222       28857 :   for(unsigned i=0; i<atoms.size(); i++) {
+     223       28738 :     if(i%25==0) log<<"\n";
+     224       28738 :     log<<" "<<atoms[i].serial();
+     225             :   }
+     226         119 :   log.printf("\n");
+     227         119 : }
+     228             : 
+     229         120 : void Group::registerKeywords( Keywords& keys ) {
+     230         120 :   Action::registerKeywords( keys );
+     231         120 :   ActionAtomistic::registerKeywords( keys );
+     232         240 :   keys.add("atoms", "ATOMS", "the numerical indexes for the set of atoms in the group");
+     233         240 :   keys.add("atoms", "REMOVE","remove these atoms from the list");
+     234         240 :   keys.addFlag("SORT",false,"sort the resulting list");
+     235         240 :   keys.addFlag("UNIQUE",false,"sort atoms and remove duplicated ones");
+     236         240 :   keys.add("optional", "NDX_FILE", "the name of index file (gromacs syntax)");
+     237         240 :   keys.add("optional", "NDX_GROUP", "the name of the group to be imported (gromacs syntax) - first group found is used by default");
+     238         120 : }
+     239             : 
+     240         238 : Group::~Group() {
+     241         119 :   atoms.removeGroup(getLabel());
+     242         238 : }
+     243             : 
+     244             : }
+     245             : }
+     246             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e0de786640 --- /dev/null +++ b/coverage/generic/Include.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:111384.6 %
Date:2024-06-10 08:19:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7Include5applyEv0
_ZN4PLMD7generic7Include9calculateEv0
_ZN4PLMD7generic7IncludeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe1606createERKNS_13ActionOptionsE18
_ZN4PLMD7generic7IncludeC1ERKNS_13ActionOptionsE18
_ZN4PLMD7generic7Include16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe160C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe160D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Include.cpp.func.html b/coverage/generic/Include.cpp.func.html new file mode 100644 index 0000000000..c72429b45b --- /dev/null +++ b/coverage/generic/Include.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:111384.6 %
Date:2024-06-10 08:19:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe1606createERKNS_13ActionOptionsE18
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe160C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe160D2Ev3473
_ZN4PLMD7generic7Include16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD7generic7Include5applyEv0
_ZN4PLMD7generic7Include9calculateEv0
_ZN4PLMD7generic7IncludeC1ERKNS_13ActionOptionsE18
_ZN4PLMD7generic7IncludeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Include.cpp.gcov.html b/coverage/generic/Include.cpp.gcov.html new file mode 100644 index 0000000000..5e9ae672fc --- /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:111384.6 %
Date:2024-06-10 08:19:14Functions: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 "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       10455 : PLUMED_REGISTER_ACTION(Include,"INCLUDE")
+     161             : 
+     162          19 : void Include::registerKeywords( Keywords& keys ) {
+     163          19 :   Action::registerKeywords(keys);
+     164          38 :   keys.add("compulsory","FILE","file to be included");
+     165          19 : }
+     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.15
+
+ + + diff --git a/coverage/generic/MolInfo.cpp.func-sort-c.html b/coverage/generic/MolInfo.cpp.func-sort-c.html new file mode 100644 index 0000000000..4202047d2a --- /dev/null +++ b/coverage/generic/MolInfo.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - generic/MolInfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - MolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe2666createERKNS_13ActionOptionsE84
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe266C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe266D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/MolInfo.cpp.func.html b/coverage/generic/MolInfo.cpp.func.html new file mode 100644 index 0000000000..8c26a531ab --- /dev/null +++ b/coverage/generic/MolInfo.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - generic/MolInfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - MolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe2666createERKNS_13ActionOptionsE84
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe266C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe266D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/MolInfo.cpp.gcov.html b/coverage/generic/MolInfo.cpp.gcov.html new file mode 100644 index 0000000000..1a1e7682dc --- /dev/null +++ b/coverage/generic/MolInfo.cpp.gcov.html @@ -0,0 +1,346 @@ + + + + + + + + LCOV - plumed test coverage - generic/MolInfo.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - MolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-06-10 08:19:14Functions: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             : #include "core/ActionRegister.h"
+      23             : #include "core/GenericMolInfo.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace generic {
+      27             : 
+      28             : //+PLUMEDOC TOPOLOGY MOLINFO
+      29             : /*
+      30             : This command is used to provide information on the molecules that are present in your system.
+      31             : 
+      32             : The information on the molecules in your system can either be provided in the form of a pdb file
+      33             : or as a set of lists of atoms that describe the various chains in your system. If a pdb file
+      34             : is used plumed the MOLINFO command will endeavor to recognize the various chains and residues that
+      35             : make up the molecules in your system using the chainIDs and resnumbers from the pdb file. You can
+      36             : then use this information in later commands to specify atom lists in terms residues.  For example
+      37             : using this command you can find the backbone atoms in your structure automatically.
+      38             : Starting with PLUMED 2.7 you can use multiple MOLINFO actions. Every time you perform an atom
+      39             : selection, the last available MOLINFO action will be used. This allows you to provide multiple PDB
+      40             : files, for instance using different naming conventions (see \issue{134}).
+      41             : 
+      42             : \warning
+      43             : Please be aware that the PDB parser in plumed is far from perfect. You should thus check the log file
+      44             : and examine what plumed is actually doing whenever you use the MOLINFO action.
+      45             : Also make sure that the atoms are listed in the pdb with the correct order.
+      46             : If you are using gromacs, the safest way is to use reference pdb file
+      47             : generated with `gmx editconf -f topol.tpr -o reference.pdb`.
+      48             : 
+      49             : More information of the PDB parser implemented in PLUMED can be found \ref pdbreader "at this page".
+      50             : 
+      51             : Providing `MOLTYPE=protein`, `MOLTYPE=rna`, or `MOLTYPE=dna` will instruct plumed to look
+      52             : for known residues from these three types of molecule. In other words, this is available for
+      53             : historical reasons and to allow future extensions where alternative lists will be provided.
+      54             : As of now, you can just ignore this keyword.
+      55             : 
+      56             : Using \ref MOLINFO extends the possibility of atoms selection using the @ special
+      57             : symbol. The following shortcuts are available that do not refer to one specific residue:
+      58             : 
+      59             : \verbatim
+      60             : @nucleic : all atoms that are part of a DNA or RNA molecule
+      61             : @protein : all atoms that are part of a protein
+      62             : @water : all water molecules
+      63             : @ions : all the ions
+      64             : @hydrogens : all hydrogen atoms (those for which the first non-number in the name is a H)
+      65             : @nonhydrogens : all non hydrogen atoms (those for which the first non-number in the name is not a H)
+      66             : \endverbatim
+      67             : 
+      68             : \warning
+      69             : Be careful since these choices are based on common names used in PDB files. Always check if
+      70             : the selected atoms are correct.
+      71             : 
+      72             : In addition, atoms from a specific residue can be selected with a symbol in this form:
+      73             : 
+      74             : \verbatim
+      75             : @"definition"-chain_residuenum
+      76             : @"definition"-chainresiduenum
+      77             : @"definition"-residuenum
+      78             : \endverbatim
+      79             : 
+      80             : So for example
+      81             : 
+      82             : \verbatim
+      83             : @psi-1 will select the atoms defining the psi torsion of residue 1
+      84             : @psi-C1  or @psi-C_1 will define the same torsion for residue 1 of chain C.
+      85             : @psi-3_1 will define the same torsion for residue 1 of chain 3.
+      86             : \endverbatim
+      87             : 
+      88             : Using the underscore to separate chain and residue is available as of PLUMED 2.5 and allows selecting chains
+      89             : with a numeric id.
+      90             : 
+      91             : In the following are listed the current available definitions:
+      92             : 
+      93             : For protein residues, the following groups are available:
+      94             : 
+      95             : \verbatim
+      96             : # quadruplets for dihedral angles
+      97             : @phi-#
+      98             : @psi-#
+      99             : @omega-#
+     100             : @chi1-#
+     101             : @chi2-#
+     102             : @chi3-#
+     103             : @chi4-#
+     104             : @chi5-#
+     105             : 
+     106             : # all sidechain atoms (excluding glycine, including all hydrogens)
+     107             : @sidechain-#
+     108             : # all backbone atoms (including hydrogens)
+     109             : @back-#
+     110             : \endverbatim
+     111             : 
+     112             : that select the appropriate atoms that define each dihedral angle for residue #.
+     113             : 
+     114             : For DNA or RNA residues, the following groups are available:
+     115             : 
+     116             : \verbatim
+     117             : # quadruplets for backbone dihedral angles
+     118             : @alpha-#
+     119             : @beta-#
+     120             : @gamma-#
+     121             : @delta-#
+     122             : @epsilon-#
+     123             : @zeta-#
+     124             : 
+     125             : # quadruplets for sugar dihedral angles
+     126             : @v0-#
+     127             : @v1-#
+     128             : @v2-#
+     129             : @v3-#
+     130             : @v4-#
+     131             : 
+     132             : # quadruplet corresponding to the chi torsional angle
+     133             : @chi-#
+     134             : 
+     135             : # backbone, sugar, and base heavy atoms
+     136             : @back-#
+     137             : @sugar-#
+     138             : @base-#
+     139             : 
+     140             : # ordered triplets of atoms on the 6-membered ring of nucleobases
+     141             : # namely:
+     142             : #  C2/C4/C6 for pyrimidines
+     143             : #  C2/C6/C4 for purines
+     144             : @lcs-#
+     145             : \endverbatim
+     146             : 
+     147             : Notice that `zeta` and `epsilon` groups should not be used on 3' end residue and `alpha` and `beta`
+     148             : should not be used on 5' end residue.
+     149             : 
+     150             : Furthermore it is also possible to pick single atoms using the syntax
+     151             : `atom-chain_residuenum`, `@atom-chainresiduenum` or `@atom-residuenum`.
+     152             : As of PLUMED 2.5, this also works when the residue is not a protein/rna/dna residue.
+     153             : For instance, `@OW-100` will select oxygen of water molecule with residue number 100.
+     154             : 
+     155             : Finally, notice that other shortcuts are available even when not using the \ref MOLINFO command (see \ref atomSpecs).
+     156             : 
+     157             : \warning If a residue-chain is repeated twice in the reference pdb only the first entry will be selected.
+     158             : 
+     159             : \bug At the moment the HA1 atoms in a GLY residues are treated as if they are the CB atoms. This may or
+     160             : may not be true - GLY is problematic for secondary structure residues as it is achiral.
+     161             : 
+     162             : \bug If you use WHOLEMOLECULES RESIDUES=1-10 for a 18 amino acid protein
+     163             : ( 18 amino acids + 2 terminal groups = 20 residues ) the code will fail as it will not be able to
+     164             : interpret terminal residue 1.
+     165             : 
+     166             : \par Advanced atom selection with mdtraj or MDAnalysis
+     167             : 
+     168             : Since PLUMED 2.6 it is possible to use the expressive selection syntax of [mdtraj](http://mdtraj.org/latest/atom_selection.html) and/or [MDAnalysis](https://www.mdanalysis.org/docs/documentation_pages/selections.html):
+     169             : 
+     170             : \plumedfile
+     171             : MOLINFO STRUCTURE=helix.pdb PYTHON_BIN=python
+     172             : g1: GROUP ATOMS=@mda:backbone
+     173             : g2: GROUP ATOMS={@mda:{resnum 1 or resid 3:5}}
+     174             : g3: GROUP ATOMS={@mda:{resid 3:5} @mda:{resnum 1}}
+     175             : g4: GROUP ATOMS={@mdt:{protein and (backbone or resname ALA)}}
+     176             : g5: GROUP ATOMS={@mdt:{mass 5.5 to 20}} # masses guessed by mdtraj based on atom type!
+     177             : g6: GROUP ATOMS={@mda:{resid 3:5} @mda:{resnum 1} 1-10}
+     178             : \endplumedfile
+     179             : 
+     180             : Here `@mda:` indicates that `MDAnalysis` language is used, whereas `@mdt:` indicates that `mdtraj` language is used. Notice that these languages typically select atoms in order. If you want to specify a different order, you can chain definitions as in `g3` above (compare with `g2`). Selections can be also chained with standard PLUMED selections (see `g6`).
+     181             : 
+     182             : The double braces are required due to the way PLUMED parses atom lists. In particular:
+     183             : 
+     184             : - The outer braces are needed to show PLUMED where the `ATOMS=...` option ends.
+     185             : - The inner braces are needed to show PLUMED where each selector ends.
+     186             : 
+     187             : MDAnalysis also supports geometric selectors based on atomic coordinates. These selectors **are static** and return lists computed using the coordinates stored in the `MOLINFO` pdb file.
+     188             : 
+     189             : In order to use this syntax you should check the following points at runtime:
+     190             : 
+     191             : 1. `plumed --no-mpi config has subprocess` prints `subprocess on` (should be ok on most UNIX systems).
+     192             : 2. You have a python interpreter with mdtraj and/or MDAnalysis installed. You can check using:
+     193             :    - `python -c "import mdtraj"`
+     194             :    - `python -c "import MDAnalysis"`
+     195             : 
+     196             :    In order to install these packages refer to their documentation. Pip or conda install should be ok, provided you make sure the correct python interpreter is in the execution PATH at runtime. Notice that you will only need the package(s) related to the syntax that you want to use.
+     197             : 3. In case you installed these modules on a python with a different name (e.g. `python3.6`), the correct check is:
+     198             :    - `python3.6 -c "import mdtraj"`
+     199             :    - `python3.6 -c "import MDAnalysis"`
+     200             : 
+     201             :    If this is the case, you should set the environment variable `export PYTHON_BIN=python3.6` or `export PLUMED_PYTHON_BIN=python3.6` (higher priority). Alternatively, directly provide the interpreter in the PLUMED input file
+     202             :    using `MOLINFO PYTHON_BIN=python3.6` (even higher priority).
+     203             : 4. The PDB file that you provide to `MOLINFO` should have consecutive atom numbers starting from 1. This is currently enforced since reading atom numbers out of order (as PLUMED does) is not supported by other packages.
+     204             : 
+     205             : \par Advanced atom selection with VMD (experimental)
+     206             : 
+     207             : Similarly to the `@mda:` and `@mdt:` selectors above, you can use the two following selectors in order to
+     208             : access to [VMD](https://www.ks.uiuc.edu/Research/vmd/) syntax for atoms selection:
+     209             : - `@vmdexec:`: This selector launches an instance of VMD, so `vmd` executable should be in your execution path.
+     210             :   Might be very slow or even crash your simulation. Notice that even if `vmd` executable is used,
+     211             :   the implementation is still python based and so a working python interpreter should be provided.
+     212             : - `@vmd:`: This selector tries to import the `vmd` python module. Notice that the best way to obtain this module
+     213             :   is not within the standard VMD installer but rather by installing the python
+     214             :   module that can be found at [this link](http://github.com/Eigenstate/vmd-python).
+     215             :   The module is also available on [conda](https://anaconda.org/conda-forge/vmd-python).
+     216             :   You should make sure the module is available in the python interpreter used by MOLINFO
+     217             :   (check using the command `python -c "import vmd"`).
+     218             : 
+     219             : These two selectors are experimental and might be removed at some point.
+     220             : 
+     221             : \par Examples
+     222             : 
+     223             : In the following example the MOLINFO command is used to provide the information on which atoms
+     224             : are in the backbone of a protein to the ALPHARMSD CV.
+     225             : 
+     226             : \plumedfile
+     227             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+     228             : MOLINFO STRUCTURE=reference.pdb
+     229             : ALPHARMSD RESIDUES=all TYPE=DRMSD LESS_THAN={RATIONAL R_0=0.08 NN=8 MM=12} LABEL=a
+     230             : \endplumedfile
+     231             : 
+     232             : The following example prints the distance corresponding to the hydrogen bonds
+     233             : in a GC Watson-Crick pair.
+     234             : 
+     235             : \plumedfile
+     236             : #SETTINGS MOLFILE=regtest/basic/rt-ermsd/ref.pdb
+     237             : MOLINFO STRUCTURE=reference.pdb MOLTYPE=dna
+     238             : hb1: DISTANCE ATOMS=@N2-2,@O2-15
+     239             : hb2: DISTANCE ATOMS=@N1-2,@N3-15
+     240             : hb3: DISTANCE ATOMS=@O6-2,@N4-15
+     241             : PRINT ARG=hb1,hb2,hb3
+     242             : \endplumedfile
+     243             : 
+     244             : This example use MOLINFO to calculate torsion angles
+     245             : 
+     246             : \plumedfile
+     247             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+     248             : MOLINFO MOLTYPE=protein STRUCTURE=myprotein.pdb
+     249             : t1: TORSION ATOMS=@phi-3
+     250             : t2: TORSION ATOMS=@psi-4
+     251             : PRINT ARG=t1,t2 FILE=colvar STRIDE=10
+     252             : \endplumedfile
+     253             : 
+     254             : */
+     255             : //+ENDPLUMEDOC
+     256             : 
+     257             : 
+     258             : /*
+     259             : This action is defined in core/ as it is used by other actions.
+     260             : Anyway, it is registered here, so that excluding this module from
+     261             : compilation will exclude it from plumed.
+     262             : */
+     263             : 
+     264             : typedef PLMD::GenericMolInfo MolInfo;
+     265             : 
+     266       10587 : PLUMED_REGISTER_ACTION(MolInfo,"MOLINFO")
+     267             : 
+     268             : }
+     269             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ca7588a8c3 --- /dev/null +++ b/coverage/generic/Plumed.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + 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:16717993.3 %
Date:2024-06-10 08:19:14Functions:121485.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic6Plumed22getNumberOfDerivativesEv0
_ZN4PLMD7generic6PlumedC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe1726createERKNS_13ActionOptionsE12
_ZN4PLMD7generic6PlumedC1ERKNS_13ActionOptionsE12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE0_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE1_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE_clEv12
_ZN4PLMD7generic6Plumed16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7generic6Plumed5applyEv104
_ZN4PLMD7generic6Plumed6updateEv104
_ZN4PLMD7generic6Plumed9calculateEv134
_ZN4PLMD7generic6Plumed7prepareEv164
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe172C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe172D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Plumed.cpp.func.html b/coverage/generic/Plumed.cpp.func.html new file mode 100644 index 0000000000..3e1aa02fa0 --- /dev/null +++ b/coverage/generic/Plumed.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + 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:16717993.3 %
Date:2024-06-10 08:19:14Functions:121485.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe1726createERKNS_13ActionOptionsE12
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe172C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe172D2Ev3473
_ZN4PLMD7generic6Plumed16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7generic6Plumed22getNumberOfDerivativesEv0
_ZN4PLMD7generic6Plumed5applyEv104
_ZN4PLMD7generic6Plumed6updateEv104
_ZN4PLMD7generic6Plumed7prepareEv164
_ZN4PLMD7generic6Plumed9calculateEv134
_ZN4PLMD7generic6PlumedC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic6PlumedC2ERKNS_13ActionOptionsE0
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE0_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE1_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE_clEv12
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Plumed.cpp.gcov.html b/coverage/generic/Plumed.cpp.gcov.html new file mode 100644 index 0000000000..db5a3a7007 --- /dev/null +++ b/coverage/generic/Plumed.cpp.gcov.html @@ -0,0 +1,496 @@ + + + + + + + + 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:16717993.3 %
Date:2024-06-10 08:19:14Functions:121485.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/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 "core/PlumedMain.h"
+      29             : #include <cstring>
+      30             : #ifdef __PLUMED_HAS_DLOPEN
+      31             : #include <dlfcn.h>
+      32             : #endif
+      33             : 
+      34             : #include <iostream>
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace generic {
+      38             : 
+      39             : //+PLUMEDOC GENERIC PLUMED
+      40             : /*
+      41             : Embed a separate PLUMED instance.
+      42             : 
+      43             : This command can be used to embed a separate PLUMED instance.
+      44             : Only required atoms will be passed to that instance, using an interface
+      45             : that is similar to the one used when calling PLUMED from the NAMD engine.
+      46             : 
+      47             : Notice that the two instances are running in the same UNIX process, so that they cannot be perfectly isolated.
+      48             : However, most of the features are expected to work correctly.
+      49             : 
+      50             : Notes:
+      51             : - The \ref LOAD action will not work correctly since registers will be shared among the two instances.
+      52             :   In particular, the loaded actions will be visible to both guest and host irrespective of where they are loaded from.
+      53             :   This can be fixed and will probably be fixed in a later version.
+      54             : - `CHDIR` is not thread safe.
+      55             :    However, in most implementations there will be a single process running PLUMED, with perhaps multiple OpenMP threads
+      56             :    spawn in order to parallelize the calculation of individual variables. So, this is likely not a problem.
+      57             : - MPI is working correctly. However, notice that the guest PLUMED will always run with a single process.
+      58             :   Multiple replicas should be handled correctly.
+      59             : 
+      60             : As an advanced feature, one can use the option `KERNEL` to select the version of the guest PLUMED instance.
+      61             : In particular, an empty `KERNEL` (default) implies that the guest PLUMED instance is the same as the host one
+      62             : (no library is loaded).
+      63             : On the other hand, `KERNEL=/path/to/libplumedKernel.so` will allow specifying a library to be loaded for the
+      64             : guest instance.
+      65             : In addition to those mentioned above, this feature has limitations mostly related to
+      66             : clashes in the symbols defined in the different instances of the PLUMED library:
+      67             : - On OSX, if you load a KERNEL with version >=2.5 there should be no problem thanks to the use
+      68             :   of two-level namespaces.
+      69             : - On OSX, if you load a KERNEL with version <=2.4 there should be clashes in symbol resolution.
+      70             :   The only possible workarounds are:
+      71             :   - If you are are using PLUMED with an MD code, it should be patched with `--runtime` and you should
+      72             :     `export PLUMED_LOAD_NAMESPACE=LOCAL` before starting the MD engine.
+      73             :   - If you are using PLUMED driver, you should launch the `plumed-runtime` executable (contained in the
+      74             :     `prefix/lib/plumed/` directory), export `PLUMED_KERNEL` equal to the path of the host kernel library
+      75             :    (as usual in runtime loading) and `export PLUMED_LOAD_NAMESPACE=LOCAL` before launching `plumed-runtime driver`.
+      76             : - On Linux, any `KERNEL` should in principle work correctly. To achieve namespace separation we are loading
+      77             :   the guest kernel with `RTLD_DEEPBIND`. However, this might create difficult to track problems in other linked libraries.
+      78             : - On Unix systems where `RTLD_DEEPBIND` is not available kernels will not load correctly.
+      79             : - In general, there might be unexpected crashes. Particularly difficult are situations where different
+      80             :   kernels were compiled with different libraries.
+      81             : 
+      82             : A possible solution for the symbol clashes (not tested) could be to recompile the alternative PLUMED
+      83             : versions using separate C++ namespaces (e.g. `./configure CPPFLAGS=-DPLMD=PLMD_2_3`).
+      84             : 
+      85             : \todo
+      86             : - Add support for multiple time stepping (`STRIDE` different from 1).
+      87             : - Add the possibility to import CVs calculated in the host PLUMED instance into the guest PLUMED instance.
+      88             :   Will be possible after \issue{83} will be closed.
+      89             : - Add the possibility to export CVs calculated in the guest PLUMED instance into the host PLUMED instance.
+      90             :   Could be implemented using the `DataFetchingObject` class.
+      91             : 
+      92             : \par Examples
+      93             : 
+      94             : Here an example plumed file:
+      95             : \plumedfile
+      96             : # plumed.dat
+      97             : p: PLUMED FILE=plumed2.dat
+      98             : PRINT ARG=p.bias FILE=COLVAR
+      99             : \endplumedfile
+     100             : `plumed2.dat` can be an arbitrary plumed input file, for instance
+     101             : \plumedfile
+     102             : #SETTINGS FILENAME=plumed2.dat
+     103             : # plumed2.dat
+     104             : d: DISTANCE ATOMS=1,10
+     105             : RESTRAINT ARG=d KAPPA=10 AT=2
+     106             : \endplumedfile
+     107             : 
+     108             : Now a more useful example.
+     109             : Imagine that you ran simulations using two different PLUMED input files.
+     110             : The files are long and complex and there are some clashes in the name of the variables (that is: same names
+     111             : are used in both files, same files are written, etc). In addition, files might have been written using different units (see \ref UNITS`).
+     112             : If you want to run a single simulation with a bias potential
+     113             : that is the sum of the two bias potentials, you can:
+     114             : - Place the two input files, as well as all the files required by plumed, in separate directories `directory1` and `directory2`.
+     115             : - Run with the following input file in the parent directory:
+     116             : \plumedfile
+     117             : # plumed.dat
+     118             : PLUMED FILE=plumed.dat CHDIR=directory1
+     119             : PLUMED FILE=plumed.dat CHDIR=directory2
+     120             : \endplumedfile
+     121             : 
+     122             : */
+     123             : //+ENDPLUMEDOC
+     124             : 
+     125             : class Plumed:
+     126             :   public ActionAtomistic,
+     127             :   public ActionWithValue,
+     128             :   public ActionPilot
+     129             : {
+     130             : /// True on root processor
+     131             :   const bool root;
+     132             : /// Separate directory.
+     133             :   const std::string directory;
+     134             : /// Interface to underlying plumed object.
+     135             :   PlumedHandle p;
+     136             : /// API number.
+     137             :   const int API;
+     138             : /// Self communicator
+     139             :   Communicator comm_self;
+     140             : /// Intercommunicator
+     141             :   Communicator intercomm;
+     142             : /// Detect first usage.
+     143             :   bool first=true;
+     144             : /// Stop flag, used to stop e.g. in committor analysis
+     145             :   int stop=0;
+     146             : /// Index of requested atoms.
+     147             :   std::vector<int> index;
+     148             : /// Masses of requested atoms.
+     149             :   std::vector<double> masses;
+     150             : /// Charges of requested atoms.
+     151             :   std::vector<double> charges;
+     152             : /// Forces on requested atoms.
+     153             :   std::vector<double> forces;
+     154             : /// Requested positions.
+     155             :   std::vector<double> positions;
+     156             : /// Applied virial.
+     157             :   Tensor virial;
+     158             : public:
+     159             : /// Constructor.
+     160             :   explicit Plumed(const ActionOptions&);
+     161             : /// Documentation.
+     162             :   static void registerKeywords( Keywords& keys );
+     163             :   void prepare() override;
+     164             :   void calculate() override;
+     165             :   void apply() override;
+     166             :   void update() override;
+     167           0 :   unsigned getNumberOfDerivatives() override {
+     168           0 :     return 0;
+     169             :   }
+     170             : };
+     171             : 
+     172       10443 : PLUMED_REGISTER_ACTION(Plumed,"PLUMED")
+     173             : 
+     174          13 : void Plumed::registerKeywords( Keywords& keys ) {
+     175          13 :   Action::registerKeywords( keys );
+     176          13 :   ActionPilot::registerKeywords( keys );
+     177          13 :   ActionAtomistic::registerKeywords( keys );
+     178          26 :   keys.add("compulsory","STRIDE","1","stride different from 1 are not supported yet");
+     179          26 :   keys.add("optional","FILE","input file for the guest PLUMED instance");
+     180          26 :   keys.add("optional","KERNEL","kernel to be used for the guest PLUMED instance (USE WITH CAUTION!)");
+     181          26 :   keys.add("optional","LOG","log file for the guest PLUMED instance. By default the host log is used");
+     182          26 :   keys.add("optional","CHDIR","run guest in a separate directory");
+     183          26 :   keys.addFlag("NOREPLICAS",false,"run multiple replicas as isolated ones, without letting them know that the host has multiple replicas");
+     184          26 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+     185          13 : }
+     186             : 
+     187          12 : Plumed::Plumed(const ActionOptions&ao):
+     188             :   Action(ao),
+     189             :   ActionAtomistic(ao),
+     190             :   ActionWithValue(ao),
+     191             :   ActionPilot(ao),
+     192          24 :   root(comm.Get_rank()==0),
+     193          24 :   directory([&]() {
+     194             :   std::string directory;
+     195          24 :   parse("CHDIR",directory);
+     196          12 :   if(directory.length()>0) {
+     197           0 :     log<<"  running on separate directory "<<directory<<"\n";
+     198             :   }
+     199          12 :   return directory;
+     200             : }()),
+     201          24 : p([&]() {
+     202             :   std::string kernel;
+     203          24 :   parse("KERNEL",kernel);
+     204          12 :   if(kernel.length()==0) {
+     205          11 :     log<<"  using the current kernel\n";
+     206          11 :     return PlumedHandle();
+     207             :   } else {
+     208           1 :     log<<"  using the kernel "<<kernel<<"\n";
+     209           1 :     return PlumedHandle::dlopen(kernel.c_str());
+     210             :   }
+     211             : }()),
+     212          24 : API([&]() {
+     213          12 :   int api=0;
+     214          24 :   p.cmd("getApiVersion",&api);
+     215          12 :   log<<"  reported API version is "<<api<<"\n";
+     216             :   // note: this is required in order to have cmd performCalcNoUpdate and cmd update
+     217             :   // as a matter of fact, any version <2.5 will not even load due to namespace pollution
+     218          12 :   plumed_assert(api>3) << "API>3 is required for the PLUMED action to work correctly\n";
+     219          12 :   return api;
+     220          24 : }())
+     221             : {
+     222          12 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     223             : 
+     224             :   bool noreplicas;
+     225          12 :   parseFlag("NOREPLICAS",noreplicas);
+     226             :   int nreps;
+     227          12 :   if(root) nreps=multi_sim_comm.Get_size();
+     228          12 :   comm.Bcast(nreps,0);
+     229          12 :   if(nreps>1) {
+     230           6 :     if(noreplicas) {
+     231           0 :       log<<"  running replicas as independent (no suffix used)\n";
+     232             :     } else {
+     233           6 :       log<<"  running replicas as standard multi replic (with suffix)\n";
+     234           6 :       if(root) {
+     235           6 :         intercomm.Set_comm(&multi_sim_comm.Get_comm());
+     236           9 :         p.cmd("GREX setMPIIntercomm",&intercomm.Get_comm());
+     237           9 :         p.cmd("GREX setMPIIntracomm",&comm_self.Get_comm());
+     238           6 :         p.cmd("GREX init");
+     239             :       }
+     240             :     }
+     241             :   } else {
+     242           6 :     if(noreplicas) {
+     243           0 :       log<<"  WARNING: flag NOREPLICAS ignored since we are running without replicas\n";
+     244             :     }
+     245             :   }
+     246             : 
+     247          12 :   int natoms=plumed.getAtoms().getNatoms();
+     248             : 
+     249          12 :   plumed_assert(getStride()==1) << "currently only supports STRIDE=1";
+     250             : 
+     251          12 :   double dt=getTimeStep();
+     252             : 
+     253             :   std::string file;
+     254          24 :   parse("FILE",file);
+     255          12 :   if(file.length()>0) {
+     256          12 :     log<<"  with input file "<<file<<"\n";
+     257           0 :   } else plumed_error() << "you must provide an input file\n";
+     258             : 
+     259             :   bool inherited_logfile=false;
+     260             :   std::string logfile;
+     261          24 :   parse("LOG",logfile);
+     262          12 :   if(logfile.length()>0) {
+     263           0 :     log<<"  with log file "<<logfile<<"\n";
+     264           0 :     if(root) p.cmd("setLogFile",logfile.c_str());
+     265          12 :   } else if(log.getFILE()) {
+     266          12 :     log<<"  with inherited log file\n";
+     267          18 :     if(root) p.cmd("setLog",log.getFILE());
+     268             :     inherited_logfile=true;
+     269             :   } else {
+     270           0 :     log<<"  with log on stdout\n";
+     271           0 :     if(root) p.cmd("setLog",stdout);
+     272             :   }
+     273             : 
+     274          12 :   checkRead();
+     275             : 
+     276          18 :   if(root) p.cmd("setMDEngine","plumed");
+     277             : 
+     278          12 :   double engunits=plumed.getAtoms().getUnits().getEnergy();
+     279          18 :   if(root) p.cmd("setMDEnergyUnits",&engunits);
+     280             : 
+     281          12 :   double lenunits=plumed.getAtoms().getUnits().getLength();
+     282          18 :   if(root) p.cmd("setMDLengthUnits",&lenunits);
+     283             : 
+     284          12 :   double timunits=plumed.getAtoms().getUnits().getTime();
+     285          18 :   if(root) p.cmd("setMDTimeUnits",&timunits);
+     286             : 
+     287          12 :   double chaunits=plumed.getAtoms().getUnits().getCharge();
+     288          18 :   if(root) p.cmd("setMDChargeUnits",&chaunits);
+     289          12 :   double masunits=plumed.getAtoms().getUnits().getMass();
+     290          18 :   if(root) p.cmd("setMDMassUnits",&masunits);
+     291             : 
+     292          12 :   double kbt=plumed.getAtoms().getKbT();
+     293          18 :   if(root) p.cmd("setKbT",&kbt);
+     294             : 
+     295          12 :   int res=0;
+     296          12 :   if(getRestart()) res=1;
+     297          18 :   if(root) p.cmd("setRestart",&res);
+     298             : 
+     299          18 :   if(root) p.cmd("setNatoms",&natoms);
+     300          18 :   if(root) p.cmd("setTimestep",&dt);
+     301          18 :   if(root) p.cmd("setPlumedDat",file.c_str());
+     302             : 
+     303          12 :   addComponentWithDerivatives("bias");
+     304          12 :   componentIsNotPeriodic("bias");
+     305             : 
+     306          12 :   if(inherited_logfile) log<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
+     307          18 :   if(root) p.cmd("init");
+     308          12 :   if(inherited_logfile) log<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
+     309          12 : }
+     310             : 
+     311         164 : void Plumed::prepare() {
+     312         164 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     313         164 :   int step=getStep();
+     314         253 :   if(root) p.cmd("setStep",&step);
+     315         253 :   if(root) p.cmd("prepareDependencies");
+     316         164 :   int ene=0;
+     317         253 :   if(root) p.cmd("isEnergyNeeded",&ene);
+     318         164 :   if(ene) plumed_error()<<"It is not currently possible to use ENERGY in a guest PLUMED";
+     319         164 :   int n=0;
+     320         253 :   if(root) p.cmd("createFullList",&n);
+     321         164 :   const int *pointer=nullptr;
+     322         253 :   if(root) p.cmd("getFullList",&pointer);
+     323         164 :   bool redo=(index.size()!=n);
+     324         164 :   if(first) redo=true;
+     325         164 :   first=false;
+     326        4409 :   if(root && !redo) for(int i=0; i<n; i++) if(index[i]!=pointer[i]) { redo=true; break;};
+     327         164 :   if(root && redo) {
+     328          22 :     index.resize(n);
+     329          22 :     masses.resize(n);
+     330          22 :     forces.resize(3*n);
+     331          22 :     positions.resize(3*n);
+     332          22 :     charges.resize(n);
+     333        1043 :     for(int i=0; i<n; i++) {
+     334        1021 :       index[i]=pointer[i];
+     335             :     };
+     336          44 :     p.cmd("setAtomsNlocal",&n);
+     337          44 :     p.cmd("setAtomsGatindex",index.data(),index.size());
+     338             :   }
+     339         253 :   if(root) p.cmd("clearFullList");
+     340         164 :   int tmp=0;
+     341         164 :   if(root && redo) {
+     342          22 :     tmp=1;
+     343             :   }
+     344         164 :   comm.Bcast(tmp,0);
+     345         164 :   if(tmp) {
+     346          34 :     int s=index.size();
+     347          34 :     comm.Bcast(s,0);
+     348          34 :     if(!root) index.resize(s);
+     349          34 :     comm.Bcast(index,0);
+     350             :     std::vector<AtomNumber> numbers;
+     351          34 :     numbers.reserve(index.size());
+     352        2138 :     for(auto i : index) numbers.emplace_back(AtomNumber::index(i));
+     353          34 :     requestAtoms(numbers);
+     354             :   }
+     355         164 : }
+     356             : 
+     357         134 : void Plumed::calculate() {
+     358         134 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     359         208 :   if(root) p.cmd("setStopFlag",&stop);
+     360         134 :   Tensor box=getPbc().getBox();
+     361         208 :   if(root) p.cmd("setBox",&box[0][0],9);
+     362             : 
+     363         134 :   virial.zero();
+     364       24875 :   for(int i=0; i<forces.size(); i++) forces[i]=0.0;
+     365        4238 :   for(int i=0; i<masses.size(); i++) masses[i]=getMass(i);
+     366        4238 :   for(int i=0; i<charges.size(); i++) charges[i]=getCharge(i);
+     367             : 
+     368         208 :   if(root) p.cmd("setMasses",masses.data(),masses.size());
+     369         208 :   if(root) p.cmd("setCharges",charges.data(),charges.size());
+     370         208 :   if(root) p.cmd("setPositions",positions.data(),positions.size());
+     371         208 :   if(root) p.cmd("setForces",forces.data(),forces.size());
+     372         208 :   if(root) p.cmd("setVirial",&virial[0][0],9);
+     373             : 
+     374             : 
+     375        4238 :   if(root) for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     376        4104 :       positions[3*i+0]=getPosition(i)[0];
+     377        4104 :       positions[3*i+1]=getPosition(i)[1];
+     378        4104 :       positions[3*i+2]=getPosition(i)[2];
+     379             :     }
+     380             : 
+     381         208 :   if(root) p.cmd("shareData");
+     382         208 :   if(root) p.cmd("performCalcNoUpdate");
+     383             : 
+     384         134 :   int s=forces.size();
+     385         134 :   comm.Bcast(s,0);
+     386         134 :   if(!root) forces.resize(s);
+     387         134 :   comm.Bcast(forces,0);
+     388         134 :   comm.Bcast(virial,0);
+     389             : 
+     390         134 :   double bias=0.0;
+     391         208 :   if(root) p.cmd("getBias",&bias);
+     392         134 :   comm.Bcast(bias,0);
+     393         134 :   getPntrToComponent("bias")->set(bias);
+     394         134 : }
+     395             : 
+     396         104 : void Plumed::apply() {
+     397         104 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     398             :   auto & f(modifyForces());
+     399        6596 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     400        6492 :     f[i][0]+=forces[3*i+0];
+     401        6492 :     f[i][1]+=forces[3*i+1];
+     402        6492 :     f[i][2]+=forces[3*i+2];
+     403             :   }
+     404             :   auto & v(modifyVirial());
+     405         104 :   v+=virial;
+     406         104 : }
+     407             : 
+     408         104 : void Plumed::update() {
+     409         104 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     410         163 :   if(root) p.cmd("update");
+     411         104 :   comm.Bcast(stop,0);
+     412         104 :   if(stop) {
+     413           0 :     log<<"  Action " << getLabel()<<" asked to stop\n";
+     414           0 :     plumed.stop();
+     415             :   }
+     416         104 : }
+     417             : 
+     418             : }
+     419             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9cf7136d29 --- /dev/null +++ b/coverage/generic/Print.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:565896.6 %
Date:2024-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe956createERKNS_13ActionOptionsE793
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE793
_ZN4PLMD7generic5PrintD0Ev793
_ZN4PLMD7generic5PrintD1Ev793
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE794
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe95C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe95D2Ev3473
_ZN4PLMD7generic5Print6updateEv211407
_ZN4PLMD7generic5Print5applyEv212026
_ZN4PLMD7generic5Print9calculateEv212144
_ZN4PLMD7generic5Print7prepareEv212267
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Print.cpp.func.html b/coverage/generic/Print.cpp.func.html new file mode 100644 index 0000000000..4cdc5c5d65 --- /dev/null +++ b/coverage/generic/Print.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:565896.6 %
Date:2024-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe956createERKNS_13ActionOptionsE793
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe95C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe95D2Ev3473
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE794
_ZN4PLMD7generic5Print5applyEv212026
_ZN4PLMD7generic5Print6updateEv211407
_ZN4PLMD7generic5Print7prepareEv212267
_ZN4PLMD7generic5Print9calculateEv212144
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE793
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD0Ev793
_ZN4PLMD7generic5PrintD1Ev793
_ZN4PLMD7generic5PrintD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Print.cpp.gcov.html b/coverage/generic/Print.cpp.gcov.html new file mode 100644 index 0000000000..b7269846cb --- /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:565896.6 %
Date:2024-06-10 08:19:14Functions:111384.6 %
+
+ + + + + + + + +

+
          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      212144 :   void calculate() override {}
+      87             :   void prepare() override;
+      88             :   explicit Print(const ActionOptions&);
+      89             :   static void registerKeywords(Keywords& keys);
+      90      212026 :   void apply() override {}
+      91             :   void update() override;
+      92             :   ~Print();
+      93             : };
+      94             : 
+      95       12005 : PLUMED_REGISTER_ACTION(Print,"PRINT")
+      96             : 
+      97         794 : void Print::registerKeywords(Keywords& keys) {
+      98         794 :   Action::registerKeywords(keys);
+      99         794 :   ActionPilot::registerKeywords(keys);
+     100         794 :   ActionWithArguments::registerKeywords(keys);
+     101         794 :   keys.use("ARG");
+     102        1588 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+     103        1588 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+     104        1588 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     105        1588 :   keys.add("hidden","_ROTATE","some funky thing implemented by GBussi");
+     106         794 :   keys.use("RESTART");
+     107         794 :   keys.use("UPDATE_FROM");
+     108         794 :   keys.use("UPDATE_UNTIL");
+     109         794 : }
+     110             : 
+     111         793 : Print::Print(const ActionOptions&ao):
+     112             :   Action(ao),
+     113             :   ActionPilot(ao),
+     114             :   ActionWithArguments(ao),
+     115         793 :   fmt("%f"),
+     116        1586 :   rotate(0)
+     117             : {
+     118         793 :   ofile.link(*this);
+     119        1586 :   parse("FILE",file);
+     120         793 :   if(file.length()>0) {
+     121         793 :     ofile.open(file);
+     122         793 :     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         793 :   parse("FMT",fmt);
+     128         793 :   fmt=" "+fmt;
+     129         793 :   log.printf("  with format %s\n",fmt.c_str());
+     130        6100 :   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         793 :   parse("_ROTATE",rotate);
+     136         793 :   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         793 :   checkRead();
+     145         793 : }
+     146             : 
+     147      212267 : void Print::prepare() {
+     148             : /////////////////////////////////////////
+     149             : // these are crazy things just for debug:
+     150             : // they allow to change regularly the
+     151             : // printed argument
+     152      212267 :   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      212267 : }
+     163             : 
+     164      211407 : void Print::update() {
+     165      211407 :   ofile.fmtField(" %f");
+     166      211407 :   ofile.printField("time",getTime());
+     167      742140 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     168      530733 :     ofile.fmtField(fmt);
+     169      530733 :     ofile.printField( getPntrToArgument(i), getArgument(i) );
+     170             :   }
+     171      211407 :   ofile.printField();
+     172      211407 : }
+     173             : 
+     174        1586 : Print::~Print() {
+     175        2379 : }
+     176             : 
+     177             : }
+     178             : 
+     179             : 
+     180             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ecfc5a3495 --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:51435.7 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe836createERKNS_13ActionOptionsE0
_ZN4PLMD7generic15RandomExchanges5applyEv0
_ZN4PLMD7generic15RandomExchanges9calculateEv0
_ZN4PLMD7generic15RandomExchangesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15RandomExchanges16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe83C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe83D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.func.html b/coverage/generic/RandomExchanges.cpp.func.html new file mode 100644 index 0000000000..e6d3bcfd2b --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:51435.7 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe836createERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe83C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe83D2Ev3473
_ZN4PLMD7generic15RandomExchanges16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD7generic15RandomExchanges5applyEv0
_ZN4PLMD7generic15RandomExchanges9calculateEv0
_ZN4PLMD7generic15RandomExchangesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.gcov.html b/coverage/generic/RandomExchanges.cpp.gcov.html new file mode 100644 index 0000000000..0ccd6e0f14 --- /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:51435.7 %
Date:2024-06-10 08:19:14Functions:3742.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 "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       10419 : PLUMED_REGISTER_ACTION(RandomExchanges,"RANDOM_EXCHANGES")
+      84             : 
+      85           1 : void RandomExchanges::registerKeywords( Keywords& keys ) {
+      86           1 :   Action::registerKeywords(keys);
+      87           2 :   keys.add("optional","SEED","seed for random exchanges");
+      88           1 : }
+      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.15
+
+ + + 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 0000000000..00f3e8a62f --- /dev/null +++ b/coverage/generic/Read.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + 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:9510095.0 %
Date:2024-06-10 08:19:14Functions:121485.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Read22getNumberOfDerivativesEv0
_ZN4PLMD7generic4ReadC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4Read17turnOnDerivativesEv28
_ZN4PLMD7generic4Read7getFileEv37
_ZNK4PLMD7generic4Read11getFilenameB5cxx11Ev40
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe1086createERKNS_13ActionOptionsE86
_ZN4PLMD7generic4ReadC1ERKNS_13ActionOptionsE86
_ZN4PLMD7generic4Read16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe108C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe108D2Ev3473
_ZN4PLMD7generic4Read5applyEv921318
_ZN4PLMD7generic4Read6updateEv921318
_ZN4PLMD7generic4Read7prepareEv921318
_ZN4PLMD7generic4Read9calculateEv921318
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Read.cpp.func.html b/coverage/generic/Read.cpp.func.html new file mode 100644 index 0000000000..8a5b8b6ffa --- /dev/null +++ b/coverage/generic/Read.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + 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:9510095.0 %
Date:2024-06-10 08:19:14Functions:121485.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe1086createERKNS_13ActionOptionsE86
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe108C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe108D2Ev3473
_ZN4PLMD7generic4Read16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD7generic4Read17turnOnDerivativesEv28
_ZN4PLMD7generic4Read22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Read5applyEv921318
_ZN4PLMD7generic4Read6updateEv921318
_ZN4PLMD7generic4Read7getFileEv37
_ZN4PLMD7generic4Read7prepareEv921318
_ZN4PLMD7generic4Read9calculateEv921318
_ZN4PLMD7generic4ReadC1ERKNS_13ActionOptionsE86
_ZN4PLMD7generic4ReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7generic4Read11getFilenameB5cxx11Ev40
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Read.cpp.gcov.html b/coverage/generic/Read.cpp.gcov.html new file mode 100644 index 0000000000..7a5adf8a08 --- /dev/null +++ b/coverage/generic/Read.cpp.gcov.html @@ -0,0 +1,333 @@ + + + + + + + + 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:9510095.0 %
Date:2024-06-10 08:19:14Functions:121485.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/ActionPilot.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "core/Atoms.h"
+      28             : #include "tools/IFile.h"
+      29             : #include <memory>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace generic {
+      33             : 
+      34             : //+PLUMEDOC GENERIC READ
+      35             : /*
+      36             : Read quantities from a colvar file.
+      37             : 
+      38             : This Action can be used with driver to read in a colvar file that was generated during
+      39             : an MD simulation
+      40             : 
+      41             : \par Description of components
+      42             : 
+      43             : The READ command will read those fields that are labelled with the text string given to the
+      44             : VALUE keyword.  It will also read in any fields that are labeled with the text string
+      45             : given to the VALUE keyword followed by a dot and a further string. If a single Value is read in
+      46             : this value can be referenced using the label of the Action.  Alternatively, if multiple quantities
+      47             : are read in, they can be referenced elsewhere in the input by using the label for the Action
+      48             : followed by a dot and the character string that appeared after the dot in the title of the field.
+      49             : 
+      50             : \par Examples
+      51             : 
+      52             : This input reads in data from a file called input_colvar.data that was generated
+      53             : in a calculation that involved PLUMED.  The first command reads in the data from the
+      54             : column headed phi1 while the second reads in the data from the column headed phi2.
+      55             : 
+      56             : \plumedfile
+      57             : rphi1:       READ FILE=input_colvar.data  VALUES=phi1
+      58             : rphi2:       READ FILE=input_colvar.data  VALUES=phi2
+      59             : PRINT ARG=rphi1,rphi2 STRIDE=500  FILE=output_colvar.data
+      60             : \endplumedfile
+      61             : 
+      62             : The file input_colvar.data is just a normal colvar file as shown below
+      63             : 
+      64             : \auxfile{input_colvar.data}
+      65             : #! FIELDS time phi psi metad.bias metad.rbias metad.rct
+      66             : #! SET min_phi -pi
+      67             : #! SET max_phi pi
+      68             : #! SET min_psi -pi
+      69             : #! SET max_psi pi
+      70             :  0.000000  -1.2379   0.8942   0.0000   0.0000   0.0000
+      71             :  1.000000  -1.4839   1.0482   0.0000   0.0000   0.0089
+      72             :  2.000000  -1.3243   0.6055   0.0753   0.0664   0.0184
+      73             : \endauxfile
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78             : class Read :
+      79             :   public ActionPilot,
+      80             :   public ActionWithValue
+      81             : {
+      82             : private:
+      83             :   bool ignore_time;
+      84             :   bool ignore_forces;
+      85             :   bool cloned_file;
+      86             :   unsigned nlinesPerStep;
+      87             :   std::string filename;
+      88             : /// Unique pointer with the same scope as ifile.
+      89             :   std::unique_ptr<IFile> ifile_ptr;
+      90             : /// Pointer to input file.
+      91             : /// It is either pointing to the content of ifile_ptr
+      92             : /// or to the file it is cloned from.
+      93             :   IFile* ifile;
+      94             :   std::vector<std::unique_ptr<Value>> readvals;
+      95             : public:
+      96             :   static void registerKeywords( Keywords& keys );
+      97             :   explicit Read(const ActionOptions&);
+      98             :   void prepare() override;
+      99      921318 :   void apply() override {}
+     100             :   void calculate() override;
+     101             :   void update() override;
+     102             :   std::string getFilename() const;
+     103             :   IFile* getFile();
+     104             :   unsigned getNumberOfDerivatives() override;
+     105             :   void turnOnDerivatives() override;
+     106             : };
+     107             : 
+     108       10591 : PLUMED_REGISTER_ACTION(Read,"READ")
+     109             : 
+     110          87 : void Read::registerKeywords(Keywords& keys) {
+     111          87 :   Action::registerKeywords(keys);
+     112          87 :   ActionPilot::registerKeywords(keys);
+     113          87 :   ActionWithValue::registerKeywords(keys);
+     114         174 :   keys.add("compulsory","STRIDE","1","the frequency with which the file should be read.");
+     115         174 :   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.");
+     116         174 :   keys.add("compulsory","VALUES","the values to read from the file");
+     117         174 :   keys.add("compulsory","FILE","the name of the file from which to read these quantities");
+     118         174 :   keys.addFlag("IGNORE_TIME",false,"ignore the time in the colvar file. When this flag is not present read will be quite strict "
+     119             :                "about the start time of the simulation and the stride between frames");
+     120         174 :   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 "
+     121             :                "safely ignored if you are doing post processing that does not involve outputting forces");
+     122          87 :   keys.remove("NUMERICAL_DERIVATIVES");
+     123          87 :   keys.use("UPDATE_FROM");
+     124          87 :   keys.use("UPDATE_UNTIL");
+     125          87 :   ActionWithValue::useCustomisableComponents(keys);
+     126          87 : }
+     127             : 
+     128          86 : Read::Read(const ActionOptions&ao):
+     129             :   Action(ao),
+     130             :   ActionPilot(ao),
+     131             :   ActionWithValue(ao),
+     132          86 :   ignore_time(false),
+     133          86 :   ignore_forces(false),
+     134          86 :   nlinesPerStep(1)
+     135             : {
+     136             :   // Read the file name from the input line
+     137          86 :   parse("FILE",filename);
+     138             :   // Check if time is to be ignored
+     139          86 :   parseFlag("IGNORE_TIME",ignore_time);
+     140             :   // Check if forces are to be ignored
+     141          86 :   parseFlag("IGNORE_FORCES",ignore_forces);
+     142             :   // Open the file if it is not already opened
+     143          86 :   cloned_file=false;
+     144          86 :   std::vector<Read*> other_reads=plumed.getActionSet().select<Read*>();
+     145         126 :   for(unsigned i=0; i<other_reads.size(); ++i) {
+     146          40 :     if( other_reads[i]->getFilename()==filename ) {
+     147          37 :       ifile=other_reads[i]->getFile();
+     148          37 :       cloned_file=true;
+     149             :     }
+     150             :   }
+     151          86 :   if( !cloned_file ) {
+     152         124 :     ifile_ptr=Tools::make_unique<IFile>();
+     153          62 :     ifile=ifile_ptr.get();
+     154          62 :     if( !ifile->FileExist(filename) ) error("could not find file named " + filename);
+     155          62 :     ifile->link(*this);
+     156          62 :     ifile->open(filename);
+     157          62 :     ifile->allowIgnoredFields();
+     158             :   }
+     159          86 :   parse("EVERY",nlinesPerStep);
+     160          86 :   if(nlinesPerStep>1) log.printf("  only reading every %uth line of file %s\n",nlinesPerStep,filename.c_str() );
+     161          84 :   else log.printf("  reading data from file %s\n",filename.c_str() );
+     162             :   // Find out what we are reading
+     163          86 :   std::vector<std::string> valread; parseVector("VALUES",valread);
+     164             : 
+     165          86 :   if(nlinesPerStep>1 && cloned_file) error("Opening a file multiple times and using EVERY is not allowed");
+     166             : 
+     167             :   std::size_t dot=valread[0].find_first_of('.');
+     168          86 :   if( valread[0].find(".")!=std::string::npos ) {
+     169           8 :     std::string label=valread[0].substr(0,dot);
+     170           8 :     std::string name=valread[0].substr(dot+1);
+     171           8 :     if( name=="*" ) {
+     172           1 :       if( valread.size()>1 ) error("all values must be from the same Action when using READ");
+     173             :       std::vector<std::string> fieldnames;
+     174           1 :       ifile->scanFieldList( fieldnames );
+     175           8 :       for(unsigned i=0; i<fieldnames.size(); ++i) {
+     176           7 :         if( fieldnames[i].substr(0,dot)==label ) {
+     177           3 :           readvals.emplace_back(Tools::make_unique<Value>(this, fieldnames[i], false) ); addComponentWithDerivatives( fieldnames[i].substr(dot+1) );
+     178           6 :           if( ifile->FieldExist("min_" + fieldnames[i]) ) componentIsPeriodic( fieldnames[i].substr(dot+1), "-pi","pi" );
+     179           6 :           else componentIsNotPeriodic( fieldnames[i].substr(dot+1) );
+     180             :         }
+     181             :       }
+     182           1 :     } else {
+     183           7 :       readvals.emplace_back(Tools::make_unique<Value>(this, valread[0], false) ); addComponentWithDerivatives( name );
+     184          14 :       if( ifile->FieldExist("min_" + valread[0]) ) componentIsPeriodic( valread[0].substr(dot+1), "-pi", "pi" );
+     185          14 :       else componentIsNotPeriodic( valread[0].substr(dot+1) );
+     186           9 :       for(unsigned i=1; i<valread.size(); ++i) {
+     187           4 :         if( valread[i].substr(0,dot)!=label ) error("all values must be from the same Action when using READ");;
+     188           2 :         readvals.emplace_back(Tools::make_unique<Value>(this, valread[i], false) ); addComponentWithDerivatives( valread[i].substr(dot+1) );
+     189           4 :         if( ifile->FieldExist("min_" + valread[i]) ) componentIsPeriodic( valread[i].substr(dot+1), "-pi", "pi" );
+     190           4 :         else componentIsNotPeriodic( valread[i].substr(dot+1) );
+     191             :       }
+     192             :     }
+     193             :   } else {
+     194          78 :     if( valread.size()!=1 ) error("all values must be from the same Action when using READ");
+     195          78 :     readvals.emplace_back(Tools::make_unique<Value>(this, valread[0], false) ); addValueWithDerivatives();
+     196         165 :     if( ifile->FieldExist("min_" + valread[0]) ) setPeriodic( "-pi", "pi" );
+     197          69 :     else setNotPeriodic();
+     198          78 :     log.printf("  reading value %s and storing as %s\n",valread[0].c_str(),getLabel().c_str() );
+     199             :   }
+     200          86 :   checkRead();
+     201         172 : }
+     202             : 
+     203          40 : std::string Read::getFilename() const {
+     204          40 :   return filename;
+     205             : }
+     206             : 
+     207          37 : IFile* Read::getFile() {
+     208          37 :   return ifile;
+     209             : }
+     210             : 
+     211           0 : unsigned Read::getNumberOfDerivatives() {
+     212           0 :   return 0;
+     213             : }
+     214             : 
+     215          28 : void Read::turnOnDerivatives() {
+     216          28 :   if( !ignore_forces ) error("cannot calculate derivatives for colvars that are read in from a file.  If you are postprocessing and "
+     217             :                                "these forces do not matter add the flag IGNORE_FORCES to all READ actions");
+     218          28 : }
+     219             : 
+     220      921318 : void Read::prepare() {
+     221      921318 :   if( !cloned_file ) {
+     222             :     double du_time;
+     223      404026 :     if( !ifile->scanField("time",du_time) ) {
+     224           0 :       error("Reached end of file " + filename + " before end of trajectory");
+     225      202013 :     } else if( std::abs( du_time-getTime() )>plumed.getAtoms().getTimeStep() && !ignore_time ) {
+     226           0 :       std::string str_dutime,str_ptime; Tools::convert(du_time,str_dutime); Tools::convert(getTime(),str_ptime);
+     227           0 :       error("mismatched times in colvar files : colvar time=" + str_dutime + " plumed time=" + str_ptime + ". Add IGNORE_TIME to ignore error.");
+     228             :     }
+     229             :   }
+     230      921318 : }
+     231             : 
+     232      921318 : void Read::calculate() {
+     233             :   std::string smin, smax;
+     234     2018830 :   for(unsigned i=0; i<readvals.size(); ++i) {
+     235             : // .get  returns the raw pointer
+     236             : // ->get calls the Value::get() method
+     237     1097512 :     ifile->scanField( readvals[i].get() );
+     238     1097512 :     getPntrToComponent(i)->set( readvals[i]->get() );
+     239     1097512 :     if( readvals[i]->isPeriodic() ) {
+     240        3309 :       readvals[i]->getDomain( smin, smax );
+     241        3309 :       getPntrToComponent(i)->setDomain( smin, smax );
+     242             :     }
+     243             :   }
+     244      921318 : }
+     245             : 
+     246      921318 : void Read::update() {
+     247      921318 :   if( !cloned_file ) {
+     248      404577 :     for(unsigned i=0; i<nlinesPerStep; ++i) {
+     249      202564 :       ifile->scanField(); double du_time;
+     250      405128 :       if( !ifile->scanField("time",du_time) && plumed.getAtoms().getNatoms()==0 ) plumed.stop();
+     251             :     }
+     252             :   }
+     253      921318 : }
+     254             : 
+     255             : }
+     256             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..124232fd2e --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9ResetCellC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe1066createERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCellC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCell16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7generic9ResetCell5applyEv17
_ZN4PLMD7generic9ResetCell9calculateEv17
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe106C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe106D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.func.html b/coverage/generic/ResetCell.cpp.func.html new file mode 100644 index 0000000000..0a4d31b972 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe1066createERKNS_13ActionOptionsE2
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe106C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe106D2Ev3473
_ZN4PLMD7generic9ResetCell16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7generic9ResetCell5applyEv17
_ZN4PLMD7generic9ResetCell9calculateEv17
_ZN4PLMD7generic9ResetCellC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCellC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.gcov.html b/coverage/generic/ResetCell.cpp.gcov.html new file mode 100644 index 0000000000..a42d5c6776 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.gcov.html @@ -0,0 +1,275 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions: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 "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Vector.h"
+      26             : #include "tools/Matrix.h"
+      27             : #include "tools/AtomNumber.h"
+      28             : #include "tools/Tools.h"
+      29             : #include "core/Atoms.h"
+      30             : #include "tools/Pbc.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace generic {
+      34             : 
+      35             : //+PLUMEDOC GENERIC RESET_CELL
+      36             : /*
+      37             : This action is used to rotate the full cell
+      38             : 
+      39             : This can be used to modify the periodic box. Notice that
+      40             : this is done at fixed scaled coordinates,
+      41             : so that also atomic coordinates for the entire system are affected.
+      42             : To see what effect try
+      43             : the \ref DUMPATOMS directive to output the atomic positions.
+      44             : 
+      45             : Also notice that PLUMED propagate forces correctly so that you can add a bias on a CV computed
+      46             : after rotation. See also \ref FIT_TO_TEMPLATE
+      47             : 
+      48             : Currently, only TYPE=TRIANGULAR is implemented, which allows one to reset
+      49             : the cell to a lower triangular one. Namely, a proper rotation is found that allows
+      50             : rotating the box so that the first lattice vector is in the form (ax,0,0),
+      51             : the second lattice vector is in the form (bx,by,0), and the third lattice vector is
+      52             : arbitrary.
+      53             : 
+      54             : \attention
+      55             : The implementation of this action is available but should be considered in testing phase. Please report any
+      56             : strange behavior.
+      57             : 
+      58             : \attention
+      59             : This directive modifies the stored position at the precise moment
+      60             : it is executed. This means that only collective variables
+      61             : which are below it in the input script will see the corrected positions.
+      62             : Unless you
+      63             : know exactly what you are doing, leave the default stride (1), so that
+      64             : this action is performed at every MD step.
+      65             : 
+      66             : \par Examples
+      67             : 
+      68             : Reset cell to be triangular after a rototranslational fit
+      69             : \plumedfile
+      70             : DUMPATOMS FILE=dump-original.xyz ATOMS=1-20
+      71             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=OPTIMAL
+      72             : DUMPATOMS FILE=dump-fit.xyz ATOMS=1-20
+      73             : RESET_CELL TYPE=TRIANGULAR
+      74             : DUMPATOMS FILE=dump-reset.xyz ATOMS=1-20
+      75             : \endplumedfile
+      76             : 
+      77             : The reference file for the FIT_TO_TEMPLATE is just a normal pdb file with the format shown below:
+      78             : 
+      79             : \auxfile{ref.pdb}
+      80             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      81             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      82             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      83             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      84             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      85             : END
+      86             : \endauxfile
+      87             : 
+      88             : */
+      89             : //+ENDPLUMEDOC
+      90             : 
+      91             : 
+      92             : class ResetCell:
+      93             :   public ActionPilot,
+      94             :   public ActionAtomistic
+      95             : {
+      96             :   std::string type;
+      97             :   Tensor rotation,newbox;
+      98             : 
+      99             : public:
+     100             :   explicit ResetCell(const ActionOptions&ao);
+     101             :   static void registerKeywords( Keywords& keys );
+     102             :   void calculate() override;
+     103             :   void apply() override;
+     104             : };
+     105             : 
+     106       10423 : PLUMED_REGISTER_ACTION(ResetCell,"RESET_CELL")
+     107             : 
+     108           3 : void ResetCell::registerKeywords( Keywords& keys ) {
+     109           3 :   Action::registerKeywords( keys );
+     110           3 :   ActionAtomistic::registerKeywords( keys );
+     111           6 :   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!");
+     112           6 :   keys.add("compulsory","TYPE","TRIANGULAR","the manner in which the cell is reset");
+     113           3 : }
+     114             : 
+     115           2 : ResetCell::ResetCell(const ActionOptions&ao):
+     116             :   Action(ao),
+     117             :   ActionPilot(ao),
+     118           2 :   ActionAtomistic(ao)
+     119             : {
+     120           2 :   type.assign("TRIANGULAR");
+     121           2 :   parse("TYPE",type);
+     122             : 
+     123           2 :   log<<"  type: "<<type<<"\n";
+     124           2 :   if(type!="TRIANGULAR") error("undefined type "+type);
+     125             : 
+     126           2 :   checkRead();
+     127           2 : }
+     128             : 
+     129             : 
+     130          17 : void ResetCell::calculate() {
+     131             : 
+     132             :   Pbc & pbc(modifyGlobalPbc());
+     133             : 
+     134          17 :   Tensor box=pbc.getBox();
+     135             : 
+     136             : // moduli of lattice vectors
+     137          17 :   double a=modulo(box.getRow(0));
+     138          17 :   double b=modulo(box.getRow(1));
+     139          17 :   double c=modulo(box.getRow(2));
+     140             : // cos-angle between lattice vectors
+     141          17 :   double ab=dotProduct(box.getRow(0),box.getRow(1))/(a*b);
+     142          17 :   double ac=dotProduct(box.getRow(0),box.getRow(2))/(a*c);
+     143          17 :   double bc=dotProduct(box.getRow(1),box.getRow(2))/(b*c);
+     144             : 
+     145             : // generate a new set of lattice vectors as a lower triangular matrix
+     146          17 :   newbox[0][0]=a;
+     147          17 :   newbox[1][0]=b*ab;
+     148          17 :   newbox[1][1]=std::sqrt(b*b-newbox[1][0]*newbox[1][0]);
+     149          17 :   newbox[2][0]=c*ac;
+     150          17 :   newbox[2][1]=c*(bc-ac*ab)/std::sqrt(1-ab*ab);
+     151          17 :   newbox[2][2]=std::sqrt(c*c-newbox[2][0]*newbox[2][0]-newbox[2][1]*newbox[2][1]);
+     152             : 
+     153          17 :   if(determinant(newbox)*determinant(box)<0) newbox[2][2]=-newbox[2][2];
+     154             : 
+     155             : // rotation matrix from old to new coordinates
+     156          17 :   rotation=transpose(matmul(inverse(box),newbox));
+     157             : 
+     158             : // rotate all coordinates
+     159        1623 :   for(unsigned i=0; i<getTotAtoms(); i++) {
+     160             :     Vector & ato (modifyGlobalPosition(AtomNumber::index(i)));
+     161        1606 :     ato=matmul(rotation,ato);
+     162             :   }
+     163             : // rotate box
+     164          17 :   pbc.setBox(newbox);
+     165          17 : }
+     166             : 
+     167          17 : void ResetCell::apply() {
+     168             : // rotate back forces
+     169        1623 :   for(unsigned i=0; i<getTotAtoms(); i++) {
+     170             :     Vector & f(modifyGlobalForce(AtomNumber::index(i)));
+     171        1606 :     f=matmul(transpose(rotation),f);
+     172             :   }
+     173             : 
+     174             :   Tensor& virial(modifyGlobalVirial());
+     175             : // I have no mathematical derivation for this.
+     176             : // The reasoning is the following.
+     177             : // virial= h^T * dU/dh, where h is the box matrix and dU/dh its derivatives.
+     178             : // The final virial should be rotationally invariant, that is symmetric.
+     179             : // in the rotated frame, dU/dh elements [0][1], [0][2], and [1][2] should
+     180             : // be changed so as to enforce rotational invariance. Thus we here have to
+     181             : // make the virial matrix symmetric.
+     182             : // Since h^T is upper triangular, it can be shown that any change in these elements
+     183             : // will only affect the corresponding elements of the virial matrix.
+     184             : // Thus, the only possibility is to set the corresponding elements
+     185             : // of the virial matrix equal to their symmetric ones.
+     186             : // GB
+     187          17 :   virial[0][1]=virial[1][0];
+     188          17 :   virial[0][2]=virial[2][0];
+     189          17 :   virial[1][2]=virial[2][1];
+     190             : // rotate back virial
+     191          17 :   virial=matmul(transpose(rotation),matmul(virial,rotation));
+     192             : 
+     193             : 
+     194             : 
+     195          17 : }
+     196             : 
+     197             : }
+     198             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..83596e2abc --- /dev/null +++ b/coverage/generic/Time.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:51533.3 %
Date:2024-06-10 08:19:14Functions:3933.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe546createERKNS_13ActionOptionsE0
_ZN4PLMD7generic4Time22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Time5applyEv0
_ZN4PLMD7generic4Time9calculateEv0
_ZN4PLMD7generic4TimeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4TimeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4Time16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe54C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe54D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Time.cpp.func.html b/coverage/generic/Time.cpp.func.html new file mode 100644 index 0000000000..ded43f9cad --- /dev/null +++ b/coverage/generic/Time.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:51533.3 %
Date:2024-06-10 08:19:14Functions:3933.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe546createERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe54C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe54D2Ev3473
_ZN4PLMD7generic4Time16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD7generic4Time22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Time5applyEv0
_ZN4PLMD7generic4Time9calculateEv0
_ZN4PLMD7generic4TimeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4TimeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/Time.cpp.gcov.html b/coverage/generic/Time.cpp.gcov.html new file mode 100644 index 0000000000..44fd70b377 --- /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:51533.3 %
Date:2024-06-10 08:19:14Functions:3933.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/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       10419 : PLUMED_REGISTER_ACTION(Time,"TIME")
+      55             : 
+      56           1 : void Time::registerKeywords( Keywords& keys ) {
+      57           1 :   Action::registerKeywords( keys );
+      58           1 :   ActionWithValue::registerKeywords( keys );
+      59           1 : }
+      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.15
+
+ + + 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 0000000000..0c2b3cf365 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8UpdateIfC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8UpdateIfD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe976createERKNS_13ActionOptionsE7
_ZN4PLMD7generic8UpdateIfC1ERKNS_13ActionOptionsE7
_ZN4PLMD7generic8UpdateIfD0Ev7
_ZN4PLMD7generic8UpdateIfD1Ev7
_ZN4PLMD7generic8UpdateIf16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic8UpdateIf12beforeUpdateEv28
_ZN4PLMD7generic8UpdateIf5applyEv28
_ZN4PLMD7generic8UpdateIf7prepareEv28
_ZN4PLMD7generic8UpdateIf9calculateEv28
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe97C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe97D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.func.html b/coverage/generic/UpdateIf.cpp.func.html new file mode 100644 index 0000000000..09e7a64205 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe976createERKNS_13ActionOptionsE7
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe97C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe97D2Ev3473
_ZN4PLMD7generic8UpdateIf12beforeUpdateEv28
_ZN4PLMD7generic8UpdateIf16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic8UpdateIf5applyEv28
_ZN4PLMD7generic8UpdateIf7prepareEv28
_ZN4PLMD7generic8UpdateIf9calculateEv28
_ZN4PLMD7generic8UpdateIfC1ERKNS_13ActionOptionsE7
_ZN4PLMD7generic8UpdateIfC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8UpdateIfD0Ev7
_ZN4PLMD7generic8UpdateIfD1Ev7
_ZN4PLMD7generic8UpdateIfD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.gcov.html b/coverage/generic/UpdateIf.cpp.gcov.html new file mode 100644 index 0000000000..347cc4ed3c --- /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:4343100.0 %
Date:2024-06-10 08:19:14Functions:111384.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 "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       10433 : PLUMED_REGISTER_ACTION(UpdateIf,"UPDATE_IF")
+      98             : 
+      99           8 : void UpdateIf::registerKeywords(Keywords& keys) {
+     100           8 :   Action::registerKeywords(keys);
+     101           8 :   ActionPilot::registerKeywords(keys);
+     102           8 :   ActionWithArguments::registerKeywords(keys);
+     103           8 :   keys.use("ARG");
+     104          16 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+     105          16 :   keys.addFlag("END",false,"end");
+     106          16 :   keys.add("optional","LESS_THAN","upper bound");
+     107          16 :   keys.add("optional","MORE_THAN","lower bound");
+     108           8 : }
+     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.15
+
+ + + 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 0000000000..64a2dd5559 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:547077.1 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14WholeMoleculesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe1186createERKNS_13ActionOptionsE33
_ZN4PLMD7generic14WholeMoleculesC1ERKNS_13ActionOptionsE33
_ZN4PLMD7generic14WholeMolecules16registerKeywordsERNS_8KeywordsE34
_ZN4PLMD7generic14WholeMolecules5applyEv3313
_ZN4PLMD7generic14WholeMolecules9calculateEv3313
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe118C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe118D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.func.html b/coverage/generic/WholeMolecules.cpp.func.html new file mode 100644 index 0000000000..10c066d360 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:547077.1 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe1186createERKNS_13ActionOptionsE33
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe118C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe118D2Ev3473
_ZN4PLMD7generic14WholeMolecules16registerKeywordsERNS_8KeywordsE34
_ZN4PLMD7generic14WholeMolecules5applyEv3313
_ZN4PLMD7generic14WholeMolecules9calculateEv3313
_ZN4PLMD7generic14WholeMoleculesC1ERKNS_13ActionOptionsE33
_ZN4PLMD7generic14WholeMoleculesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.gcov.html b/coverage/generic/WholeMolecules.cpp.gcov.html new file mode 100644 index 0000000000..e22a757fde --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.gcov.html @@ -0,0 +1,320 @@ + + + + + + + + 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:547077.1 %
Date:2024-06-10 08:19:14Functions: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             : #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/Atoms.h"
+      29             : #include "core/PlumedMain.h"
+      30             : #include "core/ActionSet.h"
+      31             : #include "core/GenericMolInfo.h"
+      32             : #include "tools/OpenMP.h"
+      33             : #include "tools/Tree.h"
+      34             : 
+      35             : #include <vector>
+      36             : #include <string>
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace generic {
+      40             : 
+      41             : //+PLUMEDOC GENERIC WHOLEMOLECULES
+      42             : /*
+      43             : This action is used to rebuild molecules that can become split by the periodic boundary conditions.
+      44             : 
+      45             : It is similar to the ALIGN_ATOMS keyword of plumed1, and is needed since some
+      46             : MD dynamics code (e.g. GROMACS) can break molecules during the calculation.
+      47             : 
+      48             : Running some CVs without this command can cause there to be discontinuities changes
+      49             : in the CV value and artifacts in the calculations.  This command can be applied
+      50             : more than once.  To see what effect is has use a variable without pbc or use
+      51             : the \ref DUMPATOMS directive to output the atomic positions.
+      52             : 
+      53             : \attention
+      54             : This directive modifies the stored position at the precise moment
+      55             : it is executed. This means that only collective variables
+      56             : which are below it in the input script will see the corrected positions.
+      57             : As a general rule, put it at the top of the input file. Also, unless you
+      58             : know exactly what you are doing, leave the default stride (1), so that
+      59             : this action is performed at every MD step.
+      60             : 
+      61             : The way WHOLEMOLECULES modifies each of the listed entities is this:
+      62             : - First atom of the list is left in place
+      63             : - Each atom of the list is shifted by a lattice vectors so that it becomes as close as possible
+      64             :   to the previous one, iteratively.
+      65             : 
+      66             : In this way, if an entity consists of a list of atoms such that consecutive atoms in the
+      67             : list are always closer than half a box side the entity will become whole.
+      68             : This can be usually achieved selecting consecutive atoms (1-100), but it is also possible
+      69             : to skip some atoms, provided consecutive chosen atoms are close enough.
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : This command instructs plumed to reconstruct the molecule containing atoms 1-20
+      74             : at every step of the calculation and dump them on a file.
+      75             : 
+      76             : \plumedfile
+      77             : # to see the effect, one could dump the atoms as they were before molecule reconstruction:
+      78             : # DUMPATOMS FILE=dump-broken.xyz ATOMS=1-20
+      79             : WHOLEMOLECULES ENTITY0=1-20
+      80             : DUMPATOMS FILE=dump.xyz ATOMS=1-20
+      81             : \endplumedfile
+      82             : 
+      83             : This command instructs plumed to reconstruct two molecules containing atoms 1-20 and 30-40
+      84             : 
+      85             : \plumedfile
+      86             : WHOLEMOLECULES ENTITY0=1-20 ENTITY1=30-40
+      87             : DUMPATOMS FILE=dump.xyz ATOMS=1-20,30-40
+      88             : \endplumedfile
+      89             : 
+      90             : This command instructs plumed to reconstruct the chain of backbone atoms in a
+      91             : protein
+      92             : 
+      93             : \plumedfile
+      94             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      95             : MOLINFO STRUCTURE=helix.pdb
+      96             : WHOLEMOLECULES RESIDUES=all MOLTYPE=protein
+      97             : \endplumedfile
+      98             : 
+      99             : */
+     100             : //+ENDPLUMEDOC
+     101             : 
+     102             : 
+     103             : class WholeMolecules:
+     104             :   public ActionPilot,
+     105             :   public ActionAtomistic
+     106             : {
+     107             :   std::vector<std::vector<AtomNumber> > groups;
+     108             :   std::vector<std::vector<AtomNumber> > roots;
+     109             :   std::vector<Vector> refs;
+     110             :   bool doemst, addref;
+     111             : public:
+     112             :   explicit WholeMolecules(const ActionOptions&ao);
+     113             :   static void registerKeywords( Keywords& keys );
+     114             :   void calculate() override;
+     115        3313 :   void apply() override {}
+     116             : };
+     117             : 
+     118       10485 : PLUMED_REGISTER_ACTION(WholeMolecules,"WHOLEMOLECULES")
+     119             : 
+     120          34 : void WholeMolecules::registerKeywords( Keywords& keys ) {
+     121          34 :   Action::registerKeywords( keys );
+     122          34 :   ActionPilot::registerKeywords( keys );
+     123          34 :   ActionAtomistic::registerKeywords( keys );
+     124          68 :   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!");
+     125          68 :   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,...");
+     126          68 :   keys.reset_style("ENTITY","atoms");
+     127          68 :   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 "
+     128             :            "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 "
+     129             :            "specifying all. Alternatively, if you wish to use a subset of the residues you can specify the particular residues "
+     130             :            "you are interested in as a list of numbers");
+     131          68 :   keys.add("optional","MOLTYPE","the type of molecule that is under study.  This is used to define the backbone atoms");
+     132          68 :   keys.addFlag("EMST", false, "Define atoms sequence in entities using an Euclidean minimum spanning tree");
+     133          68 :   keys.addFlag("ADDREFERENCE", false, "Define the reference position of the first atom of each entity using a PDB file");
+     134          34 : }
+     135             : 
+     136          33 : WholeMolecules::WholeMolecules(const ActionOptions&ao):
+     137             :   Action(ao),
+     138             :   ActionPilot(ao),
+     139             :   ActionAtomistic(ao),
+     140          33 :   doemst(false), addref(false)
+     141             : {
+     142             :   // parse optional flags
+     143          33 :   parseFlag("EMST", doemst);
+     144          66 :   parseFlag("ADDREFERENCE", addref);
+     145             : 
+     146             :   // create groups from ENTITY
+     147          34 :   for(int i=0;; i++) {
+     148             :     std::vector<AtomNumber> group;
+     149         134 :     parseAtomList("ENTITY",i,group);
+     150          67 :     if( group.empty() ) break;
+     151          34 :     groups.push_back(group);
+     152          34 :   }
+     153             : 
+     154             :   // Read residues to align from MOLINFO
+     155          66 :   std::vector<std::string> resstrings; parseVector("RESIDUES",resstrings);
+     156          33 :   if( resstrings.size()>0 ) {
+     157           0 :     if( resstrings.size()==1 ) {
+     158           0 :       if( resstrings[0]=="all" ) resstrings[0]="all-ter";   // Include terminal groups in alignment
+     159             :     }
+     160           0 :     std::string moltype; parse("MOLTYPE",moltype);
+     161           0 :     if(moltype.length()==0) error("Found RESIDUES keyword without specification of the molecule - use MOLTYPE");
+     162           0 :     auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     163           0 :     if( !moldat ) error("MOLINFO is required to use RESIDUES");
+     164             :     std::vector< std::vector<AtomNumber> > backatoms;
+     165           0 :     moldat->getBackbone( resstrings, moltype, backatoms );
+     166           0 :     for(unsigned i=0; i<backatoms.size(); ++i) {
+     167           0 :       groups.push_back( backatoms[i] );
+     168             :     }
+     169           0 :   }
+     170             : 
+     171             :   // check number of groups
+     172          33 :   if(groups.size()==0) error("no atoms found for WHOLEMOLECULES!");
+     173             : 
+     174             :   // if using PDBs reorder atoms in groups based on proximity in PDB file
+     175          33 :   if(doemst) {
+     176           0 :     auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     177           0 :     if( !moldat ) error("MOLINFO is required to use EMST");
+     178             :     // initialize tree
+     179           0 :     Tree tree = Tree(moldat);
+     180             :     // cycle on groups and reorder atoms
+     181           0 :     for(unsigned i=0; i<groups.size(); ++i) {
+     182           0 :       groups[i] = tree.getTree(groups[i]);
+     183             :       // store root atoms
+     184           0 :       roots.push_back(tree.getRoot());
+     185             :     }
+     186             :   } else {
+     187             :     // fill root vector with previous atom in groups
+     188          67 :     for(unsigned i=0; i<groups.size(); ++i) {
+     189             :       std::vector<AtomNumber> root;
+     190        2538 :       for(unsigned j=0; j<groups[i].size()-1; ++j) root.push_back(groups[i][j]);
+     191             :       // store root atoms
+     192          34 :       roots.push_back(root);
+     193             :     }
+     194             :   }
+     195             : 
+     196             :   // adding reference if needed
+     197          33 :   if(addref) {
+     198           2 :     auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     199           2 :     if( !moldat ) error("MOLINFO is required to use ADDREFERENCE");
+     200           4 :     for(unsigned i=0; i<groups.size(); ++i) {
+     201             :       // add reference position of first atom in entity
+     202           4 :       refs.push_back(moldat->getPosition(groups[i][0]));
+     203             :     }
+     204             :   }
+     205             : 
+     206             :   // print out info
+     207          67 :   for(unsigned i=0; i<groups.size(); ++i) {
+     208          34 :     log.printf("  atoms in entity %d : ",i);
+     209        2572 :     for(unsigned j=0; j<groups[i].size(); ++j) log.printf("%d ",groups[i][j].serial() );
+     210          34 :     log.printf("\n");
+     211          34 :     if(addref) log.printf("     with reference position : %lf %lf %lf\n",refs[i][0],refs[i][1],refs[i][2]);
+     212             :   }
+     213             : 
+     214             :   // collect all atoms
+     215             :   std::vector<AtomNumber> merge;
+     216          67 :   for(unsigned i=0; i<groups.size(); ++i) {
+     217          34 :     merge.insert(merge.end(),groups[i].begin(),groups[i].end());
+     218             :   }
+     219             : 
+     220          33 :   checkRead();
+     221          33 :   Tools::removeDuplicates(merge);
+     222          33 :   requestAtoms(merge);
+     223             :   doNotRetrieve();
+     224             :   doNotForce();
+     225          33 : }
+     226             : 
+     227        3313 : void WholeMolecules::calculate() {
+     228        6631 :   for(unsigned i=0; i<groups.size(); ++i) {
+     229        3318 :     if(addref) {
+     230             :       Vector & first (modifyGlobalPosition(groups[i][0]));
+     231          12 :       first = refs[i]+pbcDistance(refs[i],first);
+     232             :     }
+     233      294114 :     for(unsigned j=0; j<groups[i].size()-1; ++j) {
+     234             :       const Vector & first (getGlobalPosition(roots[i][j]));
+     235      290796 :       Vector & second (modifyGlobalPosition(groups[i][j+1]));
+     236      290796 :       second=first+pbcDistance(first,second);
+     237             :     }
+     238             :   }
+     239        3313 : }
+     240             : 
+     241             : 
+     242             : }
+     243             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..813be240ee --- /dev/null +++ b/coverage/generic/WrapAround.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:4646100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10WrapAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10WrapAroundC1ERKNS_13ActionOptionsE5
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe1616createERKNS_13ActionOptionsE5
_ZN4PLMD7generic10WrapAround16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7generic10WrapAround5applyEv579
_ZN4PLMD7generic10WrapAround9calculateEv579
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe161C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe161D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.func.html b/coverage/generic/WrapAround.cpp.func.html new file mode 100644 index 0000000000..994eec6f3b --- /dev/null +++ b/coverage/generic/WrapAround.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:4646100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10WrapAround16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7generic10WrapAround5applyEv579
_ZN4PLMD7generic10WrapAround9calculateEv579
_ZN4PLMD7generic10WrapAroundC1ERKNS_13ActionOptionsE5
_ZN4PLMD7generic10WrapAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe1616createERKNS_13ActionOptionsE5
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe161C2Ev3473
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe161D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.gcov.html b/coverage/generic/WrapAround.cpp.gcov.html new file mode 100644 index 0000000000..898b12f877 --- /dev/null +++ b/coverage/generic/WrapAround.cpp.gcov.html @@ -0,0 +1,313 @@ + + + + + + + + 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:4646100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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/Atoms.h"
+      29             : #include "core/PlumedMain.h"
+      30             : #include "core/ActionSet.h"
+      31             : #include "core/GenericMolInfo.h"
+      32             : 
+      33             : #include <vector>
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace generic {
+      37             : 
+      38             : //+PLUMEDOC GENERIC WRAPAROUND
+      39             : /*
+      40             : Rebuild periodic boundary conditions around chosen atoms.
+      41             : 
+      42             : 
+      43             : Modify position of atoms indicated by ATOMS by shifting them by lattice vectors so that they are
+      44             : as close as possible to the atoms indicated by AROUND. More precisely, for every atom i
+      45             : in the ATOMS list the following procedure is performed:
+      46             : - The atom j among those in the AROUND list is searched that is closest to atom i.
+      47             : - The atom i is replaced with its periodic image that is closest to atom j.
+      48             : 
+      49             : This action works similarly to \ref WHOLEMOLECULES in that it replaces atoms coordinate. Notice that only
+      50             : atoms specified with ATOMS are replaced, and that, at variance with \ref WHOLEMOLECULES,
+      51             : the order in which atoms are specified is irrelevant.
+      52             : 
+      53             : This is often convenient at a post processing stage (using the \ref driver), but sometime
+      54             : it is required during the simulation if collective variables need atoms to be in a specific periodic image.
+      55             : 
+      56             : \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.
+      57             : 
+      58             : Consider that the computational cost grows with the product
+      59             : of the size of the two lists (ATOMS and AROUND), so that this action can become very expensive.
+      60             : If you are using it to analyze a trajectory this is usually not a big problem. If you use it to
+      61             : analyze a simulation on the fly, e.g. with \ref DUMPATOMS to store a properly wrapped trajectory,
+      62             : consider the possibility of using the STRIDE keyword here (with great care).
+      63             : \par Examples
+      64             : 
+      65             : This command instructs plumed to move all the ions to their periodic image that is as close as possible to
+      66             : the rna group.
+      67             : 
+      68             : \plumedfile
+      69             : rna: GROUP ATOMS=1-100
+      70             : ions: GROUP ATOMS=101-110
+      71             : # first make the rna molecule whole
+      72             : WHOLEMOLECULES ENTITY0=rna
+      73             : WRAPAROUND ATOMS=ions AROUND=rna
+      74             : DUMPATOMS FILE=dump.xyz ATOMS=rna,ions
+      75             : \endplumedfile
+      76             : 
+      77             : In case you want to do it during a simulation and you only care about wrapping the ions in
+      78             : the `dump.xyz` file, you can use the following:
+      79             : 
+      80             : \plumedfile
+      81             : # add some restraint that do not require molecules to be whole:
+      82             : a: TORSION ATOMS=1,2,10,11
+      83             : RESTRAINT ARG=a AT=0.0 KAPPA=5
+      84             : 
+      85             : 
+      86             : # then do the things that are required for dumping the trajectory
+      87             : # notice that they are all done every 100 steps, so as not to
+      88             : # unnecessarily overload the calculation
+      89             : 
+      90             : rna: GROUP ATOMS=1-100
+      91             : ions: GROUP ATOMS=101-110
+      92             : # first make the rna molecule whole
+      93             : WHOLEMOLECULES ENTITY0=rna STRIDE=100
+      94             : WRAPAROUND ATOMS=ions AROUND=rna STRIDE=100
+      95             : DUMPATOMS FILE=dump.xyz ATOMS=rna,ions STRIDE=100
+      96             : \endplumedfile
+      97             : 
+      98             : Notice that if the biased variable requires a molecule to be whole, you might have to put
+      99             : just the \ref WHOLEMOLECULES command before computing that variable and leave the default STRIDE=1.
+     100             : 
+     101             : This command instructs plumed to center all atoms around the center of mass of a solute molecule.
+     102             : 
+     103             : \plumedfile
+     104             : solute: GROUP ATOMS=1-100
+     105             : all: GROUP ATOMS=1-1000
+     106             : # center of the solute:
+     107             : # notice that since plumed 2.2 this also works if the
+     108             : # solute molecule is broken
+     109             : com: COM ATOMS=solute
+     110             : # notice that we wrap around a single atom. this should be fast
+     111             : WRAPAROUND ATOMS=all AROUND=com
+     112             : DUMPATOMS FILE=dump.xyz ATOMS=all
+     113             : \endplumedfile
+     114             : 
+     115             : Notice that whereas \ref WHOLEMOLECULES is designed to make molecules whole,
+     116             : \ref WRAPAROUND can easily break molecules. In the last example,
+     117             : if solvent (atoms 101-1000) is made e.g. of water, then water
+     118             : molecules could be broken by \ref WRAPAROUND (hydrogen could end up
+     119             : in an image and oxygen in another one).
+     120             : One solution is to use \ref WHOLEMOLECULES on _all_ the water molecules
+     121             : after \ref WRAPAROUND. This is tedious. A better solution is to use the
+     122             : GROUPBY option which is going
+     123             : to consider the atoms listed in ATOMS as a list of groups
+     124             : each of size GROUPBY. The first atom of the group will be brought
+     125             : close to the AROUND atoms. The following atoms of the group
+     126             : will be just brought close to the first atom of the group.
+     127             : Assuming that oxygen is the first atom of each water molecules,
+     128             : in the following examples all the water oxygen atoms will be brought
+     129             : close to the solute, and all the hydrogen atoms will be kept close
+     130             : to their related oxygen.
+     131             : 
+     132             : \plumedfile
+     133             : solute: GROUP ATOMS=1-100
+     134             : water: GROUP ATOMS=101-1000
+     135             : com: COM ATOMS=solute
+     136             : # notice that we wrap around a single atom. this should be fast
+     137             : WRAPAROUND ATOMS=solute AROUND=com
+     138             : # notice that we wrap around a single atom. this should be fast
+     139             : WRAPAROUND ATOMS=water AROUND=com GROUPBY=3
+     140             : DUMPATOMS FILE=dump.xyz ATOMS=solute,water
+     141             : \endplumedfile
+     142             : 
+     143             : */
+     144             : //+ENDPLUMEDOC
+     145             : 
+     146             : 
+     147             : class WrapAround:
+     148             :   public ActionPilot,
+     149             :   public ActionAtomistic
+     150             : {
+     151             :   std::vector<AtomNumber> atoms;
+     152             :   std::vector<AtomNumber> reference;
+     153             :   unsigned groupby;
+     154             : public:
+     155             :   explicit WrapAround(const ActionOptions&ao);
+     156             :   static void registerKeywords( Keywords& keys );
+     157             :   void calculate() override;
+     158         579 :   void apply() override {}
+     159             : };
+     160             : 
+     161       10429 : PLUMED_REGISTER_ACTION(WrapAround,"WRAPAROUND")
+     162             : 
+     163           6 : void WrapAround::registerKeywords( Keywords& keys ) {
+     164           6 :   Action::registerKeywords( keys );
+     165           6 :   ActionAtomistic::registerKeywords( keys );
+     166           6 :   ActionPilot::registerKeywords( keys );
+     167          12 :   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!");
+     168          12 :   keys.add("atoms","AROUND","reference atoms");
+     169          12 :   keys.add("atoms","ATOMS","wrapped atoms");
+     170          12 :   keys.add("compulsory","GROUPBY","1","group atoms so as not to break molecules");
+     171           6 : }
+     172             : 
+     173           5 : WrapAround::WrapAround(const ActionOptions&ao):
+     174             :   Action(ao),
+     175             :   ActionPilot(ao),
+     176             :   ActionAtomistic(ao),
+     177           5 :   groupby(1)
+     178             : {
+     179           5 :   parseAtomList("ATOMS",atoms);
+     180           5 :   parseAtomList("AROUND",reference);
+     181           5 :   parse("GROUPBY",groupby);
+     182             : 
+     183           5 :   log.printf("  atoms in reference :");
+     184          11 :   for(unsigned j=0; j<reference.size(); ++j) log.printf(" %d",reference[j].serial() );
+     185           5 :   log.printf("\n");
+     186           5 :   log.printf("  atoms to be wrapped :");
+     187         399 :   for(unsigned j=0; j<atoms.size(); ++j) log.printf(" %d",atoms[j].serial() );
+     188           5 :   log.printf("\n");
+     189           5 :   if(groupby>1) log<<"  atoms will be grouped by "<<groupby<<"\n";
+     190             : 
+     191           5 :   if(atoms.size()%groupby!=0) error("number of atoms should be a multiple of groupby option");
+     192             : 
+     193           5 :   checkRead();
+     194             : 
+     195           5 :   if(groupby<=1) Tools::removeDuplicates(atoms);
+     196           5 :   Tools::removeDuplicates(reference);
+     197             : 
+     198           5 :   std::vector<AtomNumber> merged(atoms.size()+reference.size());
+     199           5 :   merge(atoms.begin(),atoms.end(),reference.begin(),reference.end(),merged.begin());
+     200           5 :   Tools::removeDuplicates(merged);
+     201           5 :   requestAtoms(merged);
+     202             :   doNotRetrieve();
+     203             :   doNotForce();
+     204           5 : }
+     205             : 
+     206         579 : void WrapAround::calculate() {
+     207       15012 :   for(unsigned i=0; i<atoms.size(); i+=groupby) {
+     208             :     Vector & first (modifyGlobalPosition(atoms[i]));
+     209             :     double mindist2=std::numeric_limits<double>::max();
+     210             :     int closest=-1;
+     211       29416 :     for(unsigned j=0; j<reference.size(); ++j) {
+     212             :       Vector & second (modifyGlobalPosition(reference[j]));
+     213       14983 :       Vector distance=pbcDistance(first,second);
+     214       14983 :       double distance2=modulo2(distance);
+     215       14983 :       if(distance2<mindist2) {
+     216             :         mindist2=distance2;
+     217       14713 :         closest=j;
+     218             :       }
+     219             :     }
+     220       14433 :     plumed_massert(closest>=0,"closest not found");
+     221       14433 :     Vector & second (modifyGlobalPosition(reference[closest]));
+     222             : // place first atom of the group
+     223       14433 :     first=second+pbcDistance(second,first);
+     224             : // then place other atoms close to the first of the group
+     225       14928 :     for(unsigned j=1; j<groupby; j++) {
+     226         495 :       Vector & second (modifyGlobalPosition(atoms[i+j]));
+     227         495 :       second=first+pbcDistance(first,second);
+     228             :     }
+     229             :   }
+     230         579 : }
+     231             : 
+     232             : 
+     233             : 
+     234             : }
+     235             : 
+     236             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/index-sort-f.html b/coverage/generic/index-sort-f.html new file mode 100644 index 0000000000..083f46f18d --- /dev/null +++ b/coverage/generic/index-sort-f.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1197126794.5 %
Date:2024-06-10 08:19:14Functions:17722279.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Time.cpp +
33.3%33.3%
+
33.3 %5 / 1533.3 %3 / 9
RandomExchanges.cpp +
35.7%35.7%
+
35.7 %5 / 1442.9 %3 / 7
Include.cpp +
84.6%84.6%
+
84.6 %11 / 1362.5 %5 / 8
Group.cpp +
97.3%97.3%
+
97.3 %71 / 7363.6 %7 / 11
EndPlumed.cpp +
81.8%81.8%
+
81.8 %9 / 1171.4 %5 / 7
FitToTemplate.cpp +
96.6%96.6%
+
96.6 %86 / 8977.8 %7 / 9
DumpForces.cpp +
100.0%
+
100.0 %38 / 3883.3 %10 / 12
EffectiveEnergyDrift.cpp +
96.9%96.9%
+
96.9 %123 / 12783.3 %10 / 12
DumpAtoms.cpp +
98.3%98.3%
+
98.3 %119 / 12183.3 %10 / 12
DumpDerivatives.cpp +
100.0%
+
100.0 %47 / 4783.3 %10 / 12
DumpMassCharge.cpp +
98.4%98.4%
+
98.4 %62 / 6384.6 %11 / 13
DumpProjections.cpp +
100.0%
+
100.0 %39 / 3984.6 %11 / 13
Print.cpp +
96.6%96.6%
+
96.6 %56 / 5884.6 %11 / 13
UpdateIf.cpp +
100.0%
+
100.0 %43 / 4384.6 %11 / 13
Plumed.cpp +
93.3%93.3%
+
93.3 %167 / 17985.7 %12 / 14
Read.cpp +
95.0%95.0%
+
95.0 %95 / 10085.7 %12 / 14
Debug.cpp +
100.0%
+
100.0 %57 / 5787.5 %7 / 8
WrapAround.cpp +
100.0%
+
100.0 %46 / 4687.5 %7 / 8
ResetCell.cpp +
100.0%
+
100.0 %43 / 4387.5 %7 / 8
WholeMolecules.cpp +
77.1%77.1%
+
77.1 %54 / 7087.5 %7 / 8
MolInfo.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
Flush.cpp +
100.0%
+
100.0 %20 / 20100.0 %8 / 8
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/index-sort-l.html b/coverage/generic/index-sort-l.html new file mode 100644 index 0000000000..bf31d68cf1 --- /dev/null +++ b/coverage/generic/index-sort-l.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1197126794.5 %
Date:2024-06-10 08:19:14Functions:17722279.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Time.cpp +
33.3%33.3%
+
33.3 %5 / 1533.3 %3 / 9
RandomExchanges.cpp +
35.7%35.7%
+
35.7 %5 / 1442.9 %3 / 7
WholeMolecules.cpp +
77.1%77.1%
+
77.1 %54 / 7087.5 %7 / 8
EndPlumed.cpp +
81.8%81.8%
+
81.8 %9 / 1171.4 %5 / 7
Include.cpp +
84.6%84.6%
+
84.6 %11 / 1362.5 %5 / 8
Plumed.cpp +
93.3%93.3%
+
93.3 %167 / 17985.7 %12 / 14
Read.cpp +
95.0%95.0%
+
95.0 %95 / 10085.7 %12 / 14
Print.cpp +
96.6%96.6%
+
96.6 %56 / 5884.6 %11 / 13
FitToTemplate.cpp +
96.6%96.6%
+
96.6 %86 / 8977.8 %7 / 9
EffectiveEnergyDrift.cpp +
96.9%96.9%
+
96.9 %123 / 12783.3 %10 / 12
Group.cpp +
97.3%97.3%
+
97.3 %71 / 7363.6 %7 / 11
DumpAtoms.cpp +
98.3%98.3%
+
98.3 %119 / 12183.3 %10 / 12
DumpMassCharge.cpp +
98.4%98.4%
+
98.4 %62 / 6384.6 %11 / 13
MolInfo.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
Flush.cpp +
100.0%
+
100.0 %20 / 20100.0 %8 / 8
DumpForces.cpp +
100.0%
+
100.0 %38 / 3883.3 %10 / 12
DumpProjections.cpp +
100.0%
+
100.0 %39 / 3984.6 %11 / 13
UpdateIf.cpp +
100.0%
+
100.0 %43 / 4384.6 %11 / 13
ResetCell.cpp +
100.0%
+
100.0 %43 / 4387.5 %7 / 8
WrapAround.cpp +
100.0%
+
100.0 %46 / 4687.5 %7 / 8
DumpDerivatives.cpp +
100.0%
+
100.0 %47 / 4783.3 %10 / 12
Debug.cpp +
100.0%
+
100.0 %57 / 5787.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/generic/index.html b/coverage/generic/index.html new file mode 100644 index 0000000000..b5a0874082 --- /dev/null +++ b/coverage/generic/index.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1197126794.5 %
Date:2024-06-10 08:19:14Functions:17722279.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Debug.cpp +
100.0%
+
100.0 %57 / 5787.5 %7 / 8
DumpAtoms.cpp +
98.3%98.3%
+
98.3 %119 / 12183.3 %10 / 12
DumpDerivatives.cpp +
100.0%
+
100.0 %47 / 4783.3 %10 / 12
DumpForces.cpp +
100.0%
+
100.0 %38 / 3883.3 %10 / 12
DumpMassCharge.cpp +
98.4%98.4%
+
98.4 %62 / 6384.6 %11 / 13
DumpProjections.cpp +
100.0%
+
100.0 %39 / 3984.6 %11 / 13
EffectiveEnergyDrift.cpp +
96.9%96.9%
+
96.9 %123 / 12783.3 %10 / 12
EndPlumed.cpp +
81.8%81.8%
+
81.8 %9 / 1171.4 %5 / 7
FitToTemplate.cpp +
96.6%96.6%
+
96.6 %86 / 8977.8 %7 / 9
Flush.cpp +
100.0%
+
100.0 %20 / 20100.0 %8 / 8
Group.cpp +
97.3%97.3%
+
97.3 %71 / 7363.6 %7 / 11
Include.cpp +
84.6%84.6%
+
84.6 %11 / 1362.5 %5 / 8
MolInfo.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
Plumed.cpp +
93.3%93.3%
+
93.3 %167 / 17985.7 %12 / 14
Print.cpp +
96.6%96.6%
+
96.6 %56 / 5884.6 %11 / 13
RandomExchanges.cpp +
35.7%35.7%
+
35.7 %5 / 1442.9 %3 / 7
Read.cpp +
95.0%95.0%
+
95.0 %95 / 10085.7 %12 / 14
ResetCell.cpp +
100.0%
+
100.0 %43 / 4387.5 %7 / 8
Time.cpp +
33.3%33.3%
+
33.3 %5 / 1533.3 %3 / 9
UpdateIf.cpp +
100.0%
+
100.0 %43 / 4384.6 %11 / 13
WholeMolecules.cpp +
77.1%77.1%
+
77.1 %54 / 7087.5 %7 / 8
WrapAround.cpp +
100.0%
+
100.0 %46 / 4687.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..93dd1f468b --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14ActionWithGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools14ActionWithGrid17turnOnDerivativesEv16
_ZN4PLMD9gridtools14ActionWithGrid10createGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_65
_ZN4PLMD9gridtools14ActionWithGridC2ERKNS_13ActionOptionsE70
_ZN4PLMD9gridtools14ActionWithGrid16registerKeywordsERNS_8KeywordsE79
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv215
_ZNK4PLMD9gridtools14ActionWithGrid7runTaskERKjRNS_10MultiValueE57902
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithGrid.cpp.func.html b/coverage/gridtools/ActionWithGrid.cpp.func.html new file mode 100644 index 0000000000..839f87415f --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14ActionWithGrid10createGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_65
_ZN4PLMD9gridtools14ActionWithGrid16registerKeywordsERNS_8KeywordsE79
_ZN4PLMD9gridtools14ActionWithGrid17turnOnDerivativesEv16
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv215
_ZN4PLMD9gridtools14ActionWithGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools14ActionWithGridC2ERKNS_13ActionOptionsE70
_ZNK4PLMD9gridtools14ActionWithGrid7runTaskERKjRNS_10MultiValueE57902
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithGrid.cpp.gcov.html b/coverage/gridtools/ActionWithGrid.cpp.gcov.html new file mode 100644 index 0000000000..13a4a8bd0c --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.gcov.html @@ -0,0 +1,186 @@ + + + + + + + + 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-06-10 08:19:14Functions: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          79 : void ActionWithGrid::registerKeywords( Keywords& keys ) {
+      30          79 :   vesselbase::ActionWithAveraging::registerKeywords( keys );
+      31         158 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density estimation");
+      32         158 :   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         158 :   keys.add("optional","CONCENTRATION","the concentration parameter for Von Mises-Fisher distributions");
+      35          79 : }
+      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          78 :       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          40 :     grid=Tools::make_unique<GridVessel>(dar);
+      67             :   } else {
+      68           0 :     plumed_merror("no way to create grid of type " + type );
+      69             :   }
+      70          65 :   mygrid=grid.get();
+      71          65 :   return grid;
+      72          65 : }
+      73             : 
+      74          16 : void ActionWithGrid::turnOnDerivatives() {
+      75          16 :   needsDerivatives(); ActionWithValue::turnOnDerivatives();
+      76          16 :   if( getStride()==1 ) setStride(0);
+      77           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");
+      78          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" );
+      79          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");
+      80          16 : }
+      81             : 
+      82         215 : void ActionWithGrid::calculate() {
+      83             :   // Do nothing if derivatives are not required
+      84         215 :   if( doNotCalculateDerivatives() ) return;
+      85             :   // Clear on every step
+      86          40 :   if( mygrid ) clearAverage();
+      87             :   // Should not be any reweighting so just set these accordingly
+      88          40 :   lweight=0; cweight=1.0;
+      89             :   // Prepare to do the averaging
+      90          40 :   prepareForAveraging();
+      91             :   // Run all the tasks (if required
+      92          40 :   if( useRunAllTasks ) runAllTasks();
+      93             :   // This the averaging if it is not done using task list
+      94          20 :   else performOperations( true );
+      95             :   // Update the norm
+      96          40 :   if( mygrid ) mygrid->setNorm( cweight );
+      97             :   // Finish the averaging
+      98          40 :   finishAveraging();
+      99             :   // And reset for next step
+     100          40 :   if( mygrid ) mygrid->reset();
+     101             : }
+     102             : 
+     103       57902 : void ActionWithGrid::runTask( const unsigned& current, MultiValue& myvals ) const {
+     104             :   // Set the weight of this point
+     105       57902 :   myvals.setValue( 0, cweight ); compute( current, myvals );
+     106       57902 : }
+     107             : 
+     108             : }
+     109             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..610501adbb --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools19ActionWithInputGrid17performOperationsERKb21
_ZN4PLMD9gridtools19ActionWithInputGridC2ERKNS_13ActionOptionsE25
_ZN4PLMD9gridtools19ActionWithInputGrid12clearAverageEv26
_ZN4PLMD9gridtools19ActionWithInputGrid16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD9gridtools19ActionWithInputGrid19prepareForAveragingEv70
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.cpp.func.html b/coverage/gridtools/ActionWithInputGrid.cpp.func.html new file mode 100644 index 0000000000..a400b6c652 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGrid12clearAverageEv26
_ZN4PLMD9gridtools19ActionWithInputGrid16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD9gridtools19ActionWithInputGrid17performOperationsERKb21
_ZN4PLMD9gridtools19ActionWithInputGrid19prepareForAveragingEv70
_ZN4PLMD9gridtools19ActionWithInputGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools19ActionWithInputGridC2ERKNS_13ActionOptionsE25
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.cpp.gcov.html b/coverage/gridtools/ActionWithInputGrid.cpp.gcov.html new file mode 100644 index 0000000000..868ee88b28 --- /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-06-10 08:19:14Functions: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          32 : void ActionWithInputGrid::registerKeywords( Keywords& keys ) {
+      30          32 :   ActionWithGrid::registerKeywords( keys );
+      31          64 :   keys.add("compulsory","GRID","the action that creates the input grid you would like to use");
+      32          64 :   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          32 : }
+      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          77 :   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.15
+
+ + + 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 0000000000..3059b5ace5 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGrid5applyEv28
_ZNK4PLMD9gridtools19ActionWithInputGrid14checkAllActiveEv70
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKSt6vectorIjSaIjEE32928
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKj117146
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.h.func.html b/coverage/gridtools/ActionWithInputGrid.h.func.html new file mode 100644 index 0000000000..4501dfd350 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGrid5applyEv28
_ZNK4PLMD9gridtools19ActionWithInputGrid14checkAllActiveEv70
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKSt6vectorIjSaIjEE32928
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKj117146
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.h.gcov.html b/coverage/gridtools/ActionWithInputGrid.h.gcov.html new file mode 100644 index 0000000000..397097e659 --- /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-06-10 08:19:14Functions: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        8545 :   return ingrid->getValueAndDerivatives( x, mycomp, der );
+      64             : }
+      65             : 
+      66             : }
+      67             : }
+      68             : #endif
+      69             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bf302e8d96 --- /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-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegralC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ActionWithIntegralC2ERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools18ActionWithIntegral16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD9gridtools18ActionWithIntegral17turnOnDerivativesEv8
_ZN4PLMD9gridtools18ActionWithIntegral5applyEv20
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.cpp.func.html b/coverage/gridtools/ActionWithIntegral.cpp.func.html new file mode 100644 index 0000000000..eb2d04e864 --- /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-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegral16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD9gridtools18ActionWithIntegral17turnOnDerivativesEv8
_ZN4PLMD9gridtools18ActionWithIntegral5applyEv20
_ZN4PLMD9gridtools18ActionWithIntegralC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ActionWithIntegralC2ERKNS_13ActionOptionsE4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.cpp.gcov.html b/coverage/gridtools/ActionWithIntegral.cpp.gcov.html new file mode 100644 index 0000000000..a005beebad --- /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-06-10 08:19:14Functions: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           5 : void ActionWithIntegral::registerKeywords( Keywords& keys ) {
+      28           5 :   ActionWithInputGrid::registerKeywords( keys );
+      29          10 :   keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      30          15 :   keys.remove("CLEAR"); keys.add("compulsory","CLEAR","1","the frequency with which to clear all the accumulated data.");
+      31           5 : }
+      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.15
+
+ + + 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 0000000000..922b6ef7d8 --- /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-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegral10isPeriodicEv0
_ZN4PLMD9gridtools18ActionWithIntegral22getNumberOfDerivativesEv102
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.h.func.html b/coverage/gridtools/ActionWithIntegral.h.func.html new file mode 100644 index 0000000000..539d1de30a --- /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-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegral10isPeriodicEv0
_ZN4PLMD9gridtools18ActionWithIntegral22getNumberOfDerivativesEv102
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.h.gcov.html b/coverage/gridtools/ActionWithIntegral.h.gcov.html new file mode 100644 index 0000000000..3ff2dd88ef --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..386538ced9 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGridC2ERKNS_10vesselbase13VesselOptionsE8
_ZN4PLMD9gridtools13AverageOnGrid16registerKeywordsERNS_8KeywordsE65
_ZNK4PLMD9gridtools13AverageOnGrid14getGridElementERKjS3_361766
_ZNK4PLMD9gridtools13AverageOnGrid10accumulateERKjRKdS5_RKSt6vectorIdSaIdEERS8_11825111
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.cpp.func.html b/coverage/gridtools/AverageOnGrid.cpp.func.html new file mode 100644 index 0000000000..15d5c25a31 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGrid16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD9gridtools13AverageOnGridC2ERKNS_10vesselbase13VesselOptionsE8
_ZNK4PLMD9gridtools13AverageOnGrid10accumulateERKjRKdS5_RKSt6vectorIdSaIdEERS8_11825111
_ZNK4PLMD9gridtools13AverageOnGrid14getGridElementERKjS3_361766
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.cpp.gcov.html b/coverage/gridtools/AverageOnGrid.cpp.gcov.html new file mode 100644 index 0000000000..c88b84b7bf --- /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-06-10 08:19:14Functions: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      361766 : double AverageOnGrid::getGridElement( const unsigned& ipoint, const unsigned& jelement ) const {
+      52      361766 :   if( noAverage() ) return getDataElement( nper*ipoint + jelement);
+      53             : 
+      54      360566 :   if( jelement>=(nper-(dimension+1)) ) return getDataElement( nper*ipoint + jelement );
+      55             : 
+      56      360066 :   if( noderiv ) return getDataElement( nper*ipoint+jelement ) / getDataElement( nper*(1+ipoint) - 1);
+      57             : 
+      58             :   double rdenom = 1.0;
+      59      360066 :   if( std::fabs(getDataElement( nper*(ipoint+1) -(dimension+1) ))>epsilon ) rdenom = 1. / getDataElement( nper*(ipoint+1) - (dimension+1) );
+      60             : 
+      61      360066 :   unsigned jderiv = jelement%(1+dimension);
+      62      360066 :   if( jderiv==0 ) return rdenom*getDataElement( nper*ipoint+jelement );
+      63             : 
+      64      203130 :   unsigned jfloor = std::floor( jelement / (1+dimension) );
+      65      203130 :   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.15
+
+ + + 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 0000000000..95a2bb597d --- /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-06-10 08:19:14Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGrid14getFinalForcesERKSt6vectorIdSaIdEERS4_0
_ZNK4PLMD9gridtools13AverageOnGrid15accumulateForceERKjRKdRKSt6vectorIdSaIdEERS8_0
_ZNK4PLMD9gridtools13AverageOnGrid21getNumberOfComponentsEv7
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.h.func.html b/coverage/gridtools/AverageOnGrid.h.func.html new file mode 100644 index 0000000000..3e05ce9ac8 --- /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-06-10 08:19:14Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGrid14getFinalForcesERKSt6vectorIdSaIdEERS4_0
_ZNK4PLMD9gridtools13AverageOnGrid15accumulateForceERKjRKdRKSt6vectorIdSaIdEERS8_0
_ZNK4PLMD9gridtools13AverageOnGrid21getNumberOfComponentsEv7
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.h.gcov.html b/coverage/gridtools/AverageOnGrid.h.gcov.html new file mode 100644 index 0000000000..322f205e0d --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..2b34e0612d --- /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-06-10 08:19:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ContourFindingBaseC2ERKNS_13ActionOptionsE3
_ZN4PLMD9gridtools18ContourFindingBase16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.cpp.func.html b/coverage/gridtools/ContourFindingBase.cpp.func.html new file mode 100644 index 0000000000..a52983dd34 --- /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-06-10 08:19:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBase16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ContourFindingBaseC2ERKNS_13ActionOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.cpp.gcov.html b/coverage/gridtools/ContourFindingBase.cpp.gcov.html new file mode 100644 index 0000000000..daad6ad484 --- /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-06-10 08:19:14Functions: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           6 : void ContourFindingBase::registerKeywords( Keywords& keys ) {
+      28           6 :   ActionWithInputGrid::registerKeywords( keys );
+      29          12 :   keys.add("compulsory","CONTOUR","the value we would like to draw the contour at in the space");
+      30          12 :   keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      31           6 : }
+      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.15
+
+ + + 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 0000000000..5ef424b2d0 --- /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-06-10 08:19:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBase10isPeriodicEv0
_ZN4PLMD9gridtools18ContourFindingBase22getNumberOfDerivativesEv32
_ZNK4PLMD9gridtools18ContourFindingBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_8245
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.h.func.html b/coverage/gridtools/ContourFindingBase.h.func.html new file mode 100644 index 0000000000..ac628b6577 --- /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-06-10 08:19:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBase10isPeriodicEv0
_ZN4PLMD9gridtools18ContourFindingBase22getNumberOfDerivativesEv32
_ZNK4PLMD9gridtools18ContourFindingBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_8245
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.h.gcov.html b/coverage/gridtools/ContourFindingBase.h.gcov.html new file mode 100644 index 0000000000..c57ad769c5 --- /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-06-10 08:19:14Functions: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        8245 : double ContourFindingBase::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) const {
+      58        8345 :   return getFunctionValueAndDerivatives( x, der ) - contour;
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+      63             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b8935e0819 --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + 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:464895.8 %
Date:2024-06-10 08:19:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12ConvertToFES10isPeriodicEv0
_ZN4PLMD9gridtools12ConvertToFESC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12ConvertToFES7prepareEv12
_ZN4PLMD9gridtools12ConvertToFES12runFinalJobsEv15
_ZN4PLMD9gridtools12ConvertToFESC1ERKNS_13ActionOptionsE15
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe816createERKNS_13ActionOptionsE15
_ZNK4PLMD9gridtools12ConvertToFES19ignoreNormalizationEv15
_ZN4PLMD9gridtools12ConvertToFES16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD9gridtools12ConvertToFES18finishComputationsERKSt6vectorIdSaIdEE23
_ZN4PLMD9gridtools12ConvertToFES19prepareForAveragingEv23
_ZNK4PLMD9gridtools12ConvertToFES21getNumberOfQuantitiesEv92
_ZNK4PLMD9gridtools12ConvertToFES6onStepEv2234
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe81C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe81D2Ev3473
_ZNK4PLMD9gridtools12ConvertToFES7computeERKjRNS_10MultiValueE14199
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.func.html b/coverage/gridtools/ConvertToFES.cpp.func.html new file mode 100644 index 0000000000..08fca5d95c --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + 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:464895.8 %
Date:2024-06-10 08:19:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12ConvertToFES10isPeriodicEv0
_ZN4PLMD9gridtools12ConvertToFES12runFinalJobsEv15
_ZN4PLMD9gridtools12ConvertToFES16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD9gridtools12ConvertToFES18finishComputationsERKSt6vectorIdSaIdEE23
_ZN4PLMD9gridtools12ConvertToFES19prepareForAveragingEv23
_ZN4PLMD9gridtools12ConvertToFES7prepareEv12
_ZN4PLMD9gridtools12ConvertToFESC1ERKNS_13ActionOptionsE15
_ZN4PLMD9gridtools12ConvertToFESC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe816createERKNS_13ActionOptionsE15
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe81C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe81D2Ev3473
_ZNK4PLMD9gridtools12ConvertToFES19ignoreNormalizationEv15
_ZNK4PLMD9gridtools12ConvertToFES21getNumberOfQuantitiesEv92
_ZNK4PLMD9gridtools12ConvertToFES6onStepEv2234
_ZNK4PLMD9gridtools12ConvertToFES7computeERKjRNS_10MultiValueE14199
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.gcov.html b/coverage/gridtools/ConvertToFES.cpp.gcov.html new file mode 100644 index 0000000000..7866978372 --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.gcov.html @@ -0,0 +1,224 @@ + + + + + + + + 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:464895.8 %
Date:2024-06-10 08:19:14Functions: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 "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/Atoms.h"
+      25             : #include "ActionWithInputGrid.h"
+      26             : 
+      27             : //+PLUMEDOC GRIDANALYSIS CONVERT_TO_FES
+      28             : /*
+      29             : Convert a histogram, \f$H(x)\f$, to a free energy surface using \f$F(x) = -k_B T \ln H(x)\f$.
+      30             : 
+      31             : This action allows you to take a free energy surface that was calculated using the \ref HISTOGRAM
+      32             : action and to convert it to a free energy surface.  This transformation performed by doing:
+      33             : 
+      34             : \f[
+      35             : F(x) = -k_B T \ln H(x)
+      36             : \f]
+      37             : 
+      38             : The free energy calculated on a grid is output by this action and can be printed using \ref DUMPGRID
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : This is a typical example showing how CONVERT_TO_FES might be used when post processing a trajectory.
+      43             : The input below calculates the free energy as a function of the distance between atom 1 and atom 2.
+      44             : This is done by accumulating a histogram as a function of this distance using kernel density estimation
+      45             : and the HISTOGRAM action.  All the data within this trajectory is used in the construction of this
+      46             : HISTOGRAM.  Finally, once all the data has been read in, the histogram is converted to a free energy
+      47             : using the formula above and the free energy is output to a file called fes.dat
+      48             : 
+      49             : \plumedfile
+      50             : x: DISTANCE ATOMS=1,2
+      51             : hA1: HISTOGRAM ARG=x GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 BANDWIDTH=0.1
+      52             : ff: CONVERT_TO_FES GRID=hA1 TEMP=300
+      53             : DUMPGRID GRID=ff FILE=fes.dat
+      54             : \endplumedfile
+      55             : 
+      56             : */
+      57             : //+ENDPLUMEDOC
+      58             : 
+      59             : namespace PLMD {
+      60             : namespace gridtools {
+      61             : 
+      62             : class ConvertToFES : public ActionWithInputGrid {
+      63             : private:
+      64             :   double simtemp;
+      65             :   bool activated;
+      66             :   bool mintozero;
+      67             : public:
+      68             :   static void registerKeywords( Keywords& keys );
+      69             :   explicit ConvertToFES(const ActionOptions&ao);
+      70             :   unsigned getNumberOfQuantities() const override;
+      71          15 :   bool ignoreNormalization() const override { return true; }
+      72          12 :   void prepare() override { activated=true; }
+      73          23 :   void prepareForAveraging() override { ActionWithInputGrid::prepareForAveraging(); activated=false; }
+      74             :   void compute( const unsigned& current, MultiValue& myvals ) const override;
+      75             :   void finishComputations( const std::vector<double>& buffer ) override;
+      76           0 :   bool isPeriodic() override { return false; }
+      77        2234 :   bool onStep() const override { return activated; }
+      78             :   void runFinalJobs() override;
+      79             : };
+      80             : 
+      81       10449 : PLUMED_REGISTER_ACTION(ConvertToFES,"CONVERT_TO_FES")
+      82             : 
+      83          16 : void ConvertToFES::registerKeywords( Keywords& keys ) {
+      84          16 :   ActionWithInputGrid::registerKeywords( keys );
+      85          32 :   keys.add("optional","TEMP","the temperature at which you are operating");
+      86          32 :   keys.addFlag("MINTOZERO",false,"set the minimum in the free energy to be equal to zero");
+      87          48 :   keys.remove("STRIDE"); keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      88          48 :   keys.remove("LOGWEIGHTS"); keys.remove("CLEAR"); keys.remove("NORMALIZATION");
+      89          16 : }
+      90             : 
+      91          15 : ConvertToFES::ConvertToFES(const ActionOptions&ao):
+      92             :   Action(ao),
+      93             :   ActionWithInputGrid(ao),
+      94          15 :   activated(false)
+      95             : {
+      96          15 :   plumed_assert( ingrid->getNumberOfComponents()==1 );
+      97             : 
+      98             :   // Create a grid
+      99          47 :   auto grid=createGrid( "grid", "COMPONENTS=" + getLabel() + " " + ingrid->getInputString() );
+     100          15 :   if( ingrid->noDerivatives() ) grid->setNoDerivatives();
+     101             :   std::vector<double> fspacing;
+     102          15 :   grid->setBounds( ingrid->getMin(), ingrid->getMax(), ingrid->getNbin(), fspacing);
+     103          15 :   setAveragingAction( std::move(grid), true );
+     104             : 
+     105          30 :   simtemp=0.; parse("TEMP",simtemp); parseFlag("MINTOZERO",mintozero);
+     106          15 :   if(simtemp>0) simtemp*=plumed.getAtoms().getKBoltzmann();
+     107           0 :   else simtemp=plumed.getAtoms().getKbT();
+     108          15 :   if( simtemp==0 ) error("TEMP not set - use keyword TEMP");
+     109             : 
+     110             :   // Now create task list
+     111        8486 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) addTaskToList(i);
+     112             :   // And activate all tasks
+     113          15 :   deactivateAllTasks();
+     114        8486 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) taskFlags[i]=1;
+     115          15 :   lockContributors();
+     116          15 : }
+     117             : 
+     118          92 : unsigned ConvertToFES::getNumberOfQuantities() const {
+     119          92 :   if( mygrid->noDerivatives() ) return 2;
+     120          64 :   return 2 + mygrid->getDimension();
+     121             : }
+     122             : 
+     123       14199 : void ConvertToFES::compute( const unsigned& current, MultiValue& myvals ) const {
+     124       14199 :   double val=getFunctionValue( current ); myvals.setValue(1, -simtemp*std::log(val) );
+     125       14199 :   if( !mygrid->noDerivatives() && val>0 ) {
+     126       36998 :     for(unsigned i=0; i<mygrid->getDimension(); ++i) myvals.setValue( 2+i, -(simtemp/val)*ingrid->getGridElement(current,i+1) );
+     127             :   }
+     128       14199 : }
+     129             : 
+     130          23 : void ConvertToFES::finishComputations( const std::vector<double>& buffer ) {
+     131          23 :   ActionWithVessel::finishComputations( buffer );
+     132          23 :   if(!mintozero) return;
+     133             : 
+     134           2 :   double optval = mygrid->getGridElement( 0, 0 );
+     135        2602 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) {
+     136        2600 :     double tval = mygrid->getGridElement( i, 0 );
+     137        2600 :     if( tval<optval || std::isnan(optval) ) { optval=tval; }
+     138             :   }
+     139        2602 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) mygrid->addToGridElement( i, 0, -optval );
+     140             : }
+     141             : 
+     142          15 : void ConvertToFES::runFinalJobs() {
+     143          15 :   activated=true; update();
+     144          15 : }
+     145             : 
+     146             : }
+     147             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..8b5dea2615 --- /dev/null +++ b/coverage/gridtools/DumpCube.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:323688.9 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpCubeC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe736createERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools8DumpCubeC1ERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools8DumpCube16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD9gridtools8DumpCube9printGridERNS_5OFileE8
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe73C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe73D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/DumpCube.cpp.func.html b/coverage/gridtools/DumpCube.cpp.func.html new file mode 100644 index 0000000000..fd3a0827b9 --- /dev/null +++ b/coverage/gridtools/DumpCube.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:323688.9 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe736createERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe73C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe73D2Ev3473
_ZN4PLMD9gridtools8DumpCube16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD9gridtools8DumpCubeC1ERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools8DumpCubeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools8DumpCube9printGridERNS_5OFileE8
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/DumpCube.cpp.gcov.html b/coverage/gridtools/DumpCube.cpp.gcov.html new file mode 100644 index 0000000000..6c717574cb --- /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:323688.9 %
Date:2024-06-10 08:19:14Functions: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 "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       10431 : PLUMED_REGISTER_ACTION(DumpCube,"DUMPCUBE")
+      74             : 
+      75           7 : void DumpCube::registerKeywords( Keywords& keys ) {
+      76           7 :   GridPrintingBase::registerKeywords( keys );
+      77          14 :   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           7 : }
+      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.15
+
+ + + 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 0000000000..0f20f97745 --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3434100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe1496createERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools8DumpGridC1ERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools8DumpGrid16registerKeywordsERNS_8KeywordsE50
_ZNK4PLMD9gridtools8DumpGrid9printGridERNS_5OFileE60
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe149C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe149D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.func.html b/coverage/gridtools/DumpGrid.cpp.func.html new file mode 100644 index 0000000000..16f62176fb --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3434100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe1496createERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe149C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe149D2Ev3473
_ZN4PLMD9gridtools8DumpGrid16registerKeywordsERNS_8KeywordsE50
_ZN4PLMD9gridtools8DumpGridC1ERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools8DumpGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools8DumpGrid9printGridERNS_5OFileE60
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.gcov.html b/coverage/gridtools/DumpGrid.cpp.gcov.html new file mode 100644 index 0000000000..c44e5f6ebb --- /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:3434100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10517 : PLUMED_REGISTER_ACTION(DumpGrid,"DUMPGRID")
+     150             : 
+     151          50 : void DumpGrid::registerKeywords( Keywords& keys ) {
+     152          50 :   GridPrintingBase::registerKeywords( keys );
+     153          50 : }
+     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.15
+
+ + + 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 0000000000..a48477e7a5 --- /dev/null +++ b/coverage/gridtools/FindContour.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:758984.3 %
Date:2024-06-10 08:19:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools11FindContour10isPeriodicEv0
_ZN4PLMD9gridtools11FindContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools11FindContour14checkAllActiveEv0
_ZN4PLMD9gridtools11FindContour15finishAveragingEv1
_ZN4PLMD9gridtools11FindContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe1136createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools11FindContour16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD9gridtools11FindContour19prepareForAveragingEv2
_ZNK4PLMD9gridtools11FindContour21getNumberOfQuantitiesEv7
_ZNK4PLMD9gridtools11FindContour7computeERKjRNS_10MultiValueE554
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe113C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe113D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/FindContour.cpp.func.html b/coverage/gridtools/FindContour.cpp.func.html new file mode 100644 index 0000000000..1bf84bc93c --- /dev/null +++ b/coverage/gridtools/FindContour.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:758984.3 %
Date:2024-06-10 08:19:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools11FindContour10isPeriodicEv0
_ZN4PLMD9gridtools11FindContour15finishAveragingEv1
_ZN4PLMD9gridtools11FindContour16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD9gridtools11FindContour19prepareForAveragingEv2
_ZN4PLMD9gridtools11FindContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools11FindContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe1136createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe113C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe113D2Ev3473
_ZNK4PLMD9gridtools11FindContour14checkAllActiveEv0
_ZNK4PLMD9gridtools11FindContour21getNumberOfQuantitiesEv7
_ZNK4PLMD9gridtools11FindContour7computeERKjRNS_10MultiValueE554
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/FindContour.cpp.gcov.html b/coverage/gridtools/FindContour.cpp.gcov.html new file mode 100644 index 0000000000..3bb1489164 --- /dev/null +++ b/coverage/gridtools/FindContour.cpp.gcov.html @@ -0,0 +1,324 @@ + + + + + + + + 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:758984.3 %
Date:2024-06-10 08:19:14Functions:91275.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 "vesselbase/StoreDataVessel.h"
+      24             : #include "ContourFindingBase.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Atoms.h"
+      27             : 
+      28             : //+PLUMEDOC GRIDANALYSIS FIND_CONTOUR
+      29             : /*
+      30             : Find an isocontour in a smooth function.
+      31             : 
+      32             : As discussed in the part of the manual on \ref Analysis PLUMED contains a number of tools that allow you to calculate
+      33             : a function on a grid.  The function on this grid might be a \ref HISTOGRAM as a function of a few collective variables
+      34             : or it might be a phase field that has been calculated using \ref MULTICOLVARDENS.  If this function has one or two input
+      35             : arguments it is relatively straightforward to plot the function.  If by contrast the data has a three or more dimensions
+      36             : it can be difficult to visualize.
+      37             : 
+      38             : This action provides one tool for visualizing these functions.  It can be used to search for a set of points on a contour
+      39             : where the function takes a particular values.  In other words, for the function \f$f(x,y)\f$ this action would find a set
+      40             : of points \f$\{x_c,y_c\}\f$ that have:
+      41             : 
+      42             : \f[
+      43             : f(x_c,y_c) - c = 0
+      44             : \f]
+      45             : 
+      46             : where \f$c\f$ is some constant value that is specified by the user.  The points on this contour are detected using a variant
+      47             : on the marching squares or marching cubes algorithm, which you can find information on here:
+      48             : 
+      49             : https://en.wikipedia.org/wiki/Marching_squares
+      50             : https://en.wikipedia.org/wiki/Marching_cubes
+      51             : 
+      52             : As such, and unlike \ref FIND_CONTOUR_SURFACE or \ref FIND_SPHERICAL_CONTOUR, the function input to this action can have any dimension.
+      53             : Furthermore, the topology of the contour will be determined by the algorithm and does not need to be specified by the user.
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : The input below allows you to calculate something akin to a Willard-Chandler dividing surface \cite wcsurface.
+      58             : The simulation cell in this case contains a solid phase and a liquid phase.  The Willard-Chandler surface is the
+      59             : surface that separates the parts of the box containing the solid from the parts containing the liquid.  To compute the position
+      60             : of this surface  the \ref FCCUBIC symmetry function is calculated for each of the atoms in the system from on the geometry of the
+      61             : atoms in the first coordination sphere of each of the atoms.  These quantities are then transformed using a switching function.
+      62             : 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
+      63             : parts of the box that resemble the solid structure and zero for atoms that are in parts of the box that resemble the liquid.
+      64             : The position of a virtual atom is then computed using \ref CENTER_OF_MULTICOLVAR and a phase field model is constructed using
+      65             : \ref MULTICOLVARDENS.  These procedure ensures that we have a continuous function that gives a measure of the average degree of
+      66             : solidness at each point in the simulation cell.  The Willard-Chandler dividing surface is calculated by finding a a set of points
+      67             : 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
+      68             : is found on every single step for each frame that is read in.
+      69             : 
+      70             : \plumedfile
+      71             : UNITS NATURAL
+      72             : FCCUBIC ...
+      73             :   SPECIES=1-96000 SWITCH={CUBIC D_0=1.2 D_MAX=1.5}
+      74             :   ALPHA=27 PHI=0.0 THETA=-1.5708 PSI=-2.35619 LABEL=fcc
+      75             : ... FCCUBIC
+      76             : 
+      77             : tfcc: MTRANSFORM_MORE DATA=fcc LOWMEM SWITCH={SMAP R_0=0.5 A=8 B=8}
+      78             : center: CENTER_OF_MULTICOLVAR DATA=tfcc
+      79             : 
+      80             : dens: MULTICOLVARDENS ...
+      81             :   DATA=tfcc ORIGIN=center DIR=xyz
+      82             :   NBINS=80,80,80 BANDWIDTH=1.0,1.0,1.0 STRIDE=1 CLEAR=1
+      83             : ...
+      84             : 
+      85             : FIND_CONTOUR GRID=dens CONTOUR=0.5 FILE=mycontour.xyz
+      86             : \endplumedfile
+      87             : 
+      88             : */
+      89             : //+ENDPLUMEDOC
+      90             : 
+      91             : namespace PLMD {
+      92             : namespace gridtools {
+      93             : 
+      94             : class FindContour : public ContourFindingBase {
+      95             : private:
+      96             :   bool firsttime;
+      97             :   unsigned gbuffer;
+      98             : /// Stuff for output
+      99             :   OFile of;
+     100             :   double lenunit;
+     101             :   std::string fmt_xyz;
+     102             : public:
+     103             :   static void registerKeywords( Keywords& keys );
+     104             :   explicit FindContour(const ActionOptions&ao);
+     105           0 :   bool checkAllActive() const override { return gbuffer==0; }
+     106             :   void prepareForAveraging() override;
+     107           0 :   bool isPeriodic() override { return false; }
+     108           7 :   unsigned getNumberOfQuantities() const override { return 1 + ingrid->getDimension(); }
+     109             :   void compute( const unsigned& current, MultiValue& myvals ) const override;
+     110             :   void finishAveraging() override;
+     111             : };
+     112             : 
+     113       10421 : PLUMED_REGISTER_ACTION(FindContour,"FIND_CONTOUR")
+     114             : 
+     115           2 : void FindContour::registerKeywords( Keywords& keys ) {
+     116           2 :   ContourFindingBase::registerKeywords( keys );
+     117             : // We want a better way of doing this bit
+     118           4 :   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");
+     119           4 :   keys.add("compulsory","FILE","file on which to output coordinates");
+     120           4 :   keys.add("compulsory","UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+     121           4 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+     122           2 : }
+     123             : 
+     124           1 : FindContour::FindContour(const ActionOptions&ao):
+     125             :   Action(ao),
+     126             :   ContourFindingBase(ao),
+     127           1 :   firsttime(true)
+     128             : {
+     129             : 
+     130           1 :   parse("BUFFER",gbuffer);
+     131           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);
+     132             : 
+     133           2 :   std::string file; parse("FILE",file);
+     134           1 :   if( file.length()==0 ) error("name out output file was not specified");
+     135           1 :   std::string type=Tools::extension(file);
+     136           1 :   log<<"  file name "<<file<<"\n";
+     137           1 :   if(type!="xyz") error("can only print xyz file type with contour finding");
+     138             : 
+     139             :   fmt_xyz="%f";
+     140           2 :   std::string precision; parse("PRECISION",precision);
+     141           1 :   if(precision.length()>0) {
+     142           1 :     int p; Tools::convert(precision,p);
+     143           1 :     log<<"  with precision "<<p<<"\n";
+     144             :     std::string a,b;
+     145           1 :     Tools::convert(p+5,a);
+     146           1 :     Tools::convert(p,b);
+     147           2 :     fmt_xyz="%"+a+"."+b+"f";
+     148             :   }
+     149           2 :   std::string unitname; parse("UNITS",unitname);
+     150           1 :   if(unitname!="PLUMED") {
+     151           0 :     Units myunit; myunit.setLength(unitname);
+     152           0 :     lenunit=plumed.getAtoms().getUnits().getLength()/myunit.getLength();
+     153           0 :   }
+     154           1 :   else lenunit=1.0;
+     155           1 :   of.link(*this); of.open(file);
+     156           1 :   checkRead(); mydata=buildDataStashes( NULL );
+     157           1 : }
+     158             : 
+     159           2 : void FindContour::prepareForAveraging() {
+     160             :   // Create a task list if first time
+     161           2 :   if( firsttime ) {
+     162       16465 :     for(unsigned i=0; i<ingrid->getDimension()*ingrid->getNumberOfPoints(); ++i) addTaskToList( i );
+     163             :   }
+     164           2 :   firsttime=false; deactivateAllTasks();
+     165             : 
+     166             :   // We now need to identify the grid points that we need to search through
+     167           2 :   std::vector<unsigned> nbin( ingrid->getNbin() );
+     168           2 :   std::vector<unsigned> ind( ingrid->getDimension() );
+     169           2 :   std::vector<unsigned> ones( ingrid->getDimension(), 1 );
+     170             :   unsigned num_neighbours; std::vector<unsigned> neighbours;
+     171       10978 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+     172             :     // Ensure inactive grid points are ignored
+     173       10976 :     if( ingrid->inactive(i) ) continue;
+     174             : 
+     175             :     // Get the index of the current grid point
+     176       10976 :     ingrid->getIndices( i, ind );
+     177       10976 :     ingrid->getNeighbors( ind, ones, num_neighbours, neighbours );
+     178             :     bool cycle=false;
+     179      307328 :     for(unsigned j=0; j<num_neighbours; ++j) {
+     180      296352 :       if( ingrid->inactive( neighbours[j]) ) { cycle=true; break; }
+     181             :     }
+     182       10976 :     if( cycle ) continue;
+     183             : 
+     184             :     // Get the value of a point on the grid
+     185       10976 :     double val1=getFunctionValue( i ) - contour;
+     186             :     bool edge=false;
+     187       43904 :     for(unsigned j=0; j<ingrid->getDimension(); ++j) {
+     188             :       // Make sure we don't search at the edge of the grid
+     189       32928 :       if( !ingrid->isPeriodic(j) && (ind[j]+1)==nbin[j] ) continue;
+     190       32928 :       else if( (ind[j]+1)==nbin[j] ) { edge=true; ind[j]=0; }
+     191       30968 :       else ind[j]+=1;
+     192       32928 :       double val2=getFunctionValue( ind ) - contour;
+     193       32928 :       if( val1*val2<0 ) taskFlags[ ingrid->getDimension()*i + j ] = 1;
+     194       32928 :       if( ingrid->isPeriodic(j) && edge ) { edge=false; ind[j]=nbin[j]-1; }
+     195       30968 :       else ind[j]-=1;
+     196             :     }
+     197             :   }
+     198           2 :   lockContributors();
+     199           2 : }
+     200             : 
+     201         554 : void FindContour::compute( const unsigned& current, MultiValue& myvals ) const {
+     202             :   // Retrieve the initial grid point coordinates
+     203         554 :   unsigned gpoint = std::floor( current / ingrid->getDimension() );
+     204         554 :   std::vector<double> point( ingrid->getDimension() );
+     205         554 :   ingrid->getGridPointCoordinates( gpoint, point );
+     206             : 
+     207             :   // Retrieve the direction we are searching for the contour
+     208         554 :   unsigned gdir = current%(ingrid->getDimension() );
+     209         554 :   std::vector<double> direction( ingrid->getDimension(), 0 );
+     210         554 :   direction[gdir] = 0.999999999*ingrid->getGridSpacing()[gdir];
+     211             : 
+     212             :   // Now find the contour
+     213             :   findContour( direction, point );
+     214             :   // And transfer to the store data vessel
+     215        2216 :   for(unsigned i=0; i<ingrid->getDimension(); ++i) myvals.setValue( 1+i, point[i] );
+     216         554 : }
+     217             : 
+     218           1 : void FindContour::finishAveraging() {
+     219             :   // And update the list of active grid points
+     220           1 :   if( gbuffer>0 ) {
+     221             :     std::vector<unsigned> neighbours; unsigned num_neighbours;
+     222           0 :     std::vector<unsigned> ugrid_indices( ingrid->getDimension() );
+     223           0 :     std::vector<bool> active( ingrid->getNumberOfPoints(), false );
+     224           0 :     std::vector<unsigned> gbuffer_vec( ingrid->getDimension(), gbuffer );
+     225           0 :     for(unsigned i=0; i<getCurrentNumberOfActiveTasks(); ++i) {
+     226             :       // Get the point we are operating on
+     227           0 :       unsigned ipoint = std::floor( getActiveTask(i) / ingrid->getDimension() );
+     228             :       // Get the indices of this point
+     229           0 :       ingrid->getIndices( ipoint, ugrid_indices );
+     230             :       // Now activate buffer region
+     231           0 :       ingrid->getNeighbors( ugrid_indices, gbuffer_vec, num_neighbours, neighbours );
+     232           0 :       for(unsigned n=0; n<num_neighbours; ++n) active[ neighbours[n] ]=true;
+     233             :     }
+     234           0 :     ingrid->activateThesePoints( active );
+     235             :   }
+     236           1 :   std::vector<double> point( 1 + ingrid->getDimension() );
+     237           1 :   of.printf("%u\n",mydata->getNumberOfStoredValues());
+     238           1 :   of.printf("Points found on isocontour\n");
+     239         555 :   for(unsigned i=0; i<mydata->getNumberOfStoredValues(); ++i) {
+     240         554 :     mydata->retrieveSequentialValue( i, false, point ); of.printf("X");
+     241        2216 :     for(unsigned j=0; j<ingrid->getDimension(); ++j) of.printf( (" " + fmt_xyz).c_str(), lenunit*point[1+j] );
+     242         554 :     of.printf("\n");
+     243             :   }
+     244           1 : }
+     245             : 
+     246             : }
+     247             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..737ccf4bc4 --- /dev/null +++ b/coverage/gridtools/FindContourSurface.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:909495.7 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18FindContourSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools18FindContourSurface14checkAllActiveEv0
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe1066createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools18FindContourSurfaceC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools18FindContourSurface16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD9gridtools18FindContourSurface12clearAverageEv3
_ZN4PLMD9gridtools18FindContourSurface15finishAveragingEv3
_ZN4PLMD9gridtools18FindContourSurface19prepareForAveragingEv3
_ZNK4PLMD9gridtools18FindContourSurface21getNumberOfQuantitiesEv12
_ZNK4PLMD9gridtools18FindContourSurface7computeERKjRNS_10MultiValueE588
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe106C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe106D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/FindContourSurface.cpp.func.html b/coverage/gridtools/FindContourSurface.cpp.func.html new file mode 100644 index 0000000000..21d31fe3f5 --- /dev/null +++ b/coverage/gridtools/FindContourSurface.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:909495.7 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe1066createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe106C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe106D2Ev3473
_ZN4PLMD9gridtools18FindContourSurface12clearAverageEv3
_ZN4PLMD9gridtools18FindContourSurface15finishAveragingEv3
_ZN4PLMD9gridtools18FindContourSurface16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD9gridtools18FindContourSurface19prepareForAveragingEv3
_ZN4PLMD9gridtools18FindContourSurfaceC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools18FindContourSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools18FindContourSurface14checkAllActiveEv0
_ZNK4PLMD9gridtools18FindContourSurface21getNumberOfQuantitiesEv12
_ZNK4PLMD9gridtools18FindContourSurface7computeERKjRNS_10MultiValueE588
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/FindContourSurface.cpp.gcov.html b/coverage/gridtools/FindContourSurface.cpp.gcov.html new file mode 100644 index 0000000000..c02f206fcd --- /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:909495.7 %
Date:2024-06-10 08:19:14Functions:101283.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/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       10421 : PLUMED_REGISTER_ACTION(FindContourSurface,"FIND_CONTOUR_SURFACE")
+     107             : 
+     108           2 : void FindContourSurface::registerKeywords( Keywords& keys ) {
+     109           2 :   ContourFindingBase::registerKeywords( keys );
+     110           4 :   keys.add("compulsory","SEARCHDIR","In which directions do you wish to search for the contour.");
+     111           4 :   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           2 : }
+     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          12 :     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.15
+
+ + + 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 0000000000..295ae82a2a --- /dev/null +++ b/coverage/gridtools/FindSphericalContour.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:394195.1 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools20FindSphericalContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe1226createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools20FindSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools20FindSphericalContour16registerKeywordsERNS_8KeywordsE2
_ZNK4PLMD9gridtools20FindSphericalContour21getNumberOfQuantitiesEv4
_ZNK4PLMD9gridtools20FindSphericalContour7computeERKjRNS_10MultiValueE100
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe122C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe122D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/FindSphericalContour.cpp.func.html b/coverage/gridtools/FindSphericalContour.cpp.func.html new file mode 100644 index 0000000000..8eb523da62 --- /dev/null +++ b/coverage/gridtools/FindSphericalContour.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:394195.1 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe1226createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe122C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe122D2Ev3473
_ZN4PLMD9gridtools20FindSphericalContour16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD9gridtools20FindSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools20FindSphericalContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools20FindSphericalContour21getNumberOfQuantitiesEv4
_ZNK4PLMD9gridtools20FindSphericalContour7computeERKjRNS_10MultiValueE100
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/FindSphericalContour.cpp.gcov.html b/coverage/gridtools/FindSphericalContour.cpp.gcov.html new file mode 100644 index 0000000000..d13990aa0f --- /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:394195.1 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(FindSphericalContour,"FIND_SPHERICAL_CONTOUR")
+     123             : 
+     124           2 : void FindSphericalContour::registerKeywords( Keywords& keys ) {
+     125           2 :   ContourFindingBase::registerKeywords( keys );
+     126           4 :   keys.add("compulsory","NPOINTS","the number of points for which we are looking for the contour");
+     127           4 :   keys.add("compulsory","INNER_RADIUS","the minimum radius on which to look for the contour");
+     128           4 :   keys.add("compulsory","OUTER_RADIUS","the outer radius on which to look for the contour");
+     129           4 :   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           2 : }
+     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.15
+
+ + + 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 0000000000..931051924e --- /dev/null +++ b/coverage/gridtools/FourierTransform.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:728683.7 %
Date:2024-06-10 08:19:14Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16FourierTransform10isPeriodicEv0
_ZN4PLMD9gridtools16FourierTransformC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools16FourierTransform7computeERKjRNS_10MultiValueE0
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe876createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools16FourierTransform12clearAverageEv1
_ZN4PLMD9gridtools16FourierTransformC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools16FourierTransform16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD9gridtools16FourierTransform17performOperationsERKb4
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe87C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe87D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/FourierTransform.cpp.func.html b/coverage/gridtools/FourierTransform.cpp.func.html new file mode 100644 index 0000000000..fe6ddd9af9 --- /dev/null +++ b/coverage/gridtools/FourierTransform.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:728683.7 %
Date:2024-06-10 08:19:14Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe876createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe87C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe87D2Ev3473
_ZN4PLMD9gridtools16FourierTransform10isPeriodicEv0
_ZN4PLMD9gridtools16FourierTransform12clearAverageEv1
_ZN4PLMD9gridtools16FourierTransform16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD9gridtools16FourierTransform17performOperationsERKb4
_ZN4PLMD9gridtools16FourierTransformC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools16FourierTransformC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools16FourierTransform7computeERKjRNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/FourierTransform.cpp.gcov.html b/coverage/gridtools/FourierTransform.cpp.gcov.html new file mode 100644 index 0000000000..c3e0c82a32 --- /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:728683.7 %
Date:2024-06-10 08:19:14Functions:71070.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 <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       10421 : PLUMED_REGISTER_ACTION(FourierTransform,"FOURIER_TRANSFORM")
+      88             : 
+      89           2 : void FourierTransform::registerKeywords( Keywords& keys ) {
+      90           4 :   ActionWithInputGrid::registerKeywords( keys ); keys.remove("BANDWIDTH"); keys.remove("KERNEL");
+      91           4 :   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           2 : }
+      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           4 :     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.15
+
+ + + 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 0000000000..faae8bd64c --- /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-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools16GridPrintingBase12runFinalJobsEv57
_ZN4PLMD9gridtools16GridPrintingBaseC2ERKNS_13ActionOptionsE57
_ZN4PLMD9gridtools16GridPrintingBase16registerKeywordsERNS_8KeywordsE60
_ZN4PLMD9gridtools16GridPrintingBase6updateEv68
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.cpp.func.html b/coverage/gridtools/GridPrintingBase.cpp.func.html new file mode 100644 index 0000000000..e0c17d00cb --- /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-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBase12runFinalJobsEv57
_ZN4PLMD9gridtools16GridPrintingBase16registerKeywordsERNS_8KeywordsE60
_ZN4PLMD9gridtools16GridPrintingBase6updateEv68
_ZN4PLMD9gridtools16GridPrintingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools16GridPrintingBaseC2ERKNS_13ActionOptionsE57
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.cpp.gcov.html b/coverage/gridtools/GridPrintingBase.cpp.gcov.html new file mode 100644 index 0000000000..16562c72a0 --- /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-06-10 08:19:14Functions: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          60 : void GridPrintingBase::registerKeywords( Keywords& keys ) {
+      31          60 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      32         120 :   keys.add("compulsory","GRID","the action that creates the grid you would like to output");
+      33         120 :   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         120 :   keys.add("compulsory","FILE","density","the file on which to write the grid.");
+      36         120 :   keys.add("compulsory","REPLICA","0","the replica for which you would like to output this information");
+      37         120 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+      38          60 : }
+      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.15
+
+ + + 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 0000000000..dd357e6464 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBase5applyEv68
_ZN4PLMD9gridtools16GridPrintingBase9calculateEv68
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.h.func.html b/coverage/gridtools/GridPrintingBase.h.func.html new file mode 100644 index 0000000000..5cc3b5c05c --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBase5applyEv68
_ZN4PLMD9gridtools16GridPrintingBase9calculateEv68
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.h.gcov.html b/coverage/gridtools/GridPrintingBase.h.gcov.html new file mode 100644 index 0000000000..92b33adafd --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..3cf635a07a --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.func.html b/coverage/gridtools/GridSearch.h.func.html new file mode 100644 index 0000000000..386f9260bd --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.gcov.html b/coverage/gridtools/GridSearch.h.gcov.html new file mode 100644 index 0000000000..7dc90f3409 --- /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-06-10 08:19:14Functions: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           2 :     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.15
+
+ + + 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 0000000000..ef44a093ca --- /dev/null +++ b/coverage/gridtools/GridToXYZ.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:404588.9 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools9GridToXYZC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe506createERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools9GridToXYZC1ERKNS_13ActionOptionsE2
_ZNK4PLMD9gridtools9GridToXYZ9printGridERNS_5OFileE2
_ZN4PLMD9gridtools9GridToXYZ16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe50C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe50D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/GridToXYZ.cpp.func.html b/coverage/gridtools/GridToXYZ.cpp.func.html new file mode 100644 index 0000000000..40e77d6b7b --- /dev/null +++ b/coverage/gridtools/GridToXYZ.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:404588.9 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe506createERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe50C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe50D2Ev3473
_ZN4PLMD9gridtools9GridToXYZ16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools9GridToXYZC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools9GridToXYZC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools9GridToXYZ9printGridERNS_5OFileE2
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/GridToXYZ.cpp.gcov.html b/coverage/gridtools/GridToXYZ.cpp.gcov.html new file mode 100644 index 0000000000..880e8b8ae1 --- /dev/null +++ b/coverage/gridtools/GridToXYZ.cpp.gcov.html @@ -0,0 +1,187 @@ + + + + + + + + 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:404588.9 %
Date:2024-06-10 08:19:14Functions: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 "GridPrintingBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/OFile.h"
+      26             : #include "core/Atoms.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace gridtools {
+      30             : 
+      31             : //+PLUMEDOC GRIDANALYSIS GRID_TO_XYZ
+      32             : /*
+      33             : Output the function on the grid to an xyz file
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : */
+      38             : //+ENDPLUMEDOC
+      39             : 
+      40             : class GridToXYZ : public GridPrintingBase {
+      41             : private:
+      42             :   double lenunit;
+      43             :   unsigned mycomp;
+      44             : public:
+      45             :   static void registerKeywords( Keywords& keys );
+      46             :   explicit GridToXYZ(const ActionOptions&ao);
+      47             :   void printGrid( OFile& ofile ) const override;
+      48             : };
+      49             : 
+      50       10423 : PLUMED_REGISTER_ACTION(GridToXYZ,"GRID_TO_XYZ")
+      51             : 
+      52           3 : void GridToXYZ::registerKeywords( Keywords& keys ) {
+      53           3 :   GridPrintingBase::registerKeywords( keys );
+      54           6 :   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");
+      55           6 :   keys.add("compulsory","UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+      56           6 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+      57           3 :   keys.remove("FMT");
+      58           3 : }
+      59             : 
+      60           2 : GridToXYZ::GridToXYZ(const ActionOptions&ao):
+      61             :   Action(ao),
+      62           2 :   GridPrintingBase(ao)
+      63             : {
+      64           2 :   if( ingrid->getDimension()!=3 ) error("cannot print grid xyz file if grid does not contain three dimensional data");
+      65           2 :   fmt = " " + fmt;
+      66             : 
+      67           2 :   if( ingrid->getNumberOfComponents()==1 ) {
+      68           2 :     mycomp=0;
+      69             :   } else {
+      70           0 :     int tcomp=-1; parse("COMPONENT",tcomp);
+      71           0 :     if( tcomp<0 ) error("component of vector field was not specified - use COMPONENT keyword");
+      72           0 :     mycomp=tcomp*(1+ingrid->getDimension()); if( ingrid->noDerivatives() ) mycomp=tcomp;
+      73           0 :     log.printf("  using %dth component of grid \n",tcomp );
+      74             :   }
+      75             :   fmt="%f";
+      76           4 :   std::string precision; parse("PRECISION",precision);
+      77           2 :   if(precision.length()>0) {
+      78           2 :     int p; Tools::convert(precision,p);
+      79           2 :     log<<"  with precision "<<p<<"\n";
+      80             :     std::string a,b;
+      81           2 :     Tools::convert(p+5,a);
+      82           2 :     Tools::convert(p,b);
+      83           4 :     fmt="%"+a+"."+b+"f";
+      84             :   }
+      85           4 :   std::string unitname; parse("UNITS",unitname);
+      86           2 :   if(unitname!="PLUMED") {
+      87           2 :     Units myunit; myunit.setLength(unitname);
+      88           2 :     lenunit=plumed.getAtoms().getUnits().getLength()/myunit.getLength();
+      89           2 :   }
+      90           0 :   else lenunit=1.0;
+      91           2 :   checkRead();
+      92           2 : }
+      93             : 
+      94           2 : void GridToXYZ::printGrid( OFile& ofile ) const {
+      95           2 :   std::vector<double> point( 3 );
+      96           2 :   ofile.printf("%u\n",ingrid->getNumberOfPoints());
+      97           2 :   ofile.printf("Grid converted to xyz file \n");
+      98         246 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+      99         244 :     ingrid->getGridPointCoordinates( i, point );
+     100         244 :     ofile.printf("X");
+     101             :     double val;
+     102         488 :     if( ingrid->getType()=="flat" ) val=1.0;
+     103         244 :     else val=ingrid->getGridElement( i, 0 );
+     104         976 :     for(unsigned j=0; j<3; ++j) { ofile.printf( (" " + fmt).c_str(), val*lenunit*point[j] ); }
+     105         244 :     ofile.printf("\n");
+     106             :   }
+     107           2 : }
+     108             : 
+     109             : }
+     110             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..483e034f93 --- /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-06-10 08:19:14Functions: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
_ZNK4PLMD9gridtools10GridVessel18getSplineNeighborsERKjRjRSt6vectorIjSaIjEE528845
_ZNK4PLMD9gridtools10GridVessel22getValueAndDerivativesERKSt6vectorIdSaIdEERKjRS4_528845
_ZNK4PLMD9gridtools10GridVessel8getIndexERKSt6vectorIdSaIdEE530956
_ZNK4PLMD9gridtools10GridVessel23getGridPointCoordinatesERKjRSt6vectorIdSaIdEE665380
_ZNK4PLMD9gridtools10GridVessel10getIndicesERKSt6vectorIdSaIdEERS2_IjSaIjEE1060389
_ZNK4PLMD9gridtools10GridVessel14getGridElementERKjS3_6552681
_ZNK4PLMD9gridtools10GridVessel9wasForcedEv11870273
_ZNK4PLMD9gridtools10GridVessel23getGridPointCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE12514073
_ZNK4PLMD9gridtools10GridVessel22getFlatGridCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE13037801
_ZNK4PLMD9gridtools10GridVessel10getIndicesERKjRSt6vectorIjSaIjEE15879019
_ZNK4PLMD9gridtools10GridVessel8getIndexERKSt6vectorIjSaIjEE24333376
_ZNK4PLMD9gridtools10GridVessel21convertIndexToIndicesERKjRKSt6vectorIjSaIjEERS6_112427817
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/GridVessel.cpp.func.html b/coverage/gridtools/GridVessel.cpp.func.html new file mode 100644 index 0000000000..14068e0f20 --- /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-06-10 08:19:14Functions: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_IjSaIjEE1060389
_ZNK4PLMD9gridtools10GridVessel10getIndicesERKjRSt6vectorIjSaIjEE15879019
_ZNK4PLMD9gridtools10GridVessel12getCubeUnitsEv8
_ZNK4PLMD9gridtools10GridVessel12getNeighborsERKSt6vectorIdSaIdEERKS2_IjSaIjEERjRS8_21514
_ZNK4PLMD9gridtools10GridVessel12getNeighborsERKSt6vectorIjSaIjEES6_RjRS4_40878
_ZNK4PLMD9gridtools10GridVessel14getGridElementERKSt6vectorIjSaIjEERKj0
_ZNK4PLMD9gridtools10GridVessel14getGridElementERKjS3_6552681
_ZNK4PLMD9gridtools10GridVessel14getInputStringB5cxx11Ev17
_ZNK4PLMD9gridtools10GridVessel17getFibonacciIndexERKSt6vectorIdSaIdEE57
_ZNK4PLMD9gridtools10GridVessel18getSplineNeighborsERKjRjRSt6vectorIjSaIjEE528845
_ZNK4PLMD9gridtools10GridVessel21convertIndexToIndicesERKjRKSt6vectorIjSaIjEERS6_112427817
_ZNK4PLMD9gridtools10GridVessel22getFlatGridCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE13037801
_ZNK4PLMD9gridtools10GridVessel22getValueAndDerivativesERKSt6vectorIdSaIdEERKjRS4_528845
_ZNK4PLMD9gridtools10GridVessel23getFibonacciCoordinatesERKjRSt6vectorIdSaIdEE86817
_ZNK4PLMD9gridtools10GridVessel23getGridPointCoordinatesERKjRSt6vectorIdSaIdEE665380
_ZNK4PLMD9gridtools10GridVessel23getGridPointCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE12514073
_ZNK4PLMD9gridtools10GridVessel6getMaxB5cxx11Ev202553
_ZNK4PLMD9gridtools10GridVessel6getMinB5cxx11Ev202520
_ZNK4PLMD9gridtools10GridVessel7getNbinEv203150
_ZNK4PLMD9gridtools10GridVessel8getIndexERKSt6vectorIdSaIdEE530956
_ZNK4PLMD9gridtools10GridVessel8getIndexERKSt6vectorIjSaIjEE24333376
_ZNK4PLMD9gridtools10GridVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE15087
_ZNK4PLMD9gridtools10GridVessel9wasForcedEv11870273
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/GridVessel.cpp.gcov.html b/coverage/gridtools/GridVessel.cpp.gcov.html new file mode 100644 index 0000000000..71222fcfdd --- /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-06-10 08:19:14Functions: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    24333376 : 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    24333376 :   unsigned index=indices[dimension-1];
+     198    69887414 :   for(unsigned i=dimension-1; i>0; --i) {
+     199    45554038 :     index=index*nbin[i-1]+indices[i-1];
+     200             :   }
+     201    24333376 :   return index;
+     202             : }
+     203             : 
+     204     1060389 : 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     3196134 :   for(unsigned i=0; i<dimension; ++i) {
+     207     2135745 :     indices[i]=std::floor( (point[i] - min[i])/dx[i] );
+     208     2135745 :     if( pbc[i] ) indices[i]=indices[i]%nbin[i];
+     209     2090225 :     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     1060389 : }
+     216             : 
+     217      530956 : unsigned GridVessel::getIndex( const std::vector<double>& point ) const {
+     218             :   plumed_dbg_assert( gtype==flat && bounds_set && point.size()==dimension );
+     219      530956 :   if( gtype==flat ) {
+     220      530956 :     std::vector<unsigned> indices(dimension); getIndices( point, indices );
+     221      530956 :     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   112427817 : void GridVessel::convertIndexToIndices( const unsigned& index, const std::vector<unsigned>& nnbin, std::vector<unsigned>& indices ) const {
+     259   112427817 :   plumed_dbg_assert( gtype==flat ); unsigned kk=index; indices[0]=index%nnbin[0];
+     260   220890761 :   for(unsigned i=1; i<dimension-1; ++i) {
+     261   108462944 :     kk=(kk-indices[i-1])/nnbin[i-1];
+     262   108462944 :     indices[i]=kk%nnbin[i];
+     263             :   }
+     264   112427817 :   if(dimension>=2) { // I think this is wrong
+     265   112411310 :     indices[dimension-1]=(kk-indices[dimension-2])/nnbin[dimension-2];
+     266             :   }
+     267   112427817 : }
+     268             : 
+     269    15879019 : void GridVessel::getIndices( const unsigned& index, std::vector<unsigned>& indices ) const {
+     270    15879019 :   plumed_dbg_assert( gtype==flat ); convertIndexToIndices( index, nbin, indices );
+     271    15879019 : }
+     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    13037801 : void GridVessel::getFlatGridCoordinates( const unsigned& ipoint, std::vector<unsigned>& tindices, std::vector<double>& x ) const {
+     289    13037801 :   plumed_dbg_assert( gtype==flat ); getIndices( ipoint, tindices );
+     290    50950445 :   for(unsigned i=0; i<dimension; ++i) x[i] = min[i] + dx[i]*tindices[i];
+     291    13037801 : }
+     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      528845 : void GridVessel::getSplineNeighbors( const unsigned& mybox, unsigned& nneighbors, std::vector<unsigned>& mysneigh ) const {
+     302      528845 :   plumed_dbg_assert( gtype==flat ); unsigned nneigh=unsigned(pow(2.0,int(dimension)));
+     303      528845 :   if( mysneigh.size()!=nneigh ) mysneigh.resize(nneigh);
+     304             : 
+     305      528845 :   unsigned inind; nneighbors = 0;
+     306      528845 :   std::vector<unsigned> tmp_indices( dimension );
+     307      528845 :   std::vector<unsigned> my_indices( dimension );
+     308      528845 :   getIndices( mybox, my_indices );
+     309     2677605 :   for(unsigned i=0; i<nneigh; ++i) {
+     310             :     unsigned tmp=i; inind=0;
+     311     6513440 :     for(unsigned j=0; j<dimension; ++j) {
+     312     4364680 :       unsigned i0=tmp%2+my_indices[j]; tmp/=2;
+     313     4364680 :       if(!pbc[j] && i0==nbin[j]) continue;
+     314     4323880 :       if( pbc[j] && i0==nbin[j]) i0=0;
+     315     4323880 :       tmp_indices[inind++]=i0;
+     316             :     }
+     317     2148760 :     if(inind==dimension ) {
+     318     2108160 :       unsigned findex=getIndex( tmp_indices );
+     319     2108160 :       mysneigh[nneighbors++]=findex;
+     320     2108160 :       plumed_massert( active[findex], "inactive grid point required for splines");
+     321             :     }
+     322             :   }
+     323      528845 : }
+     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      528845 : 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      528845 :   double X,X2,X3,value=0; der.assign(der.size(),0.0);
+     460      528845 :   std::vector<double> fd(dimension);
+     461      528845 :   std::vector<double> C(dimension);
+     462      528845 :   std::vector<double> D(dimension);
+     463      528845 :   std::vector<double> dder(dimension);
+     464             : 
+     465      528845 :   std::vector<unsigned> nindices(dimension); unsigned n_neigh;
+     466      528845 :   std::vector<unsigned> indices(dimension); getIndices( x, indices );
+     467      528845 :   std::vector<unsigned> neigh; getSplineNeighbors( getIndex(indices), n_neigh, neigh );
+     468      528845 :   std::vector<double> xfloor(dimension); getFlatGridCoordinates( getIndex(x), nindices, xfloor );
+     469             : 
+     470             : // loop over neighbors
+     471     2637005 :   for(unsigned int ipoint=0; ipoint<n_neigh; ++ipoint) {
+     472     2108160 :     double grid=getGridElement(neigh[ipoint], ind*(1+dimension) );
+     473     6391640 :     for(unsigned j=0; j<dimension; ++j) dder[j] = getGridElement( neigh[ipoint], ind*(1+dimension) + 1 + j );
+     474             : 
+     475     2108160 :     getIndices( neigh[ipoint], nindices );
+     476             :     double ff=1.0;
+     477             : 
+     478     6391640 :     for(unsigned j=0; j<dimension; ++j) {
+     479             :       int x0=1;
+     480     4283480 :       if(nindices[j]==indices[j]) x0=0;
+     481     4283480 :       double ddx=dx[j];
+     482     4283480 :       X=std::fabs((x[j]-xfloor[j])/ddx-(double)x0);
+     483     4283480 :       X2=X*X;
+     484     4283480 :       X3=X2*X;
+     485             :       double yy;
+     486     4283480 :       if(std::fabs(grid)<0.0000001) yy=0.0;
+     487     4269633 :       else yy=-dder[j]/grid;
+     488     6445420 :       C[j]=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*ddx;
+     489     4283480 :       D[j]=( -6.0*X +6.0*X2) - (x0?-1.0:1.0)*yy*(1.0-4.0*X +3.0*X2)*ddx;
+     490     4283480 :       D[j]*=(x0?-1.0:1.0)/ddx;
+     491     4283480 :       ff*=C[j];
+     492             :     }
+     493     6391640 :     for(unsigned j=0; j<dimension; ++j) {
+     494     4283480 :       fd[j]=D[j];
+     495    13052720 :       for(unsigned i=0; i<dimension; ++i) if(i!=j) fd[j]*=C[i];
+     496             :     }
+     497     2108160 :     value+=grid*ff;
+     498     6391640 :     for(unsigned j=0; j<dimension; ++j) der[j]+=grid*fd[j];
+     499             :   }
+     500      528845 :   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.15
+
+ + + 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 0000000000..9c755de136 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/gridtools/GridVessel.h.func.html b/coverage/gridtools/GridVessel.h.func.html new file mode 100644 index 0000000000..13598fa02a --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/gridtools/GridVessel.h.gcov.html b/coverage/gridtools/GridVessel.h.gcov.html new file mode 100644 index 0000000000..b14bd9ee57 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..5f00bca5ae --- /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:11912198.3 %
Date:2024-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.cpp.func.html b/coverage/gridtools/HistogramOnGrid.cpp.func.html new file mode 100644 index 0000000000..6de8b077b6 --- /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:11912198.3 %
Date:2024-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.cpp.gcov.html b/coverage/gridtools/HistogramOnGrid.cpp.gcov.html new file mode 100644 index 0000000000..b0376d0e59 --- /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:11912198.3 %
Date:2024-06-10 08:19:14Functions: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          40 :   }
+      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    23687840 :           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.15
+
+ + + 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 0000000000..b6ec261008 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools15HistogramOnGrid23getNumberOfBufferPointsEv269
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.h.func.html b/coverage/gridtools/HistogramOnGrid.h.func.html new file mode 100644 index 0000000000..68d0b8d6c2 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools15HistogramOnGrid23getNumberOfBufferPointsEv269
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.h.gcov.html b/coverage/gridtools/HistogramOnGrid.h.gcov.html new file mode 100644 index 0000000000..4fb125e3b4 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..af2d1b0ce7 --- /dev/null +++ b/coverage/gridtools/IntegrateGrid.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13IntegrateGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe446createERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools13IntegrateGridC1ERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools13IntegrateGrid16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe44C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe44D2Ev3473
_ZNK4PLMD9gridtools13IntegrateGrid7computeERKjRNS_10MultiValueE5705
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/IntegrateGrid.cpp.func.html b/coverage/gridtools/IntegrateGrid.cpp.func.html new file mode 100644 index 0000000000..c142e603a2 --- /dev/null +++ b/coverage/gridtools/IntegrateGrid.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe446createERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe44C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe44D2Ev3473
_ZN4PLMD9gridtools13IntegrateGrid16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD9gridtools13IntegrateGridC1ERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools13IntegrateGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools13IntegrateGrid7computeERKjRNS_10MultiValueE5705
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/IntegrateGrid.cpp.gcov.html b/coverage/gridtools/IntegrateGrid.cpp.gcov.html new file mode 100644 index 0000000000..dbcc24021b --- /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:1111100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10427 : PLUMED_REGISTER_ACTION(IntegrateGrid,"INTEGRATE_GRID")
+      45             : 
+      46           5 : void IntegrateGrid::registerKeywords( Keywords& keys ) {
+      47           5 :   ActionWithIntegral::registerKeywords( keys );
+      48           5 : }
+      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.15
+
+ + + 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 0000000000..436e0d03cf --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:293193.5 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15InterpolateGrid10isPeriodicEv0
_ZN4PLMD9gridtools15InterpolateGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe626createERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools15InterpolateGridC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools15InterpolateGrid16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD9gridtools15InterpolateGrid21getNumberOfQuantitiesEv8
_ZNK4PLMD9gridtools15InterpolateGrid7computeERKjRNS_10MultiValueE200
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe62C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe62D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.func.html b/coverage/gridtools/InterpolateGrid.cpp.func.html new file mode 100644 index 0000000000..1eb2fc79c3 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:293193.5 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe626createERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe62C2Ev3473
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe62D2Ev3473
_ZN4PLMD9gridtools15InterpolateGrid10isPeriodicEv0
_ZN4PLMD9gridtools15InterpolateGrid16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools15InterpolateGridC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools15InterpolateGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15InterpolateGrid21getNumberOfQuantitiesEv8
_ZNK4PLMD9gridtools15InterpolateGrid7computeERKjRNS_10MultiValueE200
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.gcov.html b/coverage/gridtools/InterpolateGrid.cpp.gcov.html new file mode 100644 index 0000000000..00ab1552ba --- /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:293193.5 %
Date:2024-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_ACTION(InterpolateGrid,"INTERPOLATE_GRID")
+      63             : 
+      64           3 : void InterpolateGrid::registerKeywords( Keywords& keys ) {
+      65           3 :   ActionWithInputGrid::registerKeywords( keys );
+      66           6 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+      67           6 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+      68           6 :   keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      69           3 : }
+      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           8 :   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.15
+
+ + + diff --git a/coverage/gridtools/index-sort-f.html b/coverage/gridtools/index-sort-f.html new file mode 100644 index 0000000000..2c6c7c45ab --- /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:1184126593.6 %
Date:2024-06-10 08:19:14Functions:17120085.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
ContourFindingBase.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
FourierTransform.cpp +
83.7%83.7%
+
83.7 %72 / 8670.0 %7 / 10
FindContour.cpp +
84.3%84.3%
+
84.3 %75 / 8975.0 %9 / 12
InterpolateGrid.cpp +
93.5%93.5%
+
93.5 %29 / 3177.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
ActionWithInputGrid.cpp +
91.2%91.2%
+
91.2 %31 / 3483.3 %5 / 6
FindContourSurface.cpp +
95.7%95.7%
+
95.7 %90 / 9483.3 %10 / 12
DumpGrid.cpp +
100.0%
+
100.0 %34 / 3485.7 %6 / 7
ActionWithGrid.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
GridToXYZ.cpp +
88.9%88.9%
+
88.9 %40 / 4585.7 %6 / 7
IntegrateGrid.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
DumpCube.cpp +
88.9%88.9%
+
88.9 %32 / 3685.7 %6 / 7
ConvertToFES.cpp +
95.8%95.8%
+
95.8 %46 / 4886.7 %13 / 15
GridVessel.h +
89.3%89.3%
+
89.3 %25 / 2887.5 %7 / 8
FindSphericalContour.cpp +
95.1%95.1%
+
95.1 %39 / 4187.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
GridSearch.h +
95.0%95.0%
+
95.0 %38 / 40100.0 %2 / 2
GridPrintingBase.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
AverageOnGrid.cpp +
96.2%96.2%
+
96.2 %25 / 26100.0 %4 / 4
ActionWithInputGrid.h +
100.0%
+
100.0 %8 / 8100.0 %4 / 4
HistogramOnGrid.cpp +
98.3%98.3%
+
98.3 %119 / 121100.0 %12 / 12
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/index-sort-l.html b/coverage/gridtools/index-sort-l.html new file mode 100644 index 0000000000..82b4cf3392 --- /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:1184126593.6 %
Date:2024-06-10 08:19:14Functions:17120085.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.7%83.7%
+
83.7 %72 / 8670.0 %7 / 10
FindContour.cpp +
84.3%84.3%
+
84.3 %75 / 8975.0 %9 / 12
DumpCube.cpp +
88.9%88.9%
+
88.9 %32 / 3685.7 %6 / 7
GridToXYZ.cpp +
88.9%88.9%
+
88.9 %40 / 4585.7 %6 / 7
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.5%93.5%
+
93.5 %29 / 3177.8 %7 / 9
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.1%95.1%
+
95.1 %39 / 4187.5 %7 / 8
FindContourSurface.cpp +
95.7%95.7%
+
95.7 %90 / 9483.3 %10 / 12
ConvertToFES.cpp +
95.8%95.8%
+
95.8 %46 / 4886.7 %13 / 15
AverageOnGrid.cpp +
96.2%96.2%
+
96.2 %25 / 26100.0 %4 / 4
ActionWithGrid.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
HistogramOnGrid.cpp +
98.3%98.3%
+
98.3 %119 / 121100.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
ContourFindingBase.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
IntegrateGrid.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
ActionWithIntegral.cpp +
100.0%
+
100.0 %22 / 2280.0 %4 / 5
DumpGrid.cpp +
100.0%
+
100.0 %34 / 3485.7 %6 / 7
GridPrintingBase.cpp +
100.0%
+
100.0 %53 / 5380.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/gridtools/index.html b/coverage/gridtools/index.html new file mode 100644 index 0000000000..07d8c920c1 --- /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:1184126593.6 %
Date:2024-06-10 08:19:14Functions:17120085.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
95.8%95.8%
+
95.8 %46 / 4886.7 %13 / 15
DumpCube.cpp +
88.9%88.9%
+
88.9 %32 / 3685.7 %6 / 7
DumpGrid.cpp +
100.0%
+
100.0 %34 / 3485.7 %6 / 7
FindContour.cpp +
84.3%84.3%
+
84.3 %75 / 8975.0 %9 / 12
FindContourSurface.cpp +
95.7%95.7%
+
95.7 %90 / 9483.3 %10 / 12
FindSphericalContour.cpp +
95.1%95.1%
+
95.1 %39 / 4187.5 %7 / 8
FourierTransform.cpp +
83.7%83.7%
+
83.7 %72 / 8670.0 %7 / 10
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.9%88.9%
+
88.9 %40 / 4585.7 %6 / 7
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 %119 / 121100.0 %12 / 12
HistogramOnGrid.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
IntegrateGrid.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
InterpolateGrid.cpp +
93.5%93.5%
+
93.5 %29 / 3177.8 %7 / 9
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/index-sort-f.html b/coverage/index-sort-f.html new file mode 100644 index 0000000000..2c2ea67965 --- /dev/null +++ b/coverage/index-sort-f.html @@ -0,0 +1,454 @@ + + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:452155261685.9 %
Date:2024-06-10 08:19:14Functions:5454683879.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
config +
62.3%62.3%
+
62.3 %86 / 13860.0 %30 / 50
wrapper +
53.9%53.9%
+
53.9 %236 / 43862.6 %142 / 227
manyrestraints +
81.5%81.5%
+
81.5 %75 / 9269.2 %18 / 26
ves +
82.1%82.1%
+
82.1 %5939 / 723270.4 %555 / 788
piv +
71.4%71.4%
+
71.4 %425 / 59572.7 %8 / 11
dimred +
84.8%84.8%
+
84.8 %556 / 65672.9 %78 / 107
crystallization +
83.3%83.3%
+
83.3 %973 / 116877.0 %144 / 187
analysis +
88.5%88.5%
+
88.5 %859 / 97177.2 %156 / 202
multicolvar +
78.6%78.6%
+
78.6 %2379 / 302878.0 %329 / 422
reference +
86.1%86.1%
+
86.1 %668 / 77679.3 %153 / 193
pamm +
81.4%81.4%
+
81.4 %215 / 26479.4 %27 / 34
generic +
94.5%94.5%
+
94.5 %1197 / 126779.7 %177 / 222
core +
85.6%85.6%
+
85.6 %3026 / 353780.0 %407 / 509
maze +
83.2%83.2%
+
83.2 %660 / 79380.3 %94 / 117
isdb +
85.2%85.2%
+
85.2 %5203 / 610880.5 %186 / 231
tools +
83.4%83.4%
+
83.4 %5445 / 653080.9 %1365 / 1687
s2cm +
91.6%91.6%
+
91.6 %152 / 16681.8 %9 / 11
adjmat +
88.7%88.7%
+
88.7 %1039 / 117282.1 %183 / 223
colvar +
93.7%93.7%
+
93.7 %1980 / 211482.4 %182 / 221
fisst +
79.6%79.6%
+
79.6 %319 / 40182.8 %24 / 29
secondarystructure +
96.7%96.7%
+
96.7 %376 / 38982.9 %29 / 35
setup +
97.8%97.8%
+
97.8 %87 / 8983.3 %15 / 18
funnel +
98.1%98.1%
+
98.1 %254 / 25983.3 %15 / 18
function +
85.4%85.4%
+
85.4 %904 / 105984.0 %84 / 100
sasa +
82.1%82.1%
+
82.1 %1004 / 122384.4 %27 / 32
gridtools +
93.6%93.6%
+
93.6 %1184 / 126585.5 %171 / 200
bias +
91.4%91.4%
+
91.4 %2347 / 256785.6 %143 / 167
eds +
92.6%92.6%
+
92.6 %452 / 48887.0 %20 / 23
vatom +
99.5%99.5%
+
99.5 %205 / 20687.5 %21 / 24
mapping +
93.7%93.7%
+
93.7 %754 / 80588.8 %87 / 98
annfunc +
97.1%97.1%
+
97.1 %134 / 13888.9 %8 / 9
vesselbase +
92.9%92.9%
+
92.9 %1139 / 122689.5 %231 / 258
cltools +
80.4%80.4%
+
80.4 %1292 / 160792.2 %94 / 102
logmfd +
89.2%89.2%
+
89.2 %298 / 33493.3 %14 / 15
opes +
96.1%96.1%
+
96.1 %2157 / 224493.8 %135 / 144
drr +
94.3%94.3%
+
94.3 %1184 / 125694.8 %92 / 97
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/index-sort-l.html b/coverage/index-sort-l.html new file mode 100644 index 0000000000..d05644bef1 --- /dev/null +++ b/coverage/index-sort-l.html @@ -0,0 +1,454 @@ + + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:452155261685.9 %
Date:2024-06-10 08:19:14Functions:5454683879.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
wrapper +
53.9%53.9%
+
53.9 %236 / 43862.6 %142 / 227
config +
62.3%62.3%
+
62.3 %86 / 13860.0 %30 / 50
piv +
71.4%71.4%
+
71.4 %425 / 59572.7 %8 / 11
multicolvar +
78.6%78.6%
+
78.6 %2379 / 302878.0 %329 / 422
fisst +
79.6%79.6%
+
79.6 %319 / 40182.8 %24 / 29
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
cltools +
80.4%80.4%
+
80.4 %1292 / 160792.2 %94 / 102
pamm +
81.4%81.4%
+
81.4 %215 / 26479.4 %27 / 34
manyrestraints +
81.5%81.5%
+
81.5 %75 / 9269.2 %18 / 26
sasa +
82.1%82.1%
+
82.1 %1004 / 122384.4 %27 / 32
ves +
82.1%82.1%
+
82.1 %5939 / 723270.4 %555 / 788
maze +
83.2%83.2%
+
83.2 %660 / 79380.3 %94 / 117
crystallization +
83.3%83.3%
+
83.3 %973 / 116877.0 %144 / 187
tools +
83.4%83.4%
+
83.4 %5445 / 653080.9 %1365 / 1687
dimred +
84.8%84.8%
+
84.8 %556 / 65672.9 %78 / 107
isdb +
85.2%85.2%
+
85.2 %5203 / 610880.5 %186 / 231
function +
85.4%85.4%
+
85.4 %904 / 105984.0 %84 / 100
core +
85.6%85.6%
+
85.6 %3026 / 353780.0 %407 / 509
reference +
86.1%86.1%
+
86.1 %668 / 77679.3 %153 / 193
analysis +
88.5%88.5%
+
88.5 %859 / 97177.2 %156 / 202
adjmat +
88.7%88.7%
+
88.7 %1039 / 117282.1 %183 / 223
logmfd +
89.2%89.2%
+
89.2 %298 / 33493.3 %14 / 15
bias +
91.4%91.4%
+
91.4 %2347 / 256785.6 %143 / 167
s2cm +
91.6%91.6%
+
91.6 %152 / 16681.8 %9 / 11
eds +
92.6%92.6%
+
92.6 %452 / 48887.0 %20 / 23
vesselbase +
92.9%92.9%
+
92.9 %1139 / 122689.5 %231 / 258
gridtools +
93.6%93.6%
+
93.6 %1184 / 126585.5 %171 / 200
mapping +
93.7%93.7%
+
93.7 %754 / 80588.8 %87 / 98
colvar +
93.7%93.7%
+
93.7 %1980 / 211482.4 %182 / 221
drr +
94.3%94.3%
+
94.3 %1184 / 125694.8 %92 / 97
generic +
94.5%94.5%
+
94.5 %1197 / 126779.7 %177 / 222
opes +
96.1%96.1%
+
96.1 %2157 / 224493.8 %135 / 144
secondarystructure +
96.7%96.7%
+
96.7 %376 / 38982.9 %29 / 35
annfunc +
97.1%97.1%
+
97.1 %134 / 13888.9 %8 / 9
setup +
97.8%97.8%
+
97.8 %87 / 8983.3 %15 / 18
funnel +
98.1%98.1%
+
98.1 %254 / 25983.3 %15 / 18
vatom +
99.5%99.5%
+
99.5 %205 / 20687.5 %21 / 24
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 0000000000..f1e97f419e --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,454 @@ + + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:452155261685.9 %
Date:2024-06-10 08:19:14Functions:5454683879.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
adjmat +
88.7%88.7%
+
88.7 %1039 / 117282.1 %183 / 223
analysis +
88.5%88.5%
+
88.5 %859 / 97177.2 %156 / 202
annfunc +
97.1%97.1%
+
97.1 %134 / 13888.9 %8 / 9
bias +
91.4%91.4%
+
91.4 %2347 / 256785.6 %143 / 167
cltools +
80.4%80.4%
+
80.4 %1292 / 160792.2 %94 / 102
colvar +
93.7%93.7%
+
93.7 %1980 / 211482.4 %182 / 221
config +
62.3%62.3%
+
62.3 %86 / 13860.0 %30 / 50
core +
85.6%85.6%
+
85.6 %3026 / 353780.0 %407 / 509
crystallization +
83.3%83.3%
+
83.3 %973 / 116877.0 %144 / 187
dimred +
84.8%84.8%
+
84.8 %556 / 65672.9 %78 / 107
drr +
94.3%94.3%
+
94.3 %1184 / 125694.8 %92 / 97
eds +
92.6%92.6%
+
92.6 %452 / 48887.0 %20 / 23
fisst +
79.6%79.6%
+
79.6 %319 / 40182.8 %24 / 29
function +
85.4%85.4%
+
85.4 %904 / 105984.0 %84 / 100
funnel +
98.1%98.1%
+
98.1 %254 / 25983.3 %15 / 18
generic +
94.5%94.5%
+
94.5 %1197 / 126779.7 %177 / 222
gridtools +
93.6%93.6%
+
93.6 %1184 / 126585.5 %171 / 200
isdb +
85.2%85.2%
+
85.2 %5203 / 610880.5 %186 / 231
logmfd +
89.2%89.2%
+
89.2 %298 / 33493.3 %14 / 15
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
manyrestraints +
81.5%81.5%
+
81.5 %75 / 9269.2 %18 / 26
mapping +
93.7%93.7%
+
93.7 %754 / 80588.8 %87 / 98
maze +
83.2%83.2%
+
83.2 %660 / 79380.3 %94 / 117
multicolvar +
78.6%78.6%
+
78.6 %2379 / 302878.0 %329 / 422
opes +
96.1%96.1%
+
96.1 %2157 / 224493.8 %135 / 144
pamm +
81.4%81.4%
+
81.4 %215 / 26479.4 %27 / 34
piv +
71.4%71.4%
+
71.4 %425 / 59572.7 %8 / 11
reference +
86.1%86.1%
+
86.1 %668 / 77679.3 %153 / 193
s2cm +
91.6%91.6%
+
91.6 %152 / 16681.8 %9 / 11
sasa +
82.1%82.1%
+
82.1 %1004 / 122384.4 %27 / 32
secondarystructure +
96.7%96.7%
+
96.7 %376 / 38982.9 %29 / 35
setup +
97.8%97.8%
+
97.8 %87 / 8983.3 %15 / 18
tools +
83.4%83.4%
+
83.4 %5445 / 653080.9 %1365 / 1687
vatom +
99.5%99.5%
+
99.5 %205 / 20687.5 %21 / 24
ves +
82.1%82.1%
+
82.1 %5939 / 723270.4 %555 / 788
vesselbase +
92.9%92.9%
+
92.9 %1139 / 122689.5 %231 / 258
wrapper +
53.9%53.9%
+
53.9 %236 / 43862.6 %142 / 227
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..0a4a4a8c1f --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.func-sort-c.html @@ -0,0 +1,177 @@ + + + + + + + + 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:91896994.7 %
Date:2024-06-10 08:19:14Functions:252696.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD4isdb12_GLOBAL__N_124CS2BackboneRegisterMe4946createERKNS_13ActionOptionsE18
_ZN4PLMD4isdb13CS2BackboneDB5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd18
_ZN4PLMD4isdb11CS2Backbone16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD4isdb11CS2Backbone7init_csERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_3PDBE108
_ZN4PLMD4isdb11CS2Backbone8RingInfoC2Ev360
_ZN4PLMD4isdb12_GLOBAL__N_124CS2BackboneRegisterMe494C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_124CS2BackboneRegisterMe494D2Ev3473
_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.15
+
+ + + diff --git a/coverage/isdb/CS2Backbone.cpp.func.html b/coverage/isdb/CS2Backbone.cpp.func.html new file mode 100644 index 0000000000..82ef1764fe --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.func.html @@ -0,0 +1,177 @@ + + + + + + + + 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:91896994.7 %
Date:2024-06-10 08:19:14Functions:252696.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_8KeywordsE19
_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
_ZN4PLMD4isdb12_GLOBAL__N_124CS2BackboneRegisterMe4946createERKNS_13ActionOptionsE18
_ZN4PLMD4isdb12_GLOBAL__N_124CS2BackboneRegisterMe494C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_124CS2BackboneRegisterMe494D2Ev3473
_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.15
+
+ + + diff --git a/coverage/isdb/CS2Backbone.cpp.gcov.html b/coverage/isdb/CS2Backbone.cpp.gcov.html new file mode 100644 index 0000000000..54b4da0bf9 --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.gcov.html @@ -0,0 +1,1916 @@ + + + + + + + + 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:91896994.7 %
Date:2024-06-10 08:19:14Functions:252696.2 %
+
+ + + + + + + + +

+
          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             : 
+      44             : namespace PLMD {
+      45             : namespace isdb {
+      46             : 
+      47             : //+PLUMEDOC ISDB_COLVAR CS2BACKBONE
+      48             : /*
+      49             : Calculates the backbone chemical shifts for a protein.
+      50             : 
+      51             : The functional form is that of CamShift \cite Kohlhoff:2009us. The chemical shift
+      52             : of the selected nuclei can be saved as components. Alternatively one can calculate either
+      53             : the CAMSHIFT score (useful as a collective variable \cite Granata:2013dk or as a scoring
+      54             : function \cite Robustelli:2010dn) or a \ref METAINFERENCE score (using DOSCORE).
+      55             : For these two latter cases experimental chemical shifts must be provided.
+      56             : 
+      57             : CS2BACKBONE calculation can be relatively heavy because it often uses a large number of atoms, it can
+      58             : be run in parallel using MPI and \ref Openmp.
+      59             : 
+      60             : As a general rule, when using \ref CS2BACKBONE or other experimental restraints it may be better to
+      61             : increase the accuracy of the constraint algorithm due to the increased strain on the bonded structure.
+      62             : In the case of GROMACS it is safer to use lincs-iter=2 and lincs-order=6.
+      63             : 
+      64             : In general the system for which chemical shifts are calculated must be completely included in
+      65             : ATOMS and a TEMPLATE pdb file for the same atoms should be provided as well in the folder DATADIR.
+      66             : The system is made automatically whole unless NOPBC is used, in particular if the system is made
+      67             : by multiple chains it is usually better to use NOPBC and make the molecule whole \ref WHOLEMOLECULES
+      68             : selecting an appropriate order of the atoms. The pdb file is needed to the generate a simple topology of the protein.
+      69             : For histidine residues in protonation states different from D the HIE/HSE HIP/HSP name should be used.
+      70             : GLH and ASH can be used for the alternative protonation of GLU and ASP. Non-standard amino acids and other
+      71             : molecules are not yet supported, but in principle they can be named UNK. If multiple chains are present
+      72             : the chain identifier must be in the standard PDB format, together with the TER keyword at the end of each chain.
+      73             : Termini groups like ACE or NME should be removed from the TEMPLATE pdb because they are not recognized by
+      74             : CS2BACKBONE.
+      75             : 
+      76             : In addition to a pdb file one needs to provide a list of chemical shifts to be calculated using one
+      77             : file per nucleus type (CAshifts.dat, CBshifts.dat, Cshifts.dat, Hshifts.dat, HAshifts.dat, Nshifts.dat),
+      78             : add only the files for the nuclei you need, but each file should include all protein residues.
+      79             : A chemical shift for a nucleus is calculated if a value greater than 0 is provided.
+      80             : For practical purposes the value can correspond to the experimental value.
+      81             : Residues numbers should match that used in the pdb file, but must be positive, so double check the pdb.
+      82             : The first and last residue of each chain should be preceded by a # character.
+      83             : 
+      84             : \verbatim
+      85             : CAshifts.dat:
+      86             : #1 0.0
+      87             : 2 55.5
+      88             : 3 58.4
+      89             : .
+      90             : .
+      91             : #last 0.0
+      92             : #first of second chain
+      93             : .
+      94             : #last of second chain
+      95             : \endverbatim
+      96             : 
+      97             : The default behavior is to store the values for the active nuclei in components (ca-#, cb-#,
+      98             : co-#, ha-#, hn-#, nh-# and expca-#, expcb-#, expco-#, expha-#, exphn-#, exp-nh#) with NOEXP it is possible
+      99             : to only store the back-calculated values, where # includes a chain and residue number.
+     100             : 
+     101             : One additional file is always needed in the folder DATADIR: camshift.db. This file includes all the parameters needed to
+     102             : calculate the chemical shifts and can be found in regtest/isdb/rt-cs2backbone/data/ .
+     103             : 
+     104             : Additional material and examples can be also found in the tutorial \ref isdb-1 as well as in the cs2backbone regtests
+     105             : in the isdb folder.
+     106             : 
+     107             : \par Examples
+     108             : 
+     109             : In this first example the chemical shifts are used to calculate a collective variable to be used
+     110             : in NMR driven Metadynamics \cite Granata:2013dk :
+     111             : 
+     112             : \plumedfile
+     113             : #SETTINGS AUXFOLDER=regtest/isdb/rt-cs2backbone/data
+     114             : whole: GROUP ATOMS=2612-2514:-1,961-1:-1,2466-962:-1,2513-2467:-1
+     115             : WHOLEMOLECULES ENTITY0=whole
+     116             : cs: CS2BACKBONE ATOMS=1-2612 DATADIR=data/ TEMPLATE=template.pdb CAMSHIFT NOPBC
+     117             : metad: METAD ARG=cs HEIGHT=0.5 SIGMA=0.1 PACE=200 BIASFACTOR=10
+     118             : PRINT ARG=cs,metad.bias FILE=COLVAR STRIDE=100
+     119             : \endplumedfile
+     120             : 
+     121             : In this second example the chemical shifts are used as replica-averaged restrained as in \cite Camilloni:2012je \cite Camilloni:2013hs .
+     122             : 
+     123             : \plumedfile
+     124             : #SETTINGS AUXFOLDER=regtest/isdb/rt-cs2backbone/data NREPLICAS=2
+     125             : cs: CS2BACKBONE ATOMS=1-174 DATADIR=data/
+     126             : encs: ENSEMBLE ARG=(cs\.hn-.*),(cs\.nh-.*)
+     127             : stcs: STATS ARG=encs.* SQDEVSUM PARARG=(cs\.exphn-.*),(cs\.expnh-.*)
+     128             : RESTRAINT ARG=stcs.sqdevsum AT=0 KAPPA=0 SLOPE=24
+     129             : 
+     130             : PRINT ARG=(cs\.hn-.*),(cs\.nh-.*) FILE=RESTRAINT STRIDE=100
+     131             : 
+     132             : \endplumedfile
+     133             : 
+     134             : This third example show how to use chemical shifts to calculate a \ref METAINFERENCE score .
+     135             : 
+     136             : \plumedfile
+     137             : #SETTINGS AUXFOLDER=regtest/isdb/rt-cs2backbone/data
+     138             : cs: CS2BACKBONE ATOMS=1-174 DATADIR=data/ SIGMA_MEAN0=1.0 DOSCORE
+     139             : csbias: BIASVALUE ARG=cs.score
+     140             : 
+     141             : PRINT ARG=(cs\.hn-.*),(cs\.nh-.*) FILE=CS.dat STRIDE=1000
+     142             : PRINT ARG=cs.score FILE=BIAS STRIDE=100
+     143             : \endplumedfile
+     144             : 
+     145             : */
+     146             : //+ENDPLUMEDOC
+     147             : 
+     148             : class CS2BackboneDB {
+     149             :   enum { STD, GLY, PRO};
+     150             :   enum { HA_ATOM, H_ATOM, N_ATOM, CA_ATOM, CB_ATOM, C_ATOM };
+     151             :   static const unsigned aa_kind = 3;
+     152             :   static const unsigned atm_kind = 6;
+     153             :   static const unsigned numXtraDists = 27;
+     154             : 
+     155             :   // ALA, ARG, ASN, ASP, CYS, GLU, GLN, GLY, HIS, ILE, LEU, LYS, MET, PHE, PRO, SER, THR, TRP, TYR, VAL
+     156             :   double c_aa[aa_kind][atm_kind][20];
+     157             :   double c_aa_prev[aa_kind][atm_kind][20];
+     158             :   double c_aa_succ[aa_kind][atm_kind][20];
+     159             :   double co_bb[aa_kind][atm_kind][16];
+     160             :   double co_sc_[aa_kind][atm_kind][20][20];
+     161             :   double co_xd[aa_kind][atm_kind][numXtraDists];
+     162             :   double co_sphere[aa_kind][atm_kind][2][8];
+     163             :   // for ring current effects
+     164             :   // Phe, Tyr, Trp_1, Trp_2, His
+     165             :   double co_ring[aa_kind][atm_kind][5];
+     166             :   // for dihedral angles
+     167             :   // co * (a * cos(3 * omega + c) + b * cos(omega + d))
+     168             :   double co_da[aa_kind][atm_kind][3];
+     169             :   double pars_da[aa_kind][atm_kind][3][5];
+     170             : 
+     171             : public:
+     172             : 
+     173       10926 :   inline unsigned kind(const std::string &s) {
+     174       10926 :     if(s=="GLY") return GLY;
+     175        9324 :     else if(s=="PRO") return PRO;
+     176             :     return STD;
+     177             :   }
+     178             : 
+     179       10926 :   inline unsigned atom_kind(const std::string &s) {
+     180       10926 :     if(s=="HA")return HA_ATOM;
+     181       10872 :     else if(s=="H") return H_ATOM;
+     182        8010 :     else if(s=="N") return N_ATOM;
+     183        5148 :     else if(s=="CA")return CA_ATOM;
+     184        2160 :     else if(s=="CB")return CB_ATOM;
+     185          54 :     else if(s=="C") return C_ATOM;
+     186             :     return -1;
+     187             :   }
+     188             : 
+     189             :   unsigned get_numXtraDists() {return numXtraDists;}
+     190             : 
+     191             :   //PARAMETERS
+     192             :   inline double * CONSTAACURR(const unsigned a_kind, const unsigned at_kind) {return c_aa[a_kind][at_kind];}
+     193             :   inline double * CONSTAANEXT(const unsigned a_kind, const unsigned at_kind) {return c_aa_succ[a_kind][at_kind];}
+     194             :   inline double * CONSTAAPREV(const unsigned a_kind, const unsigned at_kind) {return c_aa_prev[a_kind][at_kind];}
+     195             :   inline double * CONST_BB2(const unsigned a_kind, const unsigned at_kind) {return co_bb[a_kind][at_kind];}
+     196             :   inline double * CONST_SC2(const unsigned a_kind, const unsigned at_kind, unsigned res_type) { return co_sc_[a_kind][at_kind][res_type];}
+     197             :   inline double * CONST_XD(const unsigned a_kind, const unsigned at_kind) { return co_xd[a_kind][at_kind];}
+     198             :   inline double * CO_SPHERE(const unsigned a_kind, const unsigned at_kind, unsigned exp_type) { return co_sphere[a_kind][at_kind][exp_type];}
+     199             :   inline double * CO_RING(const unsigned a_kind, const unsigned at_kind) { return co_ring[a_kind][at_kind];}
+     200             :   inline double * CO_DA(const unsigned a_kind, const unsigned at_kind) { return co_da[a_kind][at_kind];}
+     201             :   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];}
+     202             : 
+     203          18 :   void parse(const std::string &file, const double dscale) {
+     204          18 :     std::ifstream in;
+     205          18 :     in.open(file.c_str());
+     206          18 :     if(!in) plumed_merror("Unable to open DB file: " + file);
+     207             : 
+     208             :     unsigned c_kind = 0;
+     209             :     unsigned c_atom = 0;
+     210             :     unsigned nline = 0;
+     211             : 
+     212         396 :     for(unsigned i=0; i<3; i++) for(unsigned j=0; j<6; j++) {
+     213        6804 :         for(unsigned k=0; k<20; k++) {
+     214        6480 :           c_aa[i][j][k]=0.;
+     215        6480 :           c_aa_prev[i][j][k]=0.;
+     216        6480 :           c_aa_succ[i][j][k]=0.;
+     217      136080 :           for(unsigned m=0; m<20; m++) co_sc_[i][j][k][m]=0.;
+     218             :         }
+     219        5508 :         for(unsigned k=0; k<16; k++) {co_bb[i][j][k]=0.; }
+     220        2916 :         for(unsigned k=0; k<8; k++) { co_sphere[i][j][0][k]=0.; co_sphere[i][j][1][k]=0.; }
+     221        1296 :         for(unsigned k=0; k<3; k++) {
+     222         972 :           co_da[i][j][k]=0.;
+     223        5832 :           for(unsigned l=0; l<5; l++) pars_da[i][j][k][l]=0.;
+     224             :         }
+     225        1944 :         for(unsigned k=0; k<5; k++) co_ring[i][j][k]=0.;
+     226        9072 :         for(unsigned k=0; k<numXtraDists; k++) co_xd[i][j][k]=0.;
+     227             :       }
+     228             : 
+     229       37710 :     while(!in.eof()) {
+     230             :       std::string line;
+     231       37692 :       getline(in,line);
+     232             :       ++nline;
+     233       37692 :       if(line.compare(0,1,"#")==0) continue;
+     234             :       std::vector<std::string> tok;
+     235             :       std::vector<std::string> tmp;
+     236       40860 :       tok = split(line,' ');
+     237      261828 :       for(unsigned q=0; q<tok.size(); q++)
+     238      241398 :         if(tok[q].size()) tmp.push_back(tok[q]);
+     239       20430 :       tok = tmp;
+     240       20430 :       if(tok.size()==0) continue;
+     241       20412 :       if(tok[0]=="PAR") {
+     242         324 :         c_kind = kind(tok[2]);
+     243         324 :         c_atom = atom_kind(tok[1]);
+     244         324 :         continue;
+     245             :       }
+     246       20088 :       else if(tok[0]=="WEIGHT") {
+     247         324 :         continue;
+     248             :       }
+     249       19764 :       else if(tok[0]=="FLATBTM") {
+     250         324 :         continue;
+     251             :       }
+     252       19440 :       else if (tok[0] == "SCALEHARM") {
+     253         324 :         continue;
+     254             :       }
+     255       19116 :       else if (tok[0] == "TANHAMPLI") {
+     256         324 :         continue;
+     257             :       }
+     258       18792 :       else if (tok[0] == "ENDHARMON") {
+     259         324 :         continue;
+     260             :       }
+     261       18468 :       else if (tok[0] == "MAXRCDEVI") {
+     262         324 :         continue;
+     263             :       }
+     264       18144 :       else if (tok[0] == "RANDCOIL") {
+     265         324 :         continue;
+     266             :       }
+     267       17820 :       else if (tok[0] == "CONST") {
+     268         324 :         continue;
+     269             :       }
+     270       17496 :       else if (tok[0] == "CONSTAA") {
+     271         324 :         assign(c_aa[c_kind][c_atom],tok,1);
+     272         324 :         continue;
+     273             :       }
+     274       17172 :       else if (tok[0] == "CONSTAA-1") {
+     275         324 :         assign(c_aa_prev[c_kind][c_atom],tok,1);
+     276         324 :         continue;
+     277             :       }
+     278       16848 :       else if (tok[0] == "CONSTAA+1") {
+     279         324 :         assign(c_aa_succ[c_kind][c_atom],tok,1);
+     280         324 :         continue;
+     281             :       }
+     282       16524 :       else if (tok[0] == "COBB1") {
+     283         324 :         continue;
+     284             :       }
+     285       16200 :       else if (tok[0] == "COBB2") {
+     286             :         //angstrom to nm
+     287         324 :         assign(co_bb[c_kind][c_atom],tok,dscale);
+     288         324 :         continue;
+     289             :       }
+     290       15876 :       else if (tok[0] == "SPHERE1") {
+     291             :         // angstrom^-3 to nm^-3
+     292         324 :         assign(co_sphere[c_kind][c_atom][0],tok,1./(dscale*dscale*dscale));
+     293         324 :         continue;
+     294             :       }
+     295       15552 :       else if (tok[0] == "SPHERE2") {
+     296             :         //angstrom to nm
+     297         324 :         assign(co_sphere[c_kind][c_atom][1],tok,dscale);
+     298         324 :         continue;
+     299             :       }
+     300       15228 :       else if (tok[0] == "DIHEDRALS") {
+     301         324 :         assign(co_da[c_kind][c_atom],tok,1);
+     302         324 :         continue;
+     303             :       }
+     304       14904 :       else if (tok[0] == "RINGS") {
+     305             :         // angstrom^-3 to nm^-3
+     306         324 :         assign(co_ring[c_kind][c_atom],tok,1./(dscale*dscale*dscale));
+     307        1944 :         for(unsigned i=1; i<tok.size(); i++)
+     308        1620 :           co_ring[c_kind][c_atom][i-1] *= 1000;
+     309         324 :         continue;
+     310         324 :       }
+     311       14580 :       else if (tok[0] == "HBONDS") {
+     312         324 :         continue;
+     313             :       }
+     314       14256 :       else if (tok[0] == "XTRADISTS") {
+     315             :         //angstrom to nm
+     316         324 :         assign(co_xd[c_kind][c_atom],tok,dscale);
+     317         324 :         continue;
+     318             :       }
+     319       13932 :       else if(tok[0]=="DIHEDPHI") {
+     320         324 :         assign(pars_da[c_kind][c_atom][0],tok,1);
+     321         324 :         continue;
+     322             :       }
+     323       13608 :       else if(tok[0]=="DIHEDPSI") {
+     324         324 :         assign(pars_da[c_kind][c_atom][1],tok,1);
+     325         324 :         continue;
+     326             :       }
+     327       13284 :       else if(tok[0]=="DIHEDCHI1") {
+     328         324 :         assign(pars_da[c_kind][c_atom][2],tok,1);
+     329         324 :         continue;
+     330             :       }
+     331             : 
+     332             :       bool ok = false;
+     333             :       std::string scIdent1 [] = {"COSCALA1", "COSCARG1", "COSCASN1", "COSCASP1", "COSCCYS1", "COSCGLN1", "COSCGLU1",
+     334             :                                  "COSCGLY1", "COSCHIS1", "COSCILE1", "COSCLEU1", "COSCLYS1", "COSCMET1", "COSCPHE1",
+     335             :                                  "COSCPRO1", "COSCSER1", "COSCTHR1", "COSCTRP1", "COSCTYR1", "COSCVAL1"
+     336      272160 :                                 };
+     337             : 
+     338      204120 :       for(unsigned scC = 0; scC < 20; scC++) {
+     339      197640 :         if(tok[0]==scIdent1[scC]) {
+     340             :           ok = true;
+     341             :           break;
+     342             :         }
+     343             :       }
+     344      285120 :       if(ok) continue;
+     345             : 
+     346             :       std::string scIdent2 [] = {"COSCALA2", "COSCARG2", "COSCASN2", "COSCASP2", "COSCCYS2", "COSCGLN2", "COSCGLU2",
+     347             :                                  "COSCGLY2", "COSCHIS2", "COSCILE2", "COSCLEU2", "COSCLYS2", "COSCMET2", "COSCPHE2",
+     348             :                                  "COSCPRO2", "COSCSER2", "COSCTHR2", "COSCTRP2", "COSCTYR2", "COSCVAL2"
+     349      136080 :                                 };
+     350             : 
+     351       68040 :       for(unsigned scC = 0; scC < 20; scC++) {
+     352       68040 :         if(tok[0]==scIdent2[scC]) {
+     353             :           //angstrom to nm
+     354        6480 :           assign(co_sc_[c_kind][c_atom][scC],tok,dscale);
+     355             :           ok = true; break;
+     356             :         }
+     357             :       }
+     358      142560 :       if(ok) continue;
+     359             : 
+     360           0 :       if(tok.size()) {
+     361           0 :         std::string str_err = "DB WARNING: unrecognized token: " + tok[0];
+     362           0 :         plumed_merror(str_err);
+     363             :       }
+     364      428670 :     }
+     365          18 :     in.close();
+     366          18 :   }
+     367             : 
+     368             : private:
+     369             : 
+     370       20430 :   std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
+     371       20430 :     std::stringstream ss(s);
+     372             :     std::string item;
+     373      261828 :     while (getline(ss, item, delim)) {
+     374      241398 :       elems.push_back(item);
+     375             :     }
+     376       20430 :     return elems;
+     377       20430 :   }
+     378             : 
+     379       20430 :   std::vector<std::string> split(const std::string &s, char delim) {
+     380             :     std::vector<std::string> elems;
+     381       20430 :     split(s, delim, elems);
+     382       20430 :     return elems;
+     383           0 :   }
+     384             : 
+     385       10368 :   void assign(double * f, const std::vector<std::string> & v, const double scale) {
+     386      122796 :     for(unsigned i=1; i<v.size(); i++) {
+     387      112428 :       f[i-1] = scale*(atof(v[i].c_str()));
+     388      112428 :       if(std::abs(f[i-1])<0.000001) f[i-1]=0.;
+     389             :     }
+     390       10368 :   }
+     391             : };
+     392             : 
+     393             : class CS2Backbone : public MetainferenceBase {
+     394             :   struct ChemicalShift {
+     395             :     double exp_cs;              // a reference chemical shifts
+     396             :     Value *comp;                // a pointer to the component
+     397             :     unsigned res_kind;          // residue type (STD/GLY/PRO)
+     398             :     unsigned atm_kind;          // nuclues (HA/CA/CB/CO/NH/HN)
+     399             :     unsigned res_type_prev;     // previous residue (ALA/VAL/..)
+     400             :     unsigned res_type_curr;     // current residue (ALA/VAL/..)
+     401             :     unsigned res_type_next;     // next residue (ALA/VAL/..)
+     402             :     std::string res_name;       // residue name
+     403             :     std::string nucleus;        // chemical shift
+     404             :     bool has_chi1;              // does we have a chi1
+     405             :     unsigned csatoms;           // fixed number of atoms used
+     406             :     unsigned totcsatoms;        // number of atoms used
+     407             :     unsigned res_num;           // residue number
+     408             :     unsigned chain;             // chain number
+     409             :     unsigned ipos;              // index of the atom for which we are calculating the chemical shifts
+     410             :     std::vector<unsigned> bb;        // atoms for the previous, current and next backbone
+     411             :     std::vector<unsigned> side_chain;// atoms for the current sidechain
+     412             :     std::vector<int> xd1;            // additional couple of atoms
+     413             :     std::vector<int> xd2;            // additional couple of atoms
+     414             :     std::vector<unsigned> box_nb;    // non-bonded atoms
+     415             : 
+     416       10602 :     ChemicalShift():
+     417       10602 :       exp_cs(0.),
+     418       10602 :       comp(NULL),
+     419       10602 :       res_kind(0),
+     420       10602 :       atm_kind(0),
+     421       10602 :       res_type_prev(0),
+     422       10602 :       res_type_curr(0),
+     423       10602 :       res_type_next(0),
+     424       10602 :       res_name(""),
+     425       10602 :       nucleus(""),
+     426       10602 :       has_chi1(true),
+     427       10602 :       csatoms(0),
+     428       10602 :       totcsatoms(0),
+     429       10602 :       res_num(0),
+     430       10602 :       chain(0),
+     431       10602 :       ipos(0)
+     432             :     {
+     433       10602 :       xd1.reserve(26);
+     434       10602 :       xd2.reserve(26);
+     435       10602 :       box_nb.reserve(150);
+     436       10602 :     }
+     437             :   };
+     438             : 
+     439             :   struct RingInfo {
+     440             :     enum {R_PHE, R_TYR, R_TRP1, R_TRP2, R_HIS};
+     441             :     unsigned rtype;    // one out of five different types
+     442             :     unsigned atom[6];  // up to six member per ring
+     443             :     unsigned numAtoms; // number of ring members (5 or 6)
+     444             :     Vector position;   // center of ring coordinates
+     445             :     Vector normVect;   // ring plane normal std::vector
+     446             :     Vector g[6];       // std::vector of the std::vectors used for normVect
+     447             :     double lengthN2;   // square of length of normVect
+     448             :     double lengthNV;   // length of normVect
+     449         360 :     RingInfo():
+     450         360 :       rtype(0),
+     451         360 :       numAtoms(0),
+     452         360 :       lengthN2(NAN),
+     453        2520 :       lengthNV(NAN)
+     454             :     {
+     455        2520 :       for(unsigned i=0; i<6; i++) atom[i]=0;
+     456         360 :     }
+     457             :   };
+     458             : 
+     459             :   enum aa_t {ALA, ARG, ASN, ASP, CYS, GLN, GLU, GLY, HIS, ILE, LEU, LYS, MET, PHE, PRO, SER, THR, TRP, TYR, VAL, UNK};
+     460             :   enum sequence_t {Np, CAp, HAp, Cp, Op, Nc, Hc, CAc, HAc, Cc, Oc, Nn, Hn, CAn, HAn, Cn, CBc, CGc};
+     461             : 
+     462             :   CS2BackboneDB    db;
+     463             :   std::vector<ChemicalShift> chemicalshifts;
+     464             : 
+     465             :   std::vector<RingInfo> ringInfo;
+     466             :   std::vector<unsigned> type;
+     467             :   std::vector<unsigned> res_num;
+     468             :   unsigned         max_cs_atoms;
+     469             :   unsigned         box_nupdate;
+     470             :   unsigned         box_count;
+     471             :   bool             camshift;
+     472             :   bool             pbc;
+     473             :   bool             serial;
+     474             : 
+     475             :   void init_cs(const std::string &file, const std::string &k, const PDB &pdb);
+     476             :   void update_neighb();
+     477             :   void compute_ring_parameters();
+     478             :   void init_types(const PDB &pdb);
+     479             :   void init_rings(const PDB &pdb);
+     480             :   aa_t frag2enum(const std::string &aa);
+     481             :   std::vector<std::string> side_chain_atoms(const std::string &s);
+     482             :   bool isSP2(const std::string & resType, const std::string & atomName);
+     483             :   bool is_chi1_cx(const std::string & frg, const std::string & atm);
+     484             :   void xdist_name_map(std::string & name);
+     485             : 
+     486             : public:
+     487             : 
+     488             :   explicit CS2Backbone(const ActionOptions&);
+     489             :   static void registerKeywords( Keywords& keys );
+     490             :   void calculate() override;
+     491             :   void update() override;
+     492             : };
+     493             : 
+     494       10455 : PLUMED_REGISTER_ACTION(CS2Backbone,"CS2BACKBONE")
+     495             : 
+     496          19 : void CS2Backbone::registerKeywords( Keywords& keys ) {
+     497          19 :   componentsAreNotOptional(keys);
+     498          19 :   MetainferenceBase::registerKeywords( keys );
+     499          38 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     500          38 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     501          38 :   keys.add("atoms","ATOMS","The atoms to be included in the calculation, e.g. the whole protein.");
+     502          38 :   keys.add("compulsory","DATADIR","data/","The folder with the experimental chemical shifts.");
+     503          38 :   keys.add("compulsory","TEMPLATE","template.pdb","A PDB file of the protein system.");
+     504          38 :   keys.add("compulsory","NEIGH_FREQ","20","Period in step for neighbor list update.");
+     505          38 :   keys.addFlag("CAMSHIFT",false,"Set to TRUE if you to calculate a single CamShift score.");
+     506          38 :   keys.addFlag("NOEXP",false,"Set to TRUE if you don't want to have fixed components with the experimental values.");
+     507          38 :   keys.addOutputComponent("ha","default","the calculated Ha hydrogen chemical shifts");
+     508          38 :   keys.addOutputComponent("hn","default","the calculated H hydrogen chemical shifts");
+     509          38 :   keys.addOutputComponent("nh","default","the calculated N nitrogen chemical shifts");
+     510          38 :   keys.addOutputComponent("ca","default","the calculated Ca carbon chemical shifts");
+     511          38 :   keys.addOutputComponent("cb","default","the calculated Cb carbon chemical shifts");
+     512          38 :   keys.addOutputComponent("co","default","the calculated C' carbon chemical shifts");
+     513          38 :   keys.addOutputComponent("expha","default","the experimental Ha hydrogen chemical shifts");
+     514          38 :   keys.addOutputComponent("exphn","default","the experimental H hydrogen chemical shifts");
+     515          38 :   keys.addOutputComponent("expnh","default","the experimental N nitrogen chemical shifts");
+     516          38 :   keys.addOutputComponent("expca","default","the experimental Ca carbon chemical shifts");
+     517          38 :   keys.addOutputComponent("expcb","default","the experimental Cb carbon chemical shifts");
+     518          38 :   keys.addOutputComponent("expco","default","the experimental C' carbon chemical shifts");
+     519          19 : }
+     520             : 
+     521          18 : CS2Backbone::CS2Backbone(const ActionOptions&ao):
+     522             :   PLUMED_METAINF_INIT(ao),
+     523          18 :   max_cs_atoms(0),
+     524          18 :   camshift(false),
+     525          18 :   pbc(true),
+     526          18 :   serial(false)
+     527             : {
+     528             :   std::vector<AtomNumber> used_atoms;
+     529          18 :   parseAtomList("ATOMS",used_atoms);
+     530             : 
+     531          18 :   parseFlag("CAMSHIFT",camshift);
+     532          18 :   if(camshift&&getDoScore()) plumed_merror("It is not possible to use CAMSHIFT and DOSCORE at the same time");
+     533             : 
+     534          18 :   bool nopbc=!pbc;
+     535          18 :   parseFlag("NOPBC",nopbc);
+     536          18 :   pbc=!nopbc;
+     537             : 
+     538          18 :   parseFlag("SERIAL",serial);
+     539             : 
+     540          18 :   bool noexp=false;
+     541          36 :   parseFlag("NOEXP",noexp);
+     542             : 
+     543             :   std::string stringa_data;
+     544          36 :   parse("DATADIR",stringa_data);
+     545             : 
+     546             :   std::string stringa_template;
+     547          18 :   parse("TEMPLATE",stringa_template);
+     548             : 
+     549          18 :   box_count=0;
+     550          18 :   box_nupdate=20;
+     551          18 :   parse("NEIGH_FREQ", box_nupdate);
+     552             : 
+     553          18 :   std::string stringadb  = stringa_data + std::string("/camshift.db");
+     554          36 :   std::string stringapdb = stringa_data + std::string("/") + stringa_template;
+     555             : 
+     556             :   /* Length conversion (parameters are tuned for angstrom) */
+     557             :   double scale=1.;
+     558          18 :   if(!plumed.getAtoms().usingNaturalUnits()) {
+     559          18 :     scale = 10.*atoms.getUnits().getLength();
+     560             :   }
+     561             : 
+     562          18 :   log.printf("  Initialization of the predictor ...\n");
+     563          18 :   db.parse(stringadb,scale);
+     564             : 
+     565          18 :   PDB pdb;
+     566          36 :   if( !pdb.read(stringapdb,plumed.getAtoms().usingNaturalUnits(),1./scale) ) plumed_merror("missing input file " + stringapdb);
+     567             : 
+     568             :   // first of all we build the list of chemical shifts we want to predict
+     569          18 :   log.printf("  Reading experimental data ...\n"); log.flush();
+     570          36 :   stringadb = stringa_data + std::string("/CAshifts.dat");
+     571          18 :   log.printf("  Initializing CA shifts %s\n", stringadb.c_str());
+     572          18 :   init_cs(stringadb, "CA", pdb);
+     573          36 :   stringadb = stringa_data + std::string("/CBshifts.dat");
+     574          18 :   log.printf("  Initializing CB shifts %s\n", stringadb.c_str());
+     575          18 :   init_cs(stringadb, "CB", pdb);
+     576          36 :   stringadb = stringa_data + std::string("/Cshifts.dat");
+     577          18 :   log.printf("  Initializing C' shifts %s\n", stringadb.c_str());
+     578          18 :   init_cs(stringadb, "C", pdb);
+     579          36 :   stringadb = stringa_data + std::string("/HAshifts.dat");
+     580          18 :   log.printf("  Initializing HA shifts %s\n", stringadb.c_str());
+     581          18 :   init_cs(stringadb, "HA", pdb);
+     582          36 :   stringadb = stringa_data + std::string("/Hshifts.dat");
+     583          18 :   log.printf("  Initializing H shifts %s\n", stringadb.c_str());
+     584          18 :   init_cs(stringadb, "H", pdb);
+     585          36 :   stringadb = stringa_data + std::string("/Nshifts.dat");
+     586          18 :   log.printf("  Initializing N shifts %s\n", stringadb.c_str());
+     587          36 :   init_cs(stringadb, "N", pdb);
+     588             : 
+     589          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)");
+     590             : 
+     591          18 :   init_types(pdb);
+     592          18 :   init_rings(pdb);
+     593             : 
+     594          18 :   log<<"  Bibliography "
+     595          36 :      <<plumed.cite("Kohlhoff K, Robustelli P, Cavalli A, Salvatella A, Vendruscolo M, J. Am. Chem. Soc. 131, 13894 (2009)");
+     596          28 :   if(camshift) log<<plumed.cite("Granata D, Camilloni C, Vendruscolo M, Laio A, Proc. Natl. Acad. Sci. USA 110, 6817 (2013)");
+     597          39 :   else log<<plumed.cite("Camilloni C, Robustelli P, De Simone A, Cavalli A, Vendruscolo M, J. Am. Chem. Soc. 134, 3968 (2012)");
+     598          36 :   log<<plumed.cite("Bonomi M, Camilloni C, Bioinformatics, 33, 3999 (2017)");
+     599          18 :   log<<"\n";
+     600             : 
+     601          18 :   if(camshift) {
+     602           5 :     noexp = true;
+     603           5 :     addValueWithDerivatives();
+     604           5 :     setNotPeriodic();
+     605             :   } else {
+     606        7670 :     for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+     607        7657 :       std::string num; Tools::convert(chemicalshifts[cs].res_num,num);
+     608        7657 :       std::string chain_num; Tools::convert(chemicalshifts[cs].chain,chain_num);
+     609        7657 :       if(getDoScore()) {
+     610        4712 :         addComponent(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     611        4712 :         componentIsNotPeriodic(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     612        2356 :         chemicalshifts[cs].comp = getPntrToComponent(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     613        4712 :         setParameter(chemicalshifts[cs].exp_cs);
+     614             :       } else {
+     615       10602 :         addComponentWithDerivatives(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     616       10602 :         componentIsNotPeriodic(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     617        5301 :         chemicalshifts[cs].comp = getPntrToComponent(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     618             :       }
+     619             :     }
+     620          13 :     if(getDoScore()) Initialise(chemicalshifts.size());
+     621             :   }
+     622             : 
+     623          18 :   if(!noexp) {
+     624        7670 :     for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+     625        7657 :       std::string num; Tools::convert(chemicalshifts[cs].res_num,num);
+     626        7657 :       std::string chain_num; Tools::convert(chemicalshifts[cs].chain,chain_num);
+     627       15314 :       addComponent("exp"+chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     628       15314 :       componentIsNotPeriodic("exp"+chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     629       15314 :       Value* comp=getPntrToComponent("exp"+chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     630        7657 :       comp->set(chemicalshifts[cs].exp_cs);
+     631             :     }
+     632             :   }
+     633             : 
+     634          18 :   requestAtoms(used_atoms, false);
+     635          18 :   setDerivatives();
+     636          18 :   checkRead();
+     637          36 : }
+     638             : 
+     639         108 : void CS2Backbone::init_cs(const std::string &file, const std::string &nucl, const PDB &pdb) {
+     640             :   // number of chains
+     641             :   std::vector<std::string> chains;
+     642         108 :   pdb.getChainNames( chains );
+     643             :   unsigned ichain=0;
+     644             : 
+     645         108 :   std::ifstream in;
+     646         108 :   in.open(file.c_str());
+     647         108 :   if(!in) return;
+     648         108 :   std::istream_iterator<std::string> iter(in), end;
+     649             :   unsigned begin=0;
+     650             : 
+     651         108 :   while(iter!=end) {
+     652       19008 :     std::string tok = *iter;
+     653             :     ++iter;
+     654       19008 :     if(tok[0]=='#') {
+     655             :       ++iter;
+     656         432 :       if(begin==1) {
+     657             :         begin=0;
+     658         216 :         ichain++;
+     659             :       } else begin=1;
+     660         432 :       continue;
+     661             :     }
+     662             :     int ro = atoi(tok.c_str());
+     663       18576 :     if(ro<0) plumed_merror("Residue numbers should be positive\n");
+     664       18576 :     unsigned resnum = static_cast<unsigned> (ro);
+     665             :     tok = *iter;
+     666             :     ++iter;
+     667             :     double cs = atof(tok.c_str());
+     668       18576 :     if(cs==0) continue;
+     669             : 
+     670             :     unsigned fres, lres;
+     671             :     std::string errmsg;
+     672       11070 :     pdb.getResidueRange(chains[ichain], fres, lres, errmsg);
+     673       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");
+     674             : 
+     675             :     // check in the PDB for the chain/residue/atom and enable the chemical shift
+     676       11070 :     std::string RES = pdb.getResidueName(resnum, chains[ichain]);
+     677       98766 :     if(RES=="HIE"||RES=="HIP"||RES=="HIS"||RES=="HSP"||RES=="HSE"||RES=="CYS"||RES=="GLH"||RES=="ASH"||RES=="UNK") continue;
+     678       10944 :     if(RES=="GLN"&&nucl=="CB") continue;
+     679       11322 :     if(RES=="ILE"&&nucl=="CB") continue;
+     680       10998 :     if(RES=="PRO"&&nucl=="N") continue;
+     681       10998 :     if(RES=="PRO"&&nucl=="H") continue;
+     682       10998 :     if(RES=="PRO"&&nucl=="CB") continue;
+     683       12240 :     if(RES=="GLY"&&nucl=="HA") continue;
+     684       12240 :     if(RES=="GLY"&&nucl=="CB") continue;
+     685             : 
+     686       10602 :     ChemicalShift tmp_cs;
+     687             : 
+     688       10602 :     tmp_cs.exp_cs = cs;
+     689       10602 :     if(nucl=="CA")      tmp_cs.nucleus = "ca-";
+     690        7668 :     else if(nucl=="CB") tmp_cs.nucleus = "cb-";
+     691        5616 :     else if(nucl=="C")  tmp_cs.nucleus = "co-";
+     692        5616 :     else if(nucl=="HA") tmp_cs.nucleus = "ha-";
+     693        5616 :     else if(nucl=="H")  tmp_cs.nucleus = "hn-";
+     694        2808 :     else if(nucl=="N")  tmp_cs.nucleus = "nh-";
+     695       10602 :     tmp_cs.chain = ichain;
+     696       10602 :     tmp_cs.res_num = resnum;
+     697       10602 :     tmp_cs.res_type_curr = frag2enum(RES);
+     698       10602 :     tmp_cs.res_type_prev = frag2enum(pdb.getResidueName(resnum-1, chains[ichain]));
+     699       10602 :     tmp_cs.res_type_next = frag2enum(pdb.getResidueName(resnum+1, chains[ichain]));
+     700             :     tmp_cs.res_name = RES;
+     701       10602 :     tmp_cs.res_kind = db.kind(RES);
+     702       10602 :     tmp_cs.atm_kind = db.atom_kind(nucl);
+     703       20556 :     if(RES!="ALA"&&RES!="GLY") {tmp_cs.bb.resize(18); tmp_cs.has_chi1=true;}
+     704        2142 :     else {tmp_cs.bb.resize(16); tmp_cs.has_chi1=false;}
+     705             : 
+     706       10602 :     std::vector<AtomNumber> res_atoms = pdb.getAtomsInResidue(resnum, chains[ichain]);
+     707             :     // find the position of the nucleus and of the other backbone atoms as well as for phi/psi/chi
+     708      173268 :     for(unsigned a=0; a<res_atoms.size(); a++) {
+     709      162666 :       std::string AN = pdb.getAtomName(res_atoms[a]);
+     710      162666 :       if(nucl=="HA"&&(AN=="HA"||AN=="HA1"||AN=="HA3")) tmp_cs.ipos = res_atoms[a].index();
+     711      244530 :       else if(nucl=="H"&&(AN=="H"||AN=="HN"))          tmp_cs.ipos = res_atoms[a].index();
+     712      202248 :       else if(nucl=="N"&&AN=="N")                      tmp_cs.ipos = res_atoms[a].index();
+     713      200862 :       else if(nucl=="CA"&&AN=="CA")                    tmp_cs.ipos = res_atoms[a].index();
+     714      188244 :       else if(nucl=="CB"&&AN=="CB")                    tmp_cs.ipos = res_atoms[a].index();
+     715      152064 :       else if(nucl=="C"&&AN=="C" )                     tmp_cs.ipos = res_atoms[a].index();
+     716             :     }
+     717             : 
+     718       10602 :     std::vector<AtomNumber> prev_res_atoms = pdb.getAtomsInResidue(resnum-1, chains[ichain]);
+     719             :     // find the position of the previous residues backbone atoms
+     720      168498 :     for(unsigned a=0; a<prev_res_atoms.size(); a++) {
+     721      157896 :       std::string AN = pdb.getAtomName(prev_res_atoms[a]);
+     722      157896 :       if(AN=="N")                             { tmp_cs.bb[Np]  = prev_res_atoms[a].index(); }
+     723      147294 :       else if(AN=="CA")                       { tmp_cs.bb[CAp] = prev_res_atoms[a].index(); }
+     724      390690 :       else if(AN=="HA"||AN=="HA1"||AN=="HA3") { tmp_cs.bb[HAp] = prev_res_atoms[a].index(); }
+     725      126090 :       else if(AN=="C" )                       { tmp_cs.bb[Cp]  = prev_res_atoms[a].index(); }
+     726      115488 :       else if(AN=="O" )                       { tmp_cs.bb[Op]  = prev_res_atoms[a].index(); }
+     727             :     }
+     728             : 
+     729      173268 :     for(unsigned a=0; a<res_atoms.size(); a++) {
+     730      162666 :       std::string AN = pdb.getAtomName(res_atoms[a]);
+     731      162666 :       if(AN=="N")                                         { tmp_cs.bb[Nc]  = res_atoms[a].index(); }
+     732      438282 :       else if(AN=="H" ||AN=="HN"||(AN=="CD"&&RES=="PRO")) { tmp_cs.bb[Hc]  = res_atoms[a].index(); }
+     733      141462 :       else if(AN=="CA")                                   { tmp_cs.bb[CAc] = res_atoms[a].index(); }
+     734      372870 :       else if(AN=="HA"||AN=="HA1"||AN=="HA3")             { tmp_cs.bb[HAc] = res_atoms[a].index(); }
+     735      120258 :       else if(AN=="C" )                                   { tmp_cs.bb[Cc]  = res_atoms[a].index(); }
+     736      109656 :       else if(AN=="O" )                                   { tmp_cs.bb[Oc]  = res_atoms[a].index(); }
+     737             : 
+     738      318852 :       if(RES!="ALA"&&RES!="GLY") {
+     739      145728 :         if(AN=="CB") tmp_cs.bb[CBc] = res_atoms[a].index();
+     740      145728 :         if(is_chi1_cx(RES,AN)) tmp_cs.bb[CGc] = res_atoms[a].index();
+     741             :       }
+     742             :     }
+     743             : 
+     744       10602 :     std::vector<AtomNumber> next_res_atoms = pdb.getAtomsInResidue(resnum+1, chains[ichain]);
+     745       10602 :     std::string NRES = pdb.getResidueName(resnum+1, chains[ichain]);
+     746             :     // find the position of the previous residues backbone atoms
+     747      168948 :     for(unsigned a=0; a<next_res_atoms.size(); a++) {
+     748      158346 :       std::string AN = pdb.getAtomName(next_res_atoms[a]);
+     749      158346 :       if(AN=="N")                                          { tmp_cs.bb[Nn]  = next_res_atoms[a].index(); }
+     750      426096 :       else if(AN=="H" ||AN=="HN"||(AN=="CD"&&NRES=="PRO")) { tmp_cs.bb[Hn]  = next_res_atoms[a].index(); }
+     751      137142 :       else if(AN=="CA")                                    { tmp_cs.bb[CAn] = next_res_atoms[a].index(); }
+     752      360198 :       else if(AN=="HA"||AN=="HA1"||AN=="HA3")              { tmp_cs.bb[HAn] = next_res_atoms[a].index(); }
+     753      115938 :       else if(AN=="C" )                                    { tmp_cs.bb[Cn]  = next_res_atoms[a].index(); }
+     754             :     }
+     755             : 
+     756             :     // set sidechain atoms
+     757       10602 :     std::vector<std::string> sc_atm = side_chain_atoms(RES);
+     758             : 
+     759      141084 :     for(unsigned sc=0; sc<sc_atm.size(); sc++) {
+     760     2501208 :       for(unsigned aa=0; aa<res_atoms.size(); aa++) {
+     761     2370726 :         if(pdb.getAtomName(res_atoms[aa])==sc_atm[sc]) {
+     762       99162 :           tmp_cs.side_chain.push_back(res_atoms[aa].index());
+     763             :         }
+     764             :       }
+     765             :     }
+     766             : 
+     767             :     // find atoms for extra distances
+     768      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"};
+     769       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};
+     770             : 
+     771      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"};
+     772       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};
+     773             : 
+     774      286254 :     for(unsigned q=0; q<db.get_numXtraDists()-1; q++) {
+     775             :       std::vector<AtomNumber> at1;
+     776      275652 :       if(resOffsetP1[q]== 0) at1 = res_atoms;
+     777      275652 :       if(resOffsetP1[q]==-1) at1 = prev_res_atoms;
+     778      275652 :       if(resOffsetP1[q]==+1) at1 = next_res_atoms;
+     779             : 
+     780             :       std::vector<AtomNumber> at2;
+     781      275652 :       if(resOffsetP2[q]== 0) at2 = res_atoms;
+     782      275652 :       if(resOffsetP2[q]==-1) at2 = prev_res_atoms;
+     783      275652 :       if(resOffsetP2[q]==+1) at2 = next_res_atoms;
+     784             : 
+     785      275652 :       int tmp1 = -1;
+     786     2197566 :       for(unsigned a=0; a<at1.size(); a++) {
+     787     2181708 :         std::string name = pdb.getAtomName(at1[a]);
+     788     2181708 :         xdist_name_map(name);
+     789             : 
+     790     2181708 :         if(name==atomsP1[q]) {
+     791      259794 :           tmp1 = at1[a].index();
+     792             :           break;
+     793             :         }
+     794             :       }
+     795             : 
+     796      275652 :       int tmp2 = -1;
+     797     1427688 :       for(unsigned a=0; a<at2.size(); a++) {
+     798     1418076 :         std::string name = pdb.getAtomName(at2[a]);
+     799     1418076 :         xdist_name_map(name);
+     800             : 
+     801     1418076 :         if(name==atomsP2[q]) {
+     802      266040 :           tmp2 = at2[a].index();
+     803             :           break;
+     804             :         }
+     805             :       }
+     806             : 
+     807      275652 :       tmp_cs.xd1.push_back(tmp1);
+     808      275652 :       tmp_cs.xd2.push_back(tmp2);
+     809             :     }
+     810             : 
+     811             :     // ready to add a new chemical shifts
+     812       10602 :     tmp_cs.csatoms = 1 + 16 + tmp_cs.side_chain.size() + 2*tmp_cs.xd1.size();
+     813       20556 :     if(tmp_cs.res_name!="ALA"&&tmp_cs.res_name!="GLY") tmp_cs.csatoms += 2;
+     814       10602 :     chemicalshifts.push_back(tmp_cs);
+     815      593712 :   }
+     816             : 
+     817         108 :   in.close();
+     818         108 : }
+     819             : 
+     820             : // this assigns an atom-type to each atom of the pdb
+     821          18 : void CS2Backbone::init_types(const PDB &pdb) {
+     822             :   enum atom_t {D_C, D_H, D_N, D_O, D_S, D_C2, D_N2, D_O2};
+     823          18 :   std::vector<AtomNumber> aa = pdb.getAtomNumbers();
+     824       47034 :   for(unsigned i=0; i<aa.size(); i++) {
+     825       47016 :     unsigned frag = pdb.getResidueNumber(aa[i]);
+     826       47016 :     std::string fragName = pdb.getResidueName(aa[i]);
+     827       47016 :     std::string atom_name = pdb.getAtomName(aa[i]);
+     828       47016 :     char atom_type = atom_name[0];
+     829       47016 :     if(isdigit(atom_name[0])) atom_type = atom_name[1];
+     830       47016 :     res_num.push_back(frag);
+     831       47016 :     unsigned t = 0;
+     832       47016 :     if (!isSP2(fragName, atom_name)) {
+     833             :       if (atom_type == 'C') t = D_C;
+     834         468 :       else if (atom_type == 'O') t = D_O;
+     835       23256 :       else if (atom_type == 'H') t = D_H;
+     836        4032 :       else if (atom_type == 'N') t = D_N;
+     837         162 :       else if (atom_type == 'S') t = D_S;
+     838           0 :       else plumed_merror("Unknown atom type: " + atom_name);
+     839             :     } else {
+     840       10080 :       if (atom_type == 'C') t = D_C2;
+     841        4104 :       else if (atom_type == 'O') t = D_O2;
+     842           0 :       else if (atom_type == 'N') t = D_N2;
+     843           0 :       else plumed_merror("Unknown atom type: " + atom_name);
+     844             :     }
+     845       47016 :     type.push_back(t);
+     846             :   }
+     847          18 : }
+     848             : 
+     849          18 : void CS2Backbone::init_rings(const PDB &pdb)
+     850             : {
+     851         126 :   const std::string pheTyr_n[] = {"CG","CD1","CE1","CZ","CE2","CD2"};
+     852         126 :   const std::string trp1_n[]   = {"CD2","CE2","CZ2","CH2","CZ3","CE3"};
+     853         108 :   const std::string trp2_n[]   = {"CG","CD1","NE1","CE2","CD2"};
+     854         108 :   const std::string his_n[]    = {"CG","ND1","CD2","CE1","NE2"};
+     855             : 
+     856             :   // number of chains
+     857             :   std::vector<std::string> chains;
+     858          18 :   pdb.getChainNames( chains );
+     859             :   unsigned total_rings_atoms = 0;
+     860             : 
+     861             :   // cycle over chains
+     862          54 :   for(unsigned i=0; i<chains.size(); i++) {
+     863             :     unsigned start, end;
+     864             :     std::string errmsg;
+     865          36 :     pdb.getResidueRange( chains[i], start, end, errmsg );
+     866             :     // cycle over residues
+     867        3168 :     for(unsigned res=start; res<end; res++) {
+     868        3132 :       std::string frg = pdb.getResidueName(res, chains[i]);
+     869       14364 :       if(!((frg=="PHE")||(frg=="TYR")||(frg=="TRP")||
+     870        8370 :            (frg=="HIS")||(frg=="HIP")||(frg=="HID")||
+     871        5580 :            (frg=="HIE")||(frg=="HSD")||(frg=="HSE")||
+     872             :            (frg=="HSP"))) continue;
+     873             : 
+     874         342 :       std::vector<AtomNumber> frg_atoms = pdb.getAtomsInResidue(res,chains[i]);
+     875             : 
+     876         396 :       if(frg=="PHE"||frg=="TYR") {
+     877         324 :         RingInfo ri;
+     878        6840 :         for(unsigned a=0; a<frg_atoms.size(); a++) {
+     879             :           unsigned atm = frg_atoms[a].index();
+     880       38808 :           for(unsigned aa=0; aa<6; aa++) {
+     881       34236 :             if(pdb.getAtomName(frg_atoms[a])==pheTyr_n[aa]) {
+     882        1944 :               ri.atom[aa] = atm;
+     883        1944 :               break;
+     884             :             }
+     885             :           }
+     886             :         }
+     887         324 :         ri.numAtoms = 6;
+     888         324 :         total_rings_atoms += 6;
+     889         324 :         if(frg=="PHE") ri.rtype = RingInfo::R_PHE;
+     890         324 :         if(frg=="TYR") ri.rtype = RingInfo::R_TYR;
+     891         324 :         ringInfo.push_back(ri);
+     892             : 
+     893          18 :       } else if(frg=="TRP") {
+     894             :         //First ring
+     895          18 :         RingInfo ri;
+     896         450 :         for(unsigned a=0; a<frg_atoms.size(); a++) {
+     897             :           unsigned atm = frg_atoms[a].index();
+     898        2646 :           for(unsigned aa=0; aa<6; aa++) {
+     899        2322 :             if(pdb.getAtomName(frg_atoms[a])==trp1_n[aa]) {
+     900         108 :               ri.atom[aa] = atm;
+     901         108 :               break;
+     902             :             }
+     903             :           }
+     904             :         }
+     905          18 :         ri.numAtoms = 6;
+     906             :         total_rings_atoms += 6;
+     907          18 :         ri.rtype = RingInfo::R_TRP1;
+     908          18 :         ringInfo.push_back(ri);
+     909             :         //Second Ring
+     910          18 :         RingInfo ri2;
+     911         450 :         for(unsigned a=0; a<frg_atoms.size(); a++) {
+     912             :           unsigned atm = frg_atoms[a].index();
+     913        2322 :           for(unsigned aa=0; aa<5; aa++) {
+     914        1980 :             if(pdb.getAtomName(frg_atoms[a])==trp2_n[aa]) {
+     915          90 :               ri2.atom[aa] = atm;
+     916          90 :               break;
+     917             :             }
+     918             :           }
+     919             :         }
+     920          18 :         ri2.numAtoms = 5;
+     921          18 :         total_rings_atoms += 3;
+     922          18 :         ri2.rtype = RingInfo::R_TRP2;
+     923          18 :         ringInfo.push_back(ri2);
+     924             : 
+     925           0 :       } else if((frg=="HIS")||(frg=="HIP")||(frg=="HID")||
+     926           0 :                 (frg=="HIE")||(frg=="HSD")||(frg=="HSE")||
+     927             :                 (frg=="HSP")) {//HIS case
+     928           0 :         RingInfo ri;
+     929           0 :         for(unsigned a=0; a<frg_atoms.size(); a++) {
+     930             :           unsigned atm = frg_atoms[a].index();
+     931           0 :           for(unsigned aa=0; aa<5; aa++) {
+     932           0 :             if(pdb.getAtomName(frg_atoms[a])==his_n[aa]) {
+     933           0 :               ri.atom[aa] = atm;
+     934           0 :               break;
+     935             :             }
+     936             :           }
+     937             :         }
+     938           0 :         ri.numAtoms = 5;
+     939           0 :         total_rings_atoms += 3;
+     940           0 :         ri.rtype = RingInfo::R_HIS;
+     941           0 :         ringInfo.push_back(ri);
+     942             :       } else {
+     943           0 :         plumed_merror("Unknown Ring Fragment: " + frg);
+     944             :       }
+     945             :     }
+     946             :   }
+     947             : 
+     948       10620 :   for(unsigned cs=0; cs<chemicalshifts.size(); cs++) chemicalshifts[cs].csatoms += total_rings_atoms;
+     949         486 : }
+     950             : 
+     951          18 : void CS2Backbone::calculate()
+     952             : {
+     953          18 :   if(pbc) makeWhole();
+     954          18 :   if(getExchangeStep()) box_count=0;
+     955          18 :   if(box_count==0) update_neighb();
+     956          18 :   compute_ring_parameters();
+     957             : 
+     958          18 :   std::vector<double> camshift_sigma2(6);
+     959          18 :   camshift_sigma2[0] = 0.08; // HA
+     960          18 :   camshift_sigma2[1] = 0.30; // HN
+     961          18 :   camshift_sigma2[2] = 9.00; // NH
+     962          18 :   camshift_sigma2[3] = 1.30; // CA
+     963          18 :   camshift_sigma2[4] = 1.56; // CB
+     964          18 :   camshift_sigma2[5] = 1.70; // CO
+     965             : 
+     966             :   std::vector<Vector>   cs_derivs;
+     967             :   std::vector<Vector>   aa_derivs;
+     968             :   std::vector<unsigned> cs_atoms;
+     969             :   std::vector<double>   all_shifts;
+     970             : 
+     971          18 :   cs_derivs.resize(chemicalshifts.size()*max_cs_atoms,Vector(0,0,0));
+     972          18 :   cs_atoms.resize(chemicalshifts.size()*max_cs_atoms,0);
+     973          18 :   all_shifts.resize(chemicalshifts.size(),0);
+     974          18 :   if(camshift||getDoScore()) aa_derivs.resize(getNumberOfAtoms(),Vector(0,0,0));
+     975             : 
+     976          18 :   unsigned stride = comm.Get_size();
+     977          18 :   unsigned rank   = comm.Get_rank();
+     978          18 :   if(serial) {
+     979             :     stride = 1;
+     980             :     rank   = 0;
+     981             :   }
+     982             : 
+     983          18 :   unsigned nt=OpenMP::getNumThreads();
+     984          18 :   if(nt*stride*2>chemicalshifts.size()) nt=1;
+     985             : 
+     986             :   // a single loop over all chemical shifts
+     987          18 :   #pragma omp parallel num_threads(nt)
+     988             :   {
+     989             :     #pragma omp for schedule(dynamic)
+     990             :     for(unsigned cs=rank; cs<chemicalshifts.size(); cs+=stride) {
+     991             :       const unsigned kdx=cs*max_cs_atoms;
+     992             :       const ChemicalShift *myfrag = &chemicalshifts[cs];
+     993             :       const unsigned aa_kind = myfrag->res_kind;
+     994             :       const unsigned at_kind = myfrag->atm_kind;
+     995             : 
+     996             :       double shift = db.CONSTAAPREV(aa_kind,at_kind)[myfrag->res_type_prev] +
+     997             :                      db.CONSTAACURR(aa_kind,at_kind)[myfrag->res_type_curr] +
+     998             :                      db.CONSTAANEXT(aa_kind,at_kind)[myfrag->res_type_next];
+     999             : 
+    1000             :       const unsigned ipos = myfrag->ipos;
+    1001             :       cs_atoms[kdx+0] = ipos;
+    1002             :       unsigned atom_counter = 1;
+    1003             : 
+    1004             :       //BACKBONE (PREV CURR NEXT)
+    1005             :       const double * CONST_BB2 = db.CONST_BB2(aa_kind,at_kind);
+    1006             :       const unsigned bbsize = 16;
+    1007             :       for(unsigned q=0; q<bbsize; q++) {
+    1008             :         const double cb2q = CONST_BB2[q];
+    1009             :         if(cb2q==0.) continue;
+    1010             :         const unsigned jpos = myfrag->bb[q];
+    1011             :         if(ipos==jpos) continue;
+    1012             :         const Vector distance = delta(getPosition(jpos),getPosition(ipos));
+    1013             :         const double d = distance.modulo();
+    1014             :         const double fact = cb2q/d;
+    1015             : 
+    1016             :         shift += cb2q*d;
+    1017             :         const Vector der = fact*distance;
+    1018             : 
+    1019             :         cs_derivs[kdx+0] += der;
+    1020             :         cs_derivs[kdx+q+atom_counter] = -der;
+    1021             :         cs_atoms[kdx+q+atom_counter] = jpos;
+    1022             :       }
+    1023             : 
+    1024             :       atom_counter += bbsize;
+    1025             : 
+    1026             :       //DIHEDRAL ANGLES
+    1027             :       const double *CO_DA = db.CO_DA(aa_kind,at_kind);
+    1028             :       //Phi
+    1029             :       {
+    1030             :         const Vector d0 = delta(getPosition(myfrag->bb[Nc]), getPosition(myfrag->bb[Cp]));
+    1031             :         const Vector d1 = delta(getPosition(myfrag->bb[CAc]), getPosition(myfrag->bb[Nc]));
+    1032             :         const Vector d2 = delta(getPosition(myfrag->bb[Cc]), getPosition(myfrag->bb[CAc]));
+    1033             :         Torsion t;
+    1034             :         Vector dd0, dd1, dd2;
+    1035             :         const double t_phi = t.compute(d0,d1,d2,dd0,dd1,dd2);
+    1036             :         const double *PARS_DA = db.PARS_DA(aa_kind,at_kind,0);
+    1037             :         const double val1 = 3.*t_phi+PARS_DA[3];
+    1038             :         const double val2 = t_phi+PARS_DA[4];
+    1039             :         shift += CO_DA[0]*(PARS_DA[0]*std::cos(val1)+PARS_DA[1]*std::cos(val2)+PARS_DA[2]);
+    1040             :         const double fact = -CO_DA[0]*(+3.*PARS_DA[0]*std::sin(val1)+PARS_DA[1]*std::sin(val2));
+    1041             : 
+    1042             :         cs_derivs[kdx+Cp+1] += fact*dd0;
+    1043             :         cs_derivs[kdx+Nc+1] += fact*(dd1-dd0);
+    1044             :         cs_derivs[kdx+CAc+1]+= fact*(dd2-dd1);
+    1045             :         cs_derivs[kdx+Cc+1] += -fact*dd2;
+    1046             :         cs_atoms[kdx+Cp+1] = myfrag->bb[Cp];
+    1047             :         cs_atoms[kdx+Nc+1] = myfrag->bb[Nc];
+    1048             :         cs_atoms[kdx+CAc+1]= myfrag->bb[CAc];
+    1049             :         cs_atoms[kdx+Cc+1] = myfrag->bb[Cc];
+    1050             :       }
+    1051             : 
+    1052             :       //Psi
+    1053             :       {
+    1054             :         const Vector d0 = delta(getPosition(myfrag->bb[CAc]), getPosition(myfrag->bb[Nc]));
+    1055             :         const Vector d1 = delta(getPosition(myfrag->bb[Cc]), getPosition(myfrag->bb[CAc]));
+    1056             :         const Vector d2 = delta(getPosition(myfrag->bb[Nn]), getPosition(myfrag->bb[Cc]));
+    1057             :         Torsion t;
+    1058             :         Vector dd0, dd1, dd2;
+    1059             :         const double t_psi = t.compute(d0,d1,d2,dd0,dd1,dd2);
+    1060             :         const double *PARS_DA = db.PARS_DA(aa_kind,at_kind,1);
+    1061             :         const double val1 = 3.*t_psi+PARS_DA[3];
+    1062             :         const double val2 = t_psi+PARS_DA[4];
+    1063             :         shift += CO_DA[1]*(PARS_DA[0]*std::cos(val1)+PARS_DA[1]*std::cos(val2)+PARS_DA[2]);
+    1064             :         const double fact = -CO_DA[1]*(+3.*PARS_DA[0]*std::sin(val1)+PARS_DA[1]*std::sin(val2));
+    1065             : 
+    1066             :         cs_derivs[kdx+Nc+1] += fact*dd0;
+    1067             :         cs_derivs[kdx+CAc+1] += fact*(dd1-dd0);
+    1068             :         cs_derivs[kdx+Cc+1] += fact*(dd2-dd1);
+    1069             :         cs_derivs[kdx+Nn+1] += -fact*dd2;
+    1070             :         cs_atoms[kdx+Nc+1] = myfrag->bb[Nc];
+    1071             :         cs_atoms[kdx+CAc+1]= myfrag->bb[CAc];
+    1072             :         cs_atoms[kdx+Cc+1] = myfrag->bb[Cc];
+    1073             :         cs_atoms[kdx+Nn+1] = myfrag->bb[Nn];
+    1074             :       }
+    1075             : 
+    1076             :       //Chi
+    1077             :       if(myfrag->has_chi1) {
+    1078             :         const Vector d0 = delta(getPosition(myfrag->bb[CAc]), getPosition(myfrag->bb[Nc]));
+    1079             :         const Vector d1 = delta(getPosition(myfrag->bb[CBc]), getPosition(myfrag->bb[CAc]));
+    1080             :         const Vector d2 = delta(getPosition(myfrag->bb[CGc]), getPosition(myfrag->bb[CBc]));
+    1081             :         Torsion t;
+    1082             :         Vector dd0, dd1, dd2;
+    1083             :         const double t_chi1 = t.compute(d0,d1,d2,dd0,dd1,dd2);
+    1084             :         const double *PARS_DA = db.PARS_DA(aa_kind,at_kind,2);
+    1085             :         const double val1 = 3.*t_chi1+PARS_DA[3];
+    1086             :         const double val2 = t_chi1+PARS_DA[4];
+    1087             :         shift += CO_DA[2]*(PARS_DA[0]*std::cos(val1)+PARS_DA[1]*std::cos(val2)+PARS_DA[2]);
+    1088             :         const double fact = -CO_DA[2]*(+3.*PARS_DA[0]*std::sin(val1)+PARS_DA[1]*std::sin(val2));
+    1089             : 
+    1090             :         cs_derivs[kdx+Nc+1] += fact*dd0;
+    1091             :         cs_derivs[kdx+CAc+1] += fact*(dd1-dd0);
+    1092             :         cs_derivs[kdx+CBc+1] += fact*(dd2-dd1);
+    1093             :         cs_derivs[kdx+CGc+1] += -fact*dd2;
+    1094             :         cs_atoms[kdx+Nc+1]  = myfrag->bb[Nc];
+    1095             :         cs_atoms[kdx+CAc+1] = myfrag->bb[CAc];
+    1096             :         cs_atoms[kdx+CBc+1] = myfrag->bb[CBc];
+    1097             :         cs_atoms[kdx+CGc+1] = myfrag->bb[CGc];
+    1098             : 
+    1099             :         atom_counter += 2;
+    1100             :       }
+    1101             :       //END OF DIHE
+    1102             : 
+    1103             :       //SIDE CHAIN
+    1104             :       const double * CONST_SC2 = db.CONST_SC2(aa_kind,at_kind,myfrag->res_type_curr);
+    1105             :       const unsigned sidsize = myfrag->side_chain.size();
+    1106             :       for(unsigned q=0; q<sidsize; q++) {
+    1107             :         const double cs2q = CONST_SC2[q];
+    1108             :         if(cs2q==0.) continue;
+    1109             :         const unsigned jpos = myfrag->side_chain[q];
+    1110             :         if(ipos==jpos) continue;
+    1111             :         const Vector distance = delta(getPosition(jpos),getPosition(ipos));
+    1112             :         const double d = distance.modulo();
+    1113             :         const double fact = cs2q/d;
+    1114             : 
+    1115             :         shift += cs2q*d;
+    1116             :         const Vector der = fact*distance;
+    1117             :         cs_derivs[kdx+0] += der;
+    1118             :         cs_derivs[kdx+q+atom_counter] = -der;
+    1119             :         cs_atoms[kdx+q+atom_counter] = jpos;
+    1120             :       }
+    1121             : 
+    1122             :       atom_counter += sidsize;
+    1123             : 
+    1124             :       //EXTRA DIST
+    1125             :       const double * CONST_XD  = db.CONST_XD(aa_kind,at_kind);
+    1126             :       const unsigned xdsize=myfrag->xd1.size();
+    1127             :       for(unsigned q=0; q<xdsize; q++) {
+    1128             :         const double cxdq = CONST_XD[q];
+    1129             :         if(cxdq==0.) continue;
+    1130             :         if(myfrag->xd1[q]==-1||myfrag->xd2[q]==-1) continue;
+    1131             :         const Vector distance = delta(getPosition(myfrag->xd1[q]),getPosition(myfrag->xd2[q]));
+    1132             :         const double d = distance.modulo();
+    1133             :         const double fact = cxdq/d;
+    1134             : 
+    1135             :         shift += cxdq*d;
+    1136             :         const Vector der = fact*distance;
+    1137             :         cs_derivs[kdx+2*q+atom_counter  ] = der;
+    1138             :         cs_derivs[kdx+2*q+atom_counter+1] = -der;
+    1139             :         cs_atoms[kdx+2*q+atom_counter] = myfrag->xd2[q];
+    1140             :         cs_atoms[kdx+2*q+atom_counter+1] = myfrag->xd1[q];
+    1141             :       }
+    1142             : 
+    1143             :       atom_counter += 2*xdsize;
+    1144             : 
+    1145             :       //RINGS
+    1146             :       const double *rc = db.CO_RING(aa_kind,at_kind);
+    1147             :       const unsigned rsize = ringInfo.size();
+    1148             :       // cycle over the list of rings
+    1149             :       for(unsigned q=0; q<rsize; q++) {
+    1150             :         // compute angle from ring middle point to current atom position
+    1151             :         // get distance std::vector from query atom to ring center and normal std::vector to ring plane
+    1152             :         const Vector n   = ringInfo[q].normVect;
+    1153             :         const double nL  = ringInfo[q].lengthNV;
+    1154             :         const double inL2 = ringInfo[q].lengthN2;
+    1155             : 
+    1156             :         const Vector d = delta(ringInfo[q].position, getPosition(ipos));
+    1157             :         const double dL2 = d.modulo2();
+    1158             :         double dL  = std::sqrt(dL2);
+    1159             :         const double idL3 = 1./(dL2*dL);
+    1160             : 
+    1161             :         const double dn    = dotProduct(d,n);
+    1162             :         const double dn2   = dn*dn;
+    1163             :         const double dLnL  = dL*nL;
+    1164             :         const double dL_nL = dL/nL;
+    1165             : 
+    1166             :         const double ang2 = dn2*inL2/dL2;
+    1167             :         const double u    = 1.-3.*ang2;
+    1168             :         const double cc   = rc[ringInfo[q].rtype];
+    1169             : 
+    1170             :         shift += cc*u*idL3;
+    1171             : 
+    1172             :         const double fUU    = -6.*dn*inL2;
+    1173             :         const double fUQ    = fUU/dL;
+    1174             :         const Vector gradUQ = fUQ*(dL2*n - dn*d);
+    1175             :         const Vector gradVQ = (3.*dL*u)*d;
+    1176             : 
+    1177             :         const double fact   = cc*idL3*idL3;
+    1178             :         cs_derivs[kdx+0] += fact*(gradUQ - gradVQ);
+    1179             : 
+    1180             :         const double fU       = fUU/nL;
+    1181             :         double OneOverN = 1./6.;
+    1182             :         if(ringInfo[q].numAtoms==5) OneOverN=1./3.;
+    1183             :         const Vector factor2  = OneOverN*n;
+    1184             :         const Vector factor4  = (OneOverN/dL_nL)*d;
+    1185             : 
+    1186             :         const Vector gradV    = -OneOverN*gradVQ;
+    1187             : 
+    1188             :         if(ringInfo[q].numAtoms==6) {
+    1189             :           // update forces on ring atoms
+    1190             :           for(unsigned at=0; at<6; at++) {
+    1191             :             const Vector ab = crossProduct(d,ringInfo[q].g[at]);
+    1192             :             const Vector c  = crossProduct(n,ringInfo[q].g[at]);
+    1193             :             const Vector factor3 = 0.5*dL_nL*c;
+    1194             :             const Vector factor1 = 0.5*ab;
+    1195             :             const Vector gradU   = fU*( dLnL*(factor1 - factor2) -dn*(factor3 - factor4) );
+    1196             :             cs_derivs[kdx+at+atom_counter] = fact*(gradU - gradV);
+    1197             :             cs_atoms[kdx+at+atom_counter] = ringInfo[q].atom[at];
+    1198             :           }
+    1199             :           atom_counter += 6;
+    1200             :         }  else {
+    1201             :           for(unsigned at=0; at<3; at++) {
+    1202             :             const Vector ab = crossProduct(d,ringInfo[q].g[at]);
+    1203             :             const Vector c  = crossProduct(n,ringInfo[q].g[at]);
+    1204             :             const Vector factor3 = dL_nL*c;
+    1205             :             const Vector factor1 = ab;
+    1206             :             const Vector gradU   = fU*( dLnL*(factor1 - factor2) -dn*(factor3 - factor4) );
+    1207             :             cs_derivs[kdx+at+atom_counter] = fact*(gradU - gradV);
+    1208             :           }
+    1209             :           cs_atoms[kdx+atom_counter] = ringInfo[q].atom[0];
+    1210             :           cs_atoms[kdx+atom_counter+1] = ringInfo[q].atom[2];
+    1211             :           cs_atoms[kdx+atom_counter+2] = ringInfo[q].atom[3];
+    1212             :           atom_counter += 3;
+    1213             :         }
+    1214             :       }
+    1215             :       //END OF RINGS
+    1216             : 
+    1217             :       //NON BOND
+    1218             :       const double * CONST_CO_SPHERE3 = db.CO_SPHERE(aa_kind,at_kind,0);
+    1219             :       const double * CONST_CO_SPHERE  = db.CO_SPHERE(aa_kind,at_kind,1);
+    1220             :       const unsigned boxsize = myfrag->box_nb.size();
+    1221             :       for(unsigned q=0; q<boxsize; q++) {
+    1222             :         const unsigned jpos = myfrag->box_nb[q];
+    1223             :         const Vector distance = delta(getPosition(jpos),getPosition(ipos));
+    1224             :         const double d2 = distance.modulo2();
+    1225             : 
+    1226             :         if(d2<cutOffDist2) {
+    1227             :           double factor1  = std::sqrt(d2);
+    1228             :           double dfactor1 = 1./factor1;
+    1229             :           double factor3  = dfactor1*dfactor1*dfactor1;
+    1230             :           double dfactor3 = -3.*factor3*dfactor1*dfactor1;
+    1231             : 
+    1232             :           if(d2>cutOnDist2) {
+    1233             :             const double af = cutOffDist2 - d2;
+    1234             :             const double bf = cutOffDist2 - 3.*cutOnDist2 + 2.*d2;
+    1235             :             const double cf = invswitch*af;
+    1236             :             const double df = cf*af*bf;
+    1237             :             factor1 *= df;
+    1238             :             factor3 *= df;
+    1239             : 
+    1240             :             const double d4  = d2*d2;
+    1241             :             const double af1 = 15.*cutOnDist2*d2;
+    1242             :             const double bf1 = -14.*d4;
+    1243             :             const double cf1 = -3.*cutOffDist2*cutOnDist2 + cutOffDist2*d2;
+    1244             :             const double df1 = af1+bf1+cf1;
+    1245             :             dfactor1 *= cf*(cutOffDist4+df1);
+    1246             : 
+    1247             :             const double af3 = +2.*cutOffDist2*cutOnDist2;
+    1248             :             const double bf3 = d2*(cutOffDist2+cutOnDist2);
+    1249             :             const double cf3 = -2.*d4;
+    1250             :             const double df3 = (af3+bf3+cf3)*d2;
+    1251             :             dfactor3 *= invswitch*(cutMixed+df3);
+    1252             :           }
+    1253             : 
+    1254             :           const unsigned t = type[jpos];
+    1255             :           shift += factor1*CONST_CO_SPHERE[t] + factor3*CONST_CO_SPHERE3[t] ;
+    1256             :           const double fact = dfactor1*CONST_CO_SPHERE[t]+dfactor3*CONST_CO_SPHERE3[t];
+    1257             :           const Vector der  = fact*distance;
+    1258             : 
+    1259             :           cs_derivs[kdx+0] += der;
+    1260             :           cs_derivs[kdx+q+atom_counter] = -der;
+    1261             :           cs_atoms[kdx+q+atom_counter] = jpos;
+    1262             :         }
+    1263             :       }
+    1264             :       //END NON BOND
+    1265             : 
+    1266             :       atom_counter += boxsize;
+    1267             :       all_shifts[cs] = shift;
+    1268             :     }
+    1269             :   }
+    1270             : 
+    1271          18 :   ++box_count;
+    1272          18 :   if(box_count == box_nupdate) box_count = 0;
+    1273             : 
+    1274          18 :   if(!camshift) {
+    1275          13 :     if(!serial) {
+    1276          13 :       if(!getDoScore()) {
+    1277           9 :         comm.Sum(&cs_derivs[0][0], 3*cs_derivs.size());
+    1278           9 :         comm.Sum(&cs_atoms[0], cs_atoms.size());
+    1279             :       }
+    1280          13 :       comm.Sum(&all_shifts[0], chemicalshifts.size());
+    1281             :     }
+    1282        7670 :     for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+    1283        7657 :       Value *comp = chemicalshifts[cs].comp;
+    1284        7657 :       comp->set(all_shifts[cs]);
+    1285        7657 :       if(getDoScore()) setCalcData(cs, all_shifts[cs]);
+    1286             :       else {
+    1287        5301 :         const unsigned kdx=cs*max_cs_atoms;
+    1288        5301 :         Tensor csvirial;
+    1289     1270127 :         for(unsigned i=0; i<chemicalshifts[cs].totcsatoms; i++) {
+    1290     1264826 :           setAtomsDerivatives(comp,cs_atoms[kdx+i],cs_derivs[kdx+i]);
+    1291     1264826 :           csvirial-=Tensor(getPosition(cs_atoms[kdx+i]),cs_derivs[kdx+i]);
+    1292             :         }
+    1293        5301 :         setBoxDerivatives(comp,csvirial);
+    1294             :       }
+    1295             :     }
+    1296          13 :     if(!getDoScore()) return;
+    1297             :   }
+    1298             : 
+    1299           9 :   double score = 0.;
+    1300             : 
+    1301             :   /* Metainference */
+    1302           9 :   if(getDoScore()) {
+    1303           4 :     score = getScore();
+    1304        1182 :     for(unsigned cs=rank; cs<chemicalshifts.size(); cs+=stride) {
+    1305        1178 :       const unsigned kdx=cs*max_cs_atoms;
+    1306             :       const double fact = getMetaDer(cs);
+    1307      282215 :       for(unsigned i=0; i<chemicalshifts[cs].totcsatoms; i++) {
+    1308      281037 :         aa_derivs[cs_atoms[kdx+i]] += cs_derivs[kdx+i]*fact;
+    1309             :       }
+    1310             :     }
+    1311             :   }
+    1312             : 
+    1313             :   /* camshift */
+    1314           9 :   if(camshift) {
+    1315        1772 :     for(unsigned cs=rank; cs<chemicalshifts.size(); cs+=stride) {
+    1316        1767 :       const unsigned kdx=cs*max_cs_atoms;
+    1317        1767 :       score += (all_shifts[cs] - chemicalshifts[cs].exp_cs)*(all_shifts[cs] - chemicalshifts[cs].exp_cs)/camshift_sigma2[chemicalshifts[cs].atm_kind];
+    1318        1767 :       double fact = 2.0*(all_shifts[cs] - chemicalshifts[cs].exp_cs)/camshift_sigma2[chemicalshifts[cs].atm_kind];
+    1319      423482 :       for(unsigned i=0; i<chemicalshifts[cs].totcsatoms; i++) {
+    1320      421715 :         aa_derivs[cs_atoms[kdx+i]] += cs_derivs[kdx+i]*fact;
+    1321             :       }
+    1322             :     }
+    1323             :   }
+    1324             : 
+    1325           9 :   if(!serial) {
+    1326           9 :     comm.Sum(&aa_derivs[0][0], 3*aa_derivs.size());
+    1327           9 :     if(camshift) comm.Sum(&score, 1);
+    1328             :   }
+    1329             : 
+    1330           9 :   Tensor virial;
+    1331       13069 :   for(unsigned i=rank; i<getNumberOfAtoms(); i+=stride) {
+    1332       13060 :     virial += Tensor(getPosition(i), aa_derivs[i]);
+    1333             :   }
+    1334             : 
+    1335           9 :   if(!serial) {
+    1336           9 :     comm.Sum(&virial[0][0], 9);
+    1337             :   }
+    1338             : 
+    1339             :   /* calculate final derivatives */
+    1340             :   Value* val;
+    1341           9 :   if(getDoScore()) {
+    1342           4 :     val=getPntrToComponent("score");
+    1343           4 :     setScore(score);
+    1344             :   } else {
+    1345           5 :     val=getPntrToValue();
+    1346           5 :     setValue(score);
+    1347             :   }
+    1348             : 
+    1349             :   /* at this point we cycle over all atoms */
+    1350       23517 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) setAtomsDerivatives(val, i,  aa_derivs[i]);
+    1351           9 :   setBoxDerivatives(val,-virial);
+    1352             : }
+    1353             : 
+    1354          18 : void CS2Backbone::update_neighb() {
+    1355             :   // cycle over chemical shifts
+    1356          18 :   unsigned nt=OpenMP::getNumThreads();
+    1357          18 :   #pragma omp parallel for num_threads(nt)
+    1358             :   for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+    1359             :     const unsigned boxsize = getNumberOfAtoms();
+    1360             :     chemicalshifts[cs].box_nb.clear();
+    1361             :     chemicalshifts[cs].box_nb.reserve(150);
+    1362             :     const unsigned res_curr = res_num[chemicalshifts[cs].ipos];
+    1363             :     for(unsigned bat=0; bat<boxsize; bat++) {
+    1364             :       const unsigned res_dist = std::abs(static_cast<int>(res_curr-res_num[bat]));
+    1365             :       if(res_dist<2) continue;
+    1366             :       const Vector distance = delta(getPosition(bat),getPosition(chemicalshifts[cs].ipos));
+    1367             :       const double d2=distance.modulo2();
+    1368             :       if(d2<cutOffNB2) chemicalshifts[cs].box_nb.push_back(bat);
+    1369             :     }
+    1370             :     chemicalshifts[cs].totcsatoms = chemicalshifts[cs].csatoms + chemicalshifts[cs].box_nb.size();
+    1371             :   }
+    1372          18 :   max_cs_atoms=0;
+    1373       10620 :   for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+    1374       10602 :     if(chemicalshifts[cs].totcsatoms>max_cs_atoms) max_cs_atoms = chemicalshifts[cs].totcsatoms;
+    1375             :   }
+    1376          18 : }
+    1377             : 
+    1378          18 : void CS2Backbone::compute_ring_parameters() {
+    1379         378 :   for(unsigned i=0; i<ringInfo.size(); i++) {
+    1380         360 :     const unsigned size = ringInfo[i].numAtoms;
+    1381         360 :     if(size==6) {
+    1382         342 :       ringInfo[i].g[0] = delta(getPosition(ringInfo[i].atom[4]),getPosition(ringInfo[i].atom[2]));
+    1383         342 :       ringInfo[i].g[1] = delta(getPosition(ringInfo[i].atom[5]),getPosition(ringInfo[i].atom[3]));
+    1384         342 :       ringInfo[i].g[2] = delta(getPosition(ringInfo[i].atom[0]),getPosition(ringInfo[i].atom[4]));
+    1385         342 :       ringInfo[i].g[3] = delta(getPosition(ringInfo[i].atom[1]),getPosition(ringInfo[i].atom[5]));
+    1386         342 :       ringInfo[i].g[4] = delta(getPosition(ringInfo[i].atom[2]),getPosition(ringInfo[i].atom[0]));
+    1387         342 :       ringInfo[i].g[5] = delta(getPosition(ringInfo[i].atom[3]),getPosition(ringInfo[i].atom[1]));
+    1388             :       // ring center
+    1389         342 :       Vector midP = getPosition(ringInfo[i].atom[0]);
+    1390        2052 :       for(unsigned j=1; j<size; j++) midP += getPosition(ringInfo[i].atom[j]);
+    1391         342 :       ringInfo[i].position = midP/6.;
+    1392             :       // compute normal std::vector to plane
+    1393         342 :       Vector n1 = crossProduct(ringInfo[i].g[2], -ringInfo[i].g[4]);
+    1394         342 :       Vector n2 = crossProduct(ringInfo[i].g[5], -ringInfo[i].g[1]);
+    1395         342 :       ringInfo[i].normVect = 0.5*(n1 + n2);
+    1396             :     }  else {
+    1397          18 :       ringInfo[i].g[0] = delta(getPosition(ringInfo[i].atom[3]),getPosition(ringInfo[i].atom[2]));
+    1398          18 :       ringInfo[i].g[1] = delta(getPosition(ringInfo[i].atom[0]),getPosition(ringInfo[i].atom[3]));
+    1399          18 :       ringInfo[i].g[2] = delta(getPosition(ringInfo[i].atom[2]),getPosition(ringInfo[i].atom[0]));
+    1400             :       // ring center
+    1401          18 :       ringInfo[i].position = (getPosition(ringInfo[i].atom[0])+getPosition(ringInfo[i].atom[2])+getPosition(ringInfo[i].atom[3]))/3.;
+    1402             :       // ring plane normal std::vector
+    1403          18 :       ringInfo[i].normVect = crossProduct(ringInfo[i].g[1],-ringInfo[i].g[2]);
+    1404             : 
+    1405             :     }
+    1406             :     // calculate squared length and length of normal std::vector
+    1407         360 :     ringInfo[i].lengthN2 = 1./ringInfo[i].normVect.modulo2();
+    1408         360 :     ringInfo[i].lengthNV = 1./std::sqrt(ringInfo[i].lengthN2);
+    1409             :   }
+    1410          18 : }
+    1411             : 
+    1412       31806 : CS2Backbone::aa_t CS2Backbone::frag2enum(const std::string &aa) {
+    1413             :   aa_t type = ALA;
+    1414       31806 :   if (aa == "ALA") type = ALA;
+    1415       29934 :   else if (aa == "ARG") type = ARG;
+    1416       28548 :   else if (aa == "ASN") type = ASN;
+    1417       26910 :   else if (aa == "ASP") type = ASP;
+    1418       25380 :   else if (aa == "ASH") type = ASP;
+    1419       25380 :   else if (aa == "CYS") type = CYS;
+    1420       24858 :   else if (aa == "CYM") type = CYS;
+    1421       24858 :   else if (aa == "GLN") type = GLN;
+    1422       24390 :   else if (aa == "GLU") type = GLU;
+    1423       22068 :   else if (aa == "GLH") type = GLU;
+    1424       22068 :   else if (aa == "GLY") type = GLY;
+    1425       16974 :   else if (aa == "HIS") type = HIS;
+    1426       16974 :   else if (aa == "HSE") type = HIS;
+    1427       16974 :   else if (aa == "HIE") type = HIS;
+    1428       16974 :   else if (aa == "HSP") type = HIS;
+    1429       16974 :   else if (aa == "HIP") type = HIS;
+    1430       16974 :   else if (aa == "HSD") type = HIS;
+    1431       16974 :   else if (aa == "HID") type = HIS;
+    1432       16974 :   else if (aa == "ILE") type = ILE;
+    1433       15174 :   else if (aa == "LEU") type = LEU;
+    1434       13536 :   else if (aa == "LYS") type = LYS;
+    1435       10746 :   else if (aa == "MET") type = MET;
+    1436        9936 :   else if (aa == "PHE") type = PHE;
+    1437        6876 :   else if (aa == "PRO") type = PRO;
+    1438        5940 :   else if (aa == "SER") type = SER;
+    1439        4302 :   else if (aa == "THR") type = THR;
+    1440        2196 :   else if (aa == "TRP") type = TRP;
+    1441        1980 :   else if (aa == "TYR") type = TYR;
+    1442        1602 :   else if (aa == "VAL") type = VAL;
+    1443           0 :   else if (aa == "UNK") type = UNK;
+    1444           0 :   else plumed_merror("Error converting std::string " + aa + " into amino acid index: not a valid 3-letter code");
+    1445       31806 :   return type;
+    1446             : }
+    1447             : 
+    1448       10602 : std::vector<std::string> CS2Backbone::side_chain_atoms(const std::string &s) {
+    1449             :   std::vector<std::string> sc;
+    1450             : 
+    1451       10602 :   if(s=="ALA") {
+    1452         648 :     sc.push_back( "CB" );
+    1453         648 :     sc.push_back( "HB1" );
+    1454         648 :     sc.push_back( "HB2" );
+    1455         648 :     sc.push_back( "HB3" );
+    1456         648 :     return sc;
+    1457        9954 :   } else if(s=="ARG") {
+    1458         468 :     sc.push_back( "CB" );
+    1459         468 :     sc.push_back( "CG" );
+    1460         468 :     sc.push_back( "CD" );
+    1461         468 :     sc.push_back( "NE" );
+    1462         468 :     sc.push_back( "CZ" );
+    1463         468 :     sc.push_back( "NH1" );
+    1464         468 :     sc.push_back( "NH2" );
+    1465         468 :     sc.push_back( "NH3" );
+    1466         468 :     sc.push_back( "HB1" );
+    1467         468 :     sc.push_back( "HB2" );
+    1468         468 :     sc.push_back( "HB3" );
+    1469         468 :     sc.push_back( "HG1" );
+    1470         468 :     sc.push_back( "HG2" );
+    1471         468 :     sc.push_back( "HG3" );
+    1472         468 :     sc.push_back( "HD1" );
+    1473         468 :     sc.push_back( "HD2" );
+    1474         468 :     sc.push_back( "HD3" );
+    1475         468 :     sc.push_back( "HE" );
+    1476         468 :     sc.push_back( "HH11" );
+    1477         468 :     sc.push_back( "HH12" );
+    1478         468 :     sc.push_back( "HH21" );
+    1479         468 :     sc.push_back( "HH22" );
+    1480         468 :     sc.push_back( "1HH1" );
+    1481         468 :     sc.push_back( "2HH1" );
+    1482         468 :     sc.push_back( "1HH2" );
+    1483         468 :     sc.push_back( "2HH2" );
+    1484         468 :     return sc;
+    1485        9486 :   } else if(s=="ASN") {
+    1486         594 :     sc.push_back( "CB" );
+    1487         594 :     sc.push_back( "CG" );
+    1488         594 :     sc.push_back( "OD1" );
+    1489         594 :     sc.push_back( "ND2" );
+    1490         594 :     sc.push_back( "HB1" );
+    1491         594 :     sc.push_back( "HB2" );
+    1492         594 :     sc.push_back( "HB3" );
+    1493         594 :     sc.push_back( "HD21" );
+    1494         594 :     sc.push_back( "HD22" );
+    1495         594 :     sc.push_back( "1HD2" );
+    1496         594 :     sc.push_back( "2HD2" );
+    1497         594 :     return sc;
+    1498       17226 :   } else if(s=="ASP"||s=="ASH") {
+    1499         558 :     sc.push_back( "CB" );
+    1500         558 :     sc.push_back( "CG" );
+    1501         558 :     sc.push_back( "OD1" );
+    1502         558 :     sc.push_back( "OD2" );
+    1503         558 :     sc.push_back( "HB1" );
+    1504         558 :     sc.push_back( "HB2" );
+    1505         558 :     sc.push_back( "HB3" );
+    1506         558 :     return sc;
+    1507       16668 :   } else if(s=="CYS"||s=="CYM") {
+    1508           0 :     sc.push_back( "CB" );
+    1509           0 :     sc.push_back( "SG" );
+    1510           0 :     sc.push_back( "HB1" );
+    1511           0 :     sc.push_back( "HB2" );
+    1512           0 :     sc.push_back( "HB3" );
+    1513           0 :     sc.push_back( "HG1" );
+    1514           0 :     sc.push_back( "HG" );
+    1515           0 :     return sc;
+    1516        8334 :   } else if(s=="GLN") {
+    1517         162 :     sc.push_back( "CB" );
+    1518         162 :     sc.push_back( "CG" );
+    1519         162 :     sc.push_back( "CD" );
+    1520         162 :     sc.push_back( "OE1" );
+    1521         162 :     sc.push_back( "NE2" );
+    1522         162 :     sc.push_back( "HB1" );
+    1523         162 :     sc.push_back( "HB2" );
+    1524         162 :     sc.push_back( "HB3" );
+    1525         162 :     sc.push_back( "HG1" );
+    1526         162 :     sc.push_back( "HG2" );
+    1527         162 :     sc.push_back( "HG3" );
+    1528         162 :     sc.push_back( "HE21" );
+    1529         162 :     sc.push_back( "HE22" );
+    1530         162 :     sc.push_back( "1HE2" );
+    1531         162 :     sc.push_back( "2HE2" );
+    1532         162 :     return sc;
+    1533       15552 :   } else if(s=="GLU"||s=="GLH") {
+    1534         792 :     sc.push_back( "CB" );
+    1535         792 :     sc.push_back( "CG" );
+    1536         792 :     sc.push_back( "CD" );
+    1537         792 :     sc.push_back( "OE1" );
+    1538         792 :     sc.push_back( "OE2" );
+    1539         792 :     sc.push_back( "HB1" );
+    1540         792 :     sc.push_back( "HB2" );
+    1541         792 :     sc.push_back( "HB3" );
+    1542         792 :     sc.push_back( "HG1" );
+    1543         792 :     sc.push_back( "HG2" );
+    1544         792 :     sc.push_back( "HG3" );
+    1545         792 :     return sc;
+    1546        7380 :   } else if(s=="GLY") {
+    1547        1494 :     sc.push_back( "HA2" );
+    1548        1494 :     return sc;
+    1549       41202 :   } else if(s=="HIS"||s=="HSE"||s=="HIE"||s=="HSD"||s=="HID"||s=="HIP"||s=="HSP") {
+    1550           0 :     sc.push_back( "CB" );
+    1551           0 :     sc.push_back( "CG" );
+    1552           0 :     sc.push_back( "ND1" );
+    1553           0 :     sc.push_back( "CD2" );
+    1554           0 :     sc.push_back( "CE1" );
+    1555           0 :     sc.push_back( "NE2" );
+    1556           0 :     sc.push_back( "HB1" );
+    1557           0 :     sc.push_back( "HB2" );
+    1558           0 :     sc.push_back( "HB3" );
+    1559           0 :     sc.push_back( "HD1" );
+    1560           0 :     sc.push_back( "HD2" );
+    1561           0 :     sc.push_back( "HE1" );
+    1562           0 :     sc.push_back( "HE2" );
+    1563           0 :     return sc;
+    1564        5886 :   } else if(s=="ILE") {
+    1565         540 :     sc.push_back( "CB" );
+    1566         540 :     sc.push_back( "CG1" );
+    1567         540 :     sc.push_back( "CG2" );
+    1568         540 :     sc.push_back( "CD" );
+    1569         540 :     sc.push_back( "HB" );
+    1570         540 :     sc.push_back( "HG11" );
+    1571         540 :     sc.push_back( "HG12" );
+    1572         540 :     sc.push_back( "HG21" );
+    1573         540 :     sc.push_back( "HG22" );
+    1574         540 :     sc.push_back( "HG23" );
+    1575         540 :     sc.push_back( "1HG1" );
+    1576         540 :     sc.push_back( "2HG1" );
+    1577         540 :     sc.push_back( "1HG2" );
+    1578         540 :     sc.push_back( "2HG2" );
+    1579         540 :     sc.push_back( "3HG2" );
+    1580         540 :     sc.push_back( "HD1" );
+    1581         540 :     sc.push_back( "HD2" );
+    1582         540 :     sc.push_back( "HD3" );
+    1583         540 :     return sc;
+    1584        5346 :   } else if(s=="LEU") {
+    1585         648 :     sc.push_back( "CB" );
+    1586         648 :     sc.push_back( "CG" );
+    1587         648 :     sc.push_back( "CD1" );
+    1588         648 :     sc.push_back( "CD2" );
+    1589         648 :     sc.push_back( "HB1" );
+    1590         648 :     sc.push_back( "HB2" );
+    1591         648 :     sc.push_back( "HB3" );
+    1592         648 :     sc.push_back( "HG" );
+    1593         648 :     sc.push_back( "HD11" );
+    1594         648 :     sc.push_back( "HD12" );
+    1595         648 :     sc.push_back( "HD13" );
+    1596         648 :     sc.push_back( "HD21" );
+    1597         648 :     sc.push_back( "HD22" );
+    1598         648 :     sc.push_back( "HD23" );
+    1599         648 :     sc.push_back( "1HD1" );
+    1600         648 :     sc.push_back( "2HD1" );
+    1601         648 :     sc.push_back( "3HD1" );
+    1602         648 :     sc.push_back( "1HD2" );
+    1603         648 :     sc.push_back( "2HD2" );
+    1604         648 :     sc.push_back( "3HD2" );
+    1605         648 :     return sc;
+    1606        4698 :   } else if(s=="LYS") {
+    1607        1008 :     sc.push_back( "CB" );
+    1608        1008 :     sc.push_back( "CG" );
+    1609        1008 :     sc.push_back( "CD" );
+    1610        1008 :     sc.push_back( "CE" );
+    1611        1008 :     sc.push_back( "NZ" );
+    1612        1008 :     sc.push_back( "HB1" );
+    1613        1008 :     sc.push_back( "HB2" );
+    1614        1008 :     sc.push_back( "HB3" );
+    1615        1008 :     sc.push_back( "HG1" );
+    1616        1008 :     sc.push_back( "HG2" );
+    1617        1008 :     sc.push_back( "HG3" );
+    1618        1008 :     sc.push_back( "HD1" );
+    1619        1008 :     sc.push_back( "HD2" );
+    1620        1008 :     sc.push_back( "HD3" );
+    1621        1008 :     sc.push_back( "HE1" );
+    1622        1008 :     sc.push_back( "HE2" );
+    1623        1008 :     sc.push_back( "HE3" );
+    1624        1008 :     sc.push_back( "HZ1" );
+    1625        1008 :     sc.push_back( "HZ2" );
+    1626        1008 :     sc.push_back( "HZ3" );
+    1627        1008 :     return sc;
+    1628        3690 :   } else if(s=="MET") {
+    1629         288 :     sc.push_back( "CB" );
+    1630         288 :     sc.push_back( "CG" );
+    1631         288 :     sc.push_back( "SD" );
+    1632         288 :     sc.push_back( "CE" );
+    1633         288 :     sc.push_back( "HB1" );
+    1634         288 :     sc.push_back( "HB2" );
+    1635         288 :     sc.push_back( "HB3" );
+    1636         288 :     sc.push_back( "HG1" );
+    1637         288 :     sc.push_back( "HG2" );
+    1638         288 :     sc.push_back( "HG3" );
+    1639         288 :     sc.push_back( "HE1" );
+    1640         288 :     sc.push_back( "HE2" );
+    1641         288 :     sc.push_back( "HE3" );
+    1642         288 :     return sc;
+    1643        3402 :   } else if(s=="PHE") {
+    1644        1098 :     sc.push_back( "CB" );
+    1645        1098 :     sc.push_back( "CG" );
+    1646        1098 :     sc.push_back( "CD1" );
+    1647        1098 :     sc.push_back( "CD2" );
+    1648        1098 :     sc.push_back( "CE1" );
+    1649        1098 :     sc.push_back( "CE2" );
+    1650        1098 :     sc.push_back( "CZ" );
+    1651        1098 :     sc.push_back( "HB1" );
+    1652        1098 :     sc.push_back( "HB2" );
+    1653        1098 :     sc.push_back( "HB3" );
+    1654        1098 :     sc.push_back( "HD1" );
+    1655        1098 :     sc.push_back( "HD2" );
+    1656        1098 :     sc.push_back( "HD3" );
+    1657        1098 :     sc.push_back( "HE1" );
+    1658        1098 :     sc.push_back( "HE2" );
+    1659        1098 :     sc.push_back( "HE3" );
+    1660        1098 :     sc.push_back( "HZ" );
+    1661        1098 :     return sc;
+    1662        2304 :   } else if(s=="PRO") {
+    1663         108 :     sc.push_back( "CB" );
+    1664         108 :     sc.push_back( "CG" );
+    1665         108 :     sc.push_back( "CD" );
+    1666         108 :     sc.push_back( "HB1" );
+    1667         108 :     sc.push_back( "HB2" );
+    1668         108 :     sc.push_back( "HB3" );
+    1669         108 :     sc.push_back( "HG1" );
+    1670         108 :     sc.push_back( "HG2" );
+    1671         108 :     sc.push_back( "HG3" );
+    1672         108 :     sc.push_back( "HD1" );
+    1673         108 :     sc.push_back( "HD2" );
+    1674         108 :     sc.push_back( "HD3" );
+    1675         108 :     return sc;
+    1676        2196 :   } else if(s=="SER") {
+    1677         630 :     sc.push_back( "CB" );
+    1678         630 :     sc.push_back( "OG" );
+    1679         630 :     sc.push_back( "HB1" );
+    1680         630 :     sc.push_back( "HB2" );
+    1681         630 :     sc.push_back( "HB3" );
+    1682         630 :     sc.push_back( "HG1" );
+    1683         630 :     sc.push_back( "HG" );
+    1684         630 :     return sc;
+    1685        1566 :   } else if(s=="THR") {
+    1686         774 :     sc.push_back( "CB" );
+    1687         774 :     sc.push_back( "OG1" );
+    1688         774 :     sc.push_back( "CG2" );
+    1689         774 :     sc.push_back( "HB" );
+    1690         774 :     sc.push_back( "HG1" );
+    1691         774 :     sc.push_back( "HG21" );
+    1692         774 :     sc.push_back( "HG22" );
+    1693         774 :     sc.push_back( "HG23" );
+    1694         774 :     sc.push_back( "1HG2" );
+    1695         774 :     sc.push_back( "2HG2" );
+    1696         774 :     sc.push_back( "3HG2" );
+    1697         774 :     return sc;
+    1698         792 :   } else if(s=="TRP") {
+    1699          72 :     sc.push_back( "CB" );
+    1700          72 :     sc.push_back( "CG" );
+    1701          72 :     sc.push_back( "CD1" );
+    1702          72 :     sc.push_back( "CD2" );
+    1703          72 :     sc.push_back( "NE1" );
+    1704          72 :     sc.push_back( "CE2" );
+    1705          72 :     sc.push_back( "CE3" );
+    1706          72 :     sc.push_back( "CZ2" );
+    1707          72 :     sc.push_back( "CZ3" );
+    1708          72 :     sc.push_back( "CH2" );
+    1709          72 :     sc.push_back( "HB1" );
+    1710          72 :     sc.push_back( "HB2" );
+    1711          72 :     sc.push_back( "HB3" );
+    1712          72 :     sc.push_back( "HD1" );
+    1713          72 :     sc.push_back( "HE1" );
+    1714          72 :     sc.push_back( "HE3" );
+    1715          72 :     sc.push_back( "HZ2" );
+    1716          72 :     sc.push_back( "HZ3" );
+    1717          72 :     sc.push_back( "HH2" );
+    1718          72 :     return sc;
+    1719         720 :   } else if(s=="TYR") {
+    1720         144 :     sc.push_back( "CB" );
+    1721         144 :     sc.push_back( "CG" );
+    1722         144 :     sc.push_back( "CD1" );
+    1723         144 :     sc.push_back( "CD2" );
+    1724         144 :     sc.push_back( "CE1" );
+    1725         144 :     sc.push_back( "CE2" );
+    1726         144 :     sc.push_back( "CZ" );
+    1727         144 :     sc.push_back( "OH" );
+    1728         144 :     sc.push_back( "HB1" );
+    1729         144 :     sc.push_back( "HB2" );
+    1730         144 :     sc.push_back( "HB3" );
+    1731         144 :     sc.push_back( "HD1" );
+    1732         144 :     sc.push_back( "HD2" );
+    1733         144 :     sc.push_back( "HD3" );
+    1734         144 :     sc.push_back( "HE1" );
+    1735         144 :     sc.push_back( "HE2" );
+    1736         144 :     sc.push_back( "HE3" );
+    1737         144 :     sc.push_back( "HH" );
+    1738         144 :     return sc;
+    1739         576 :   } else if(s=="VAL") {
+    1740         576 :     sc.push_back( "CB" );
+    1741         576 :     sc.push_back( "CG1" );
+    1742         576 :     sc.push_back( "CG2" );
+    1743         576 :     sc.push_back( "HB" );
+    1744         576 :     sc.push_back( "HG11" );
+    1745         576 :     sc.push_back( "HG12" );
+    1746         576 :     sc.push_back( "HG13" );
+    1747         576 :     sc.push_back( "HG21" );
+    1748         576 :     sc.push_back( "HG22" );
+    1749         576 :     sc.push_back( "HG23" );
+    1750         576 :     sc.push_back( "1HG1" );
+    1751         576 :     sc.push_back( "2HG1" );
+    1752         576 :     sc.push_back( "3HG1" );
+    1753         576 :     sc.push_back( "1HG2" );
+    1754         576 :     sc.push_back( "2HG2" );
+    1755         576 :     sc.push_back( "3HG2" );
+    1756         576 :     return sc;
+    1757           0 :   } else plumed_merror("Sidechain atoms unknown: " + s);
+    1758           0 : }
+    1759             : 
+    1760       47016 : bool CS2Backbone::isSP2(const std::string & resType, const std::string & atomName) {
+    1761             :   bool sp2 = false;
+    1762       47016 :   if (atomName == "C") return true;
+    1763       43848 :   if (atomName == "O") return true;
+    1764             : 
+    1765       40716 :   if(resType == "TRP") {
+    1766         396 :     if      (atomName == "CG")  sp2 = true;
+    1767         378 :     else if (atomName == "CD1") sp2 = true;
+    1768         360 :     else if (atomName == "CD2") sp2 = true;
+    1769         342 :     else if (atomName == "CE2") sp2 = true;
+    1770         324 :     else if (atomName == "CE3") sp2 = true;
+    1771         306 :     else if (atomName == "CZ2") sp2 = true;
+    1772         288 :     else if (atomName == "CZ3") sp2 = true;
+    1773         270 :     else if (atomName == "CH2") sp2 = true;
+    1774       40320 :   } else if (resType == "ASP") {
+    1775        1656 :     if      (atomName == "CG")  sp2 = true;
+    1776        1494 :     else if (atomName == "OD1") sp2 = true;
+    1777        1332 :     else if (atomName == "OD2") sp2 = true;
+    1778       38664 :   } else if (resType == "GLU") {
+    1779        2844 :     if      (atomName == "CD")  sp2 = true;
+    1780        2628 :     else if (atomName == "OE1") sp2 = true;
+    1781        2412 :     else if (atomName == "OE2") sp2 = true;
+    1782       35820 :   } else if (resType == "ARG") {
+    1783        2772 :     if (atomName == "CZ") sp2 = true;
+    1784       33048 :   } else if (resType == "HIS") {
+    1785           0 :     if      (atomName == "CG")  sp2 = true;
+    1786           0 :     else if (atomName == "ND1") sp2 = true;
+    1787           0 :     else if (atomName == "CD2") sp2 = true;
+    1788           0 :     else if (atomName == "CE1") sp2 = true;
+    1789           0 :     else if (atomName == "NE2") sp2 = true;
+    1790       33048 :   } else if (resType == "PHE") {
+    1791        5184 :     if      (atomName == "CG")  sp2 = true;
+    1792        4896 :     else if (atomName == "CD1") sp2 = true;
+    1793        4608 :     else if (atomName == "CD2") sp2 = true;
+    1794        4320 :     else if (atomName == "CE1") sp2 = true;
+    1795        4032 :     else if (atomName == "CE2") sp2 = true;
+    1796        3744 :     else if (atomName == "CZ")  sp2 = true;
+    1797       27864 :   } else if (resType == "TYR") {
+    1798         684 :     if      (atomName == "CG")  sp2 = true;
+    1799         648 :     else if (atomName == "CD1") sp2 = true;
+    1800         612 :     else if (atomName == "CD2") sp2 = true;
+    1801         576 :     else if (atomName == "CE1") sp2 = true;
+    1802         540 :     else if (atomName == "CE2") sp2 = true;
+    1803         504 :     else if (atomName == "CZ")  sp2 = true;
+    1804       27180 :   } else if (resType == "ASN") {
+    1805        1944 :     if      (atomName == "CG")  sp2 = true;
+    1806        1782 :     else if (atomName == "OD1") sp2 = true;
+    1807       25236 :   } else if (resType == "GLN") {
+    1808         810 :     if      (atomName == "CD")  sp2 = true;
+    1809         756 :     else if (atomName == "OE1") sp2 = true;
+    1810             :   }
+    1811             : 
+    1812             :   return sp2;
+    1813             : }
+    1814             : 
+    1815      145728 : bool CS2Backbone::is_chi1_cx(const std::string & frg, const std::string & atm) {
+    1816      145728 :   if(atm=="CG")                                        return true;
+    1817      139788 :   if((frg == "CYS")&&(atm =="SG"))                     return true;
+    1818      288792 :   if(((frg == "ILE")||(frg == "VAL"))&&(atm == "CG1")) return true;
+    1819      145602 :   if((frg == "SER")&&(atm == "OG"))                    return true;
+    1820      148878 :   if((frg == "THR")&&(atm == "OG1"))                   return true;
+    1821             : 
+    1822             :   return false;
+    1823             : }
+    1824             : 
+    1825     3599784 : void CS2Backbone::xdist_name_map(std::string & name) {
+    1826     7199568 :   if((name == "OT1")||(name == "OC1")) name = "O";
+    1827    10799352 :   else if ((name == "HN") || (name == "HT1") || (name == "H1")) name = "H";
+    1828     7139232 :   else if ((name == "CG1")|| (name == "OG")||
+    1829     7159572 :            (name == "SG") || (name == "OG1")) name = "CG";
+    1830     7040070 :   else if ((name == "HA1")|| (name == "HA3")) name = "HA";
+    1831     3599784 : }
+    1832             : 
+    1833          18 : void CS2Backbone::update() {
+    1834             :   // write status file
+    1835          18 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+    1836          18 : }
+    1837             : 
+    1838             : }
+    1839             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..17fa22378a --- /dev/null +++ b/coverage/isdb/Caliber.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:11514678.8 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7Caliber14get_sigma_meanEdRKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7CaliberC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_120CaliberRegisterMe1236createERKNS_13ActionOptionsE4
_ZN4PLMD4isdb7CaliberC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb7Caliber16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4isdb7Caliber17replica_averagingEdRSt6vectorIdSaIdEE2004
_ZN4PLMD4isdb7Caliber9calculateEv2004
_ZN4PLMD4isdb7Caliber9getSplineEj2004
_ZN4PLMD4isdb12_GLOBAL__N_120CaliberRegisterMe123C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_120CaliberRegisterMe123D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Caliber.cpp.func.html b/coverage/isdb/Caliber.cpp.func.html new file mode 100644 index 0000000000..9b4afd292a --- /dev/null +++ b/coverage/isdb/Caliber.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:11514678.8 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_120CaliberRegisterMe1236createERKNS_13ActionOptionsE4
_ZN4PLMD4isdb12_GLOBAL__N_120CaliberRegisterMe123C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_120CaliberRegisterMe123D2Ev3473
_ZN4PLMD4isdb7Caliber14get_sigma_meanEdRKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4isdb7Caliber17replica_averagingEdRSt6vectorIdSaIdEE2004
_ZN4PLMD4isdb7Caliber18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber9calculateEv2004
_ZN4PLMD4isdb7Caliber9getSplineEj2004
_ZN4PLMD4isdb7CaliberC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb7CaliberC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Caliber.cpp.gcov.html b/coverage/isdb/Caliber.cpp.gcov.html new file mode 100644 index 0000000000..b3b636d7f3 --- /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:11514678.8 %
Date:2024-06-10 08:19:14Functions:81172.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 "bias/Bias.h"
+      23             : #include "bias/ActionRegister.h"
+      24             : #include "core/Atoms.h"
+      25             : #include "core/PlumedMain.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       10427 : PLUMED_REGISTER_ACTION(Caliber,"CALIBER")
+     124             : 
+     125           5 : void Caliber::registerKeywords( Keywords& keys ) {
+     126           5 :   Bias::registerKeywords(keys);
+     127           5 :   keys.use("ARG");
+     128          10 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+     129          10 :   keys.add("compulsory","FILE","the name of the file containing the time-resolved values");
+     130          10 :   keys.add("compulsory","KAPPA","a force constant, this can be use to scale a constant estimated on-the-fly using AVERAGING");
+     131          10 :   keys.add("optional","AVERAGING", "Stride for calculation of the optimum kappa, if 0 only KAPPA is used.");
+     132          10 :   keys.add("compulsory","TSCALE","1.0","Apply a time scaling on the experimental time scale");
+     133          10 :   keys.add("compulsory","SCALE","1.0","Apply a constant scaling on the data provided as arguments");
+     134          10 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+     135          10 :   keys.addOutputComponent("x0","default","the instantaneous value of the center of the potential");
+     136          10 :   keys.addOutputComponent("mean","default","the current average value of the calculated observable");
+     137          10 :   keys.addOutputComponent("kappa","default","the current force constant");
+     138          10 :   keys.addOutputComponent("scale","REGRES_ZERO","the current scaling constant");
+     139           5 : }
+     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             :     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             :   setBias(ene);
+     342        2004 : }
+     343             : 
+     344             : }
+     345             : }
+     346             : 
+     347             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..75b3bddfce --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func-sort-c.html @@ -0,0 +1,241 @@ + + + + + + + + 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:59378575.5 %
Date:2024-06-10 08:19:14Functions:324276.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4EMMI11read_statusEv0
_ZN4PLMD4isdb4EMMI11scaleEnergyEd0
_ZN4PLMD4isdb4EMMI12doMonteCarloEv0
_ZN4PLMD4isdb4EMMI12doRegressionEv0
_ZN4PLMD4isdb4EMMI13get_annealingEl0
_ZN4PLMD4isdb4EMMI15read_exp_errorsENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI17read_exp_overlapsENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI19write_model_overlapEl0
_ZN4PLMD4isdb4EMMI8doAcceptEddd0
_ZN4PLMD4isdb4EMMIC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb4EMMI29calculateNumericalDerivativesEPNS_15ActionWithValueE9
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe3846createERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMI14setDerivativesEv20
_ZN4PLMD4isdb4EMMI17turnOnDerivativesEv20
_ZN4PLMD4isdb4EMMI22calculate_useful_stuffEd20
_ZN4PLMD4isdb4EMMI9get_GMM_dENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD4isdb4EMMI9get_GMM_mERSt6vectorINS_10AtomNumberESaIS3_EE20
_ZN4PLMD4isdb4EMMIC1ERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMI16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD4isdb4EMMI12lockRequestsEv30
_ZN4PLMD4isdb4EMMI14unlockRequestsEv30
_ZN4PLMD4isdb4EMMI5applyEv30
_ZN4PLMD4isdb4EMMI7prepareEv30
_ZN4PLMD4isdb4EMMI10get_medianERSt6vectorIdSaIdEE40
_ZN4PLMD4isdb4EMMI22getNumberOfDerivativesEv72
_ZN4PLMD4isdb4EMMI11check_GMM_dERKNS_13VectorGenericILj6EEEd1962
_ZN4PLMD4isdb4EMMI16get_self_overlapEj1962
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe384C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe384D2Ev3473
_ZN4PLMD4isdb4EMMI18calculate_MarginalEv5451
_ZN4PLMD4isdb4EMMI18calculate_OutliersEv5451
_ZN4PLMD4isdb4EMMI15calculate_GaussEv5463
_ZN4PLMD4isdb4EMMI12print_statusEl10904
_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.15
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.func.html b/coverage/isdb/EMMI.cpp.func.html new file mode 100644 index 0000000000..d9a4fcf732 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func.html @@ -0,0 +1,241 @@ + + + + + + + + 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:59378575.5 %
Date:2024-06-10 08:19:14Functions:324276.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe3846createERKNS_13ActionOptionsE20
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe384C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe384D2Ev3473
_ZN4PLMD4isdb4EMMI10get_medianERSt6vectorIdSaIdEE40
_ZN4PLMD4isdb4EMMI11check_GMM_dERKNS_13VectorGenericILj6EEEd1962
_ZN4PLMD4isdb4EMMI11get_overlapERKNS_13VectorGenericILj3EEES5_dRKNS2_ILj6EEERS3_3732816
_ZN4PLMD4isdb4EMMI11get_weightsERdS2_S2_16365
_ZN4PLMD4isdb4EMMI11read_statusEv0
_ZN4PLMD4isdb4EMMI11scaleEnergyEd0
_ZN4PLMD4isdb4EMMI12doMonteCarloEv0
_ZN4PLMD4isdb4EMMI12doRegressionEv0
_ZN4PLMD4isdb4EMMI12lockRequestsEv30
_ZN4PLMD4isdb4EMMI12print_statusEl10904
_ZN4PLMD4isdb4EMMI13get_annealingEl0
_ZN4PLMD4isdb4EMMI14setDerivativesEv20
_ZN4PLMD4isdb4EMMI14unlockRequestsEv30
_ZN4PLMD4isdb4EMMI15calculate_GaussEv5463
_ZN4PLMD4isdb4EMMI15get_exp_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj6EEE59085036
_ZN4PLMD4isdb4EMMI15read_exp_errorsENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI16get_self_overlapEj1962
_ZN4PLMD4isdb4EMMI16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD4isdb4EMMI17calculate_overlapEv16365
_ZN4PLMD4isdb4EMMI17read_exp_overlapsENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE16365
_ZN4PLMD4isdb4EMMI17turnOnDerivativesEv20
_ZN4PLMD4isdb4EMMI18calculate_MarginalEv5451
_ZN4PLMD4isdb4EMMI18calculate_OutliersEv5451
_ZN4PLMD4isdb4EMMI19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE9844626
_ZN4PLMD4isdb4EMMI19write_model_overlapEl0
_ZN4PLMD4isdb4EMMI20update_neighbor_listEv16355
_ZN4PLMD4isdb4EMMI21get_prefactor_inverseERKNS_13VectorGenericILj6EEES5_ddRS3_S6_1621458
_ZN4PLMD4isdb4EMMI22calculate_useful_stuffEd20
_ZN4PLMD4isdb4EMMI22getNumberOfDerivativesEv72
_ZN4PLMD4isdb4EMMI29calculateNumericalDerivativesEPNS_15ActionWithValueE9
_ZN4PLMD4isdb4EMMI5applyEv30
_ZN4PLMD4isdb4EMMI7prepareEv30
_ZN4PLMD4isdb4EMMI8doAcceptEddd0
_ZN4PLMD4isdb4EMMI9calculateEv16365
_ZN4PLMD4isdb4EMMI9get_GMM_dENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD4isdb4EMMI9get_GMM_mERSt6vectorINS_10AtomNumberESaIS3_EE20
_ZN4PLMD4isdb4EMMIC1ERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMIC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.gcov.html b/coverage/isdb/EMMI.cpp.gcov.html new file mode 100644 index 0000000000..5fd1ace61d --- /dev/null +++ b/coverage/isdb/EMMI.cpp.gcov.html @@ -0,0 +1,1827 @@ + + + + + + + + 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:59378575.5 %
Date:2024-06-10 08:19:14Functions:324276.2 %
+
+ + + + + + + + +

+
          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 "core/GenericMolInfo.h"
+      29             : #include "core/ActionSet.h"
+      30             : #include "tools/File.h"
+      31             : #include "tools/Random.h"
+      32             : 
+      33             : #include <string>
+      34             : #include <map>
+      35             : #include <numeric>
+      36             : #include <ctime>
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace isdb {
+      40             : 
+      41             : //+PLUMEDOC ISDB_COLVAR EMMI
+      42             : /*
+      43             : Calculate the fit of a structure or ensemble of structures with a cryo-EM density map.
+      44             : 
+      45             : This action implements the multi-scale Bayesian approach to cryo-EM data fitting introduced in  Ref. \cite Hanot113951 .
+      46             : 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.
+      47             : 
+      48             : The experimental density map is fit by a Gaussian Mixture Model (GMM), which is provided as an external file specified by the keyword
+      49             : GMM_FILE. We are currently working on a web server to perform
+      50             : this operation. In the meantime, the user can request a stand-alone version of the GMM code at massimiliano.bonomi_AT_gmail.com.
+      51             : 
+      52             : When run in single-replica mode, this action allows atomistic, flexible refinement of an individual structure into a density map.
+      53             : Combined with a multi-replica framework (such as the -multi option in GROMACS), the user can model an ensemble of structures using
+      54             : the Metainference approach \cite Bonomi:2016ip .
+      55             : 
+      56             : \warning
+      57             : To use \ref EMMI, the user should always add a \ref MOLINFO line and specify a pdb file of the system.
+      58             : 
+      59             : \note
+      60             : To enhance sampling in single-structure refinement, one can use a Replica Exchange Method, such as Parallel Tempering.
+      61             : 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
+      62             : Parallel-Bias Metadynamics (\ref PBMETAD), one should use the REWEIGHT flag and pass the Metadynamics bias using the ARG keyword.
+      63             : 
+      64             : \note
+      65             : \ref EMMI can be used in combination with periodic and non-periodic systems. In the latter case, one should
+      66             : add the NOPBC flag to the input line
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : In this example, we perform a single-structure refinement based on an experimental cryo-EM map. The map is fit with a GMM, whose
+      71             : parameters are listed in the file GMM_fit.dat. This file contains one line per GMM component in the following format:
+      72             : 
+      73             : \plumedfile
+      74             : #! FIELDS Id Weight Mean_0 Mean_1 Mean_2 Cov_00 Cov_01 Cov_02 Cov_11 Cov_12 Cov_22 Beta
+      75             :      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
+      76             :      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
+      77             :      ...
+      78             : \endplumedfile
+      79             : 
+      80             : To accelerate the computation of the Bayesian score, one can:
+      81             : - use neighbor lists, specified by the keywords NL_CUTOFF and NL_STRIDE;
+      82             : - calculate the restraint every other step (or more).
+      83             : 
+      84             : All the heavy atoms of the system are used to calculate the density map. This list can conveniently be provided
+      85             : using a GROMACS index file.
+      86             : 
+      87             : The input file looks as follows:
+      88             : 
+      89             : \plumedfile
+      90             : # include pdb info
+      91             : MOLINFO STRUCTURE=prot.pdb
+      92             : 
+      93             : #  all heavy atoms
+      94             : protein-h: GROUP NDX_FILE=index.ndx NDX_GROUP=Protein-H
+      95             : 
+      96             : # create EMMI score
+      97             : 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
+      98             : 
+      99             : # translate into bias - apply every 2 steps
+     100             : emr: BIASVALUE ARG=gmm.scoreb STRIDE=2
+     101             : 
+     102             : PRINT ARG=emr.* FILE=COLVAR STRIDE=500 FMT=%20.10f
+     103             : \endplumedfile
+     104             : 
+     105             : 
+     106             : */
+     107             : //+ENDPLUMEDOC
+     108             : 
+     109             : class EMMI :
+     110             :   public ActionAtomistic,
+     111             :   public ActionWithArguments,
+     112             :   public ActionWithValue
+     113             : {
+     114             : private:
+     115             : 
+     116             : // temperature in kbt
+     117             :   double kbt_;
+     118             : // model GMM - atom types
+     119             :   std::vector<unsigned> GMM_m_type_;
+     120             : // model GMM - list of atom sigmas - one per atom type
+     121             :   std::vector<double> GMM_m_s_;
+     122             : // model GMM - list of atom weights - one per atom type
+     123             :   std::vector<double> GMM_m_w_;
+     124             : // data GMM - means, weights, and covariances + beta option
+     125             :   std::vector<Vector>             GMM_d_m_;
+     126             :   std::vector<double>             GMM_d_w_;
+     127             :   std::vector< VectorGeneric<6> > GMM_d_cov_;
+     128             :   std::vector<int>                GMM_d_beta_;
+     129             :   std::vector < std::vector<int> >     GMM_d_grps_;
+     130             : // overlaps
+     131             :   std::vector<double> ovmd_;
+     132             :   std::vector<double> ovdd_;
+     133             :   std::vector<double> ovmd_ave_;
+     134             : // and derivatives
+     135             :   std::vector<Vector> ovmd_der_;
+     136             :   std::vector<Vector> atom_der_;
+     137             :   std::vector<double> GMMid_der_;
+     138             : // constants
+     139             :   double cfact_;
+     140             :   double inv_sqrt2_, sqrt2_pi_;
+     141             : // metainference
+     142             :   unsigned nrep_;
+     143             :   unsigned replica_;
+     144             :   std::vector<double> sigma_;
+     145             :   std::vector<double> sigma_min_;
+     146             :   std::vector<double> sigma_max_;
+     147             :   std::vector<double> dsigma_;
+     148             : // list of prefactors for overlap between two Gaussians
+     149             : // pre_fact = 1.0 / (2pi)**1.5 / std::sqrt(det_md) * Wm * Wd
+     150             :   std::vector<double> pre_fact_;
+     151             : // inverse of the sum of model and data covariances matrices
+     152             :   std::vector< VectorGeneric<6> > inv_cov_md_;
+     153             : // neighbor list
+     154             :   double   nl_cutoff_;
+     155             :   unsigned nl_stride_;
+     156             :   bool first_time_;
+     157             :   bool no_aver_;
+     158             :   std::vector<unsigned> nl_;
+     159             : // parallel stuff
+     160             :   unsigned size_;
+     161             :   unsigned rank_;
+     162             : // pbc
+     163             :   bool pbc_;
+     164             : // Monte Carlo stuff
+     165             :   int      MCstride_;
+     166             :   double   MCaccept_;
+     167             :   double   MCtrials_;
+     168             :   Random   random_;
+     169             :   // status stuff
+     170             :   unsigned int statusstride_;
+     171             :   std::string       statusfilename_;
+     172             :   OFile        statusfile_;
+     173             :   bool         first_status_;
+     174             :   // regression
+     175             :   unsigned nregres_;
+     176             :   double scale_;
+     177             :   double scale_min_;
+     178             :   double scale_max_;
+     179             :   double dscale_;
+     180             :   // tabulated exponential
+     181             :   double dpcutoff_;
+     182             :   double dexp_;
+     183             :   unsigned nexp_;
+     184             :   std::vector<double> tab_exp_;
+     185             :   // simulated annealing
+     186             :   unsigned nanneal_;
+     187             :   double   kanneal_;
+     188             :   double   anneal_;
+     189             :   // prior exponent
+     190             :   double prior_;
+     191             :   // noise type
+     192             :   unsigned noise_;
+     193             :   // total score and virial;
+     194             :   double ene_;
+     195             :   Tensor virial_;
+     196             :   // model overlap file
+     197             :   unsigned int ovstride_;
+     198             :   std::string       ovfilename_;
+     199             : 
+     200             :   // Reweighting additions
+     201             :   bool do_reweight_;
+     202             :   bool first_time_w_;
+     203             :   std::vector<double> forces;
+     204             :   std::vector<double> forcesToApply;
+     205             : 
+     206             :   // average weights
+     207             :   double decay_w_;
+     208             :   std::vector<double> average_weights_;
+     209             : 
+     210             : // write file with model overlap
+     211             :   void write_model_overlap(long int step);
+     212             : // get median of std::vector
+     213             :   double get_median(std::vector<double> &v);
+     214             : // annealing
+     215             :   double get_annealing(long int step);
+     216             : // do regression
+     217             :   double scaleEnergy(double s);
+     218             :   double doRegression();
+     219             : // read and write status
+     220             :   void read_status();
+     221             :   void print_status(long int step);
+     222             : // accept or reject
+     223             :   bool doAccept(double oldE, double newE, double kbt);
+     224             : // do MonteCarlo
+     225             :   void doMonteCarlo();
+     226             : // read error file
+     227             :   std::vector<double> read_exp_errors(std::string errfile);
+     228             : // read experimental overlaps
+     229             :   std::vector<double> read_exp_overlaps(std::string ovfile);
+     230             : // calculate model GMM weights and covariances
+     231             :   std::vector<double> get_GMM_m(std::vector<AtomNumber> &atoms);
+     232             : // read data GMM file
+     233             :   void get_GMM_d(std::string gmm_file);
+     234             : // check GMM data
+     235             :   void check_GMM_d(const VectorGeneric<6> &cov, double w);
+     236             : // auxiliary method
+     237             :   void calculate_useful_stuff(double reso);
+     238             : // get pref_fact and inv_cov_md
+     239             :   double get_prefactor_inverse (const VectorGeneric<6> &GMM_cov_0, const VectorGeneric<6> &GMM_cov_1,
+     240             :                                 double GMM_w_0, double GMM_w_1,
+     241             :                                 VectorGeneric<6> &sum, VectorGeneric<6> &inv_sum);
+     242             : // calculate self overlaps between data GMM components - ovdd_
+     243             :   double get_self_overlap(unsigned id);
+     244             : // calculate overlap between two Gaussians
+     245             :   double get_overlap(const Vector &m_m, const Vector &d_m, double pre_fact,
+     246             :                      const VectorGeneric<6> &inv_cov_md, Vector &ov_der);
+     247             : // calculate exponent of overlap for neighbor list update
+     248             :   double get_exp_overlap(const Vector &m_m, const Vector &d_m,
+     249             :                          const VectorGeneric<6> &inv_cov_md);
+     250             : // update the neighbor list
+     251             :   void update_neighbor_list();
+     252             : // calculate overlap
+     253             :   void calculate_overlap();
+     254             : // Gaussian noise
+     255             :   void calculate_Gauss();
+     256             : // Outliers noise
+     257             :   void calculate_Outliers();
+     258             : // Marginal noise
+     259             :   void calculate_Marginal();
+     260             : 
+     261             :   // See MetainferenceBase
+     262             :   void get_weights(double &weight, double &norm, double &neff);
+     263             : 
+     264             : public:
+     265             :   static void registerKeywords( Keywords& keys );
+     266             :   explicit EMMI(const ActionOptions&);
+     267             :   // needed for reweighting
+     268             :   void setDerivatives();
+     269             :   void turnOnDerivatives() override;
+     270             :   unsigned getNumberOfDerivatives() override;
+     271             :   void lockRequests() override;
+     272             :   void unlockRequests() override;
+     273             :   void calculateNumericalDerivatives( ActionWithValue* a ) override;
+     274             :   void apply() override;
+     275             :   void setArgDerivatives(Value *v, const double &d);
+     276             :   void setAtomsDerivatives(Value*v, const unsigned i, const Vector&d);
+     277             :   void setBoxDerivatives(Value*v, const Tensor&d);
+     278             : // active methods:
+     279             :   void prepare() override;
+     280             :   void calculate() override;
+     281             : };
+     282             : 
+     283             : inline
+     284          20 : void EMMI::setDerivatives() {
+     285             :   // Get appropriate number of derivatives
+     286             :   // Derivatives are first for arguments and then for atoms
+     287             :   unsigned nder;
+     288          20 :   if( getNumberOfAtoms()>0 ) {
+     289          20 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     290             :   } else {
+     291           0 :     nder = getNumberOfArguments();
+     292             :   }
+     293             : 
+     294             :   // Resize all derivative arrays
+     295          20 :   forces.resize( nder ); forcesToApply.resize( nder );
+     296          92 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(nder);
+     297          20 : }
+     298             : 
+     299             : inline
+     300          20 : void EMMI::turnOnDerivatives() {
+     301          20 :   ActionWithValue::turnOnDerivatives();
+     302          20 : }
+     303             : 
+     304             : inline
+     305          72 : unsigned EMMI::getNumberOfDerivatives() {
+     306          72 :   if( getNumberOfAtoms()>0 ) {
+     307          72 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     308             :   }
+     309           0 :   return getNumberOfArguments();
+     310             : }
+     311             : 
+     312             : inline
+     313          30 : void EMMI::lockRequests() {
+     314             :   ActionAtomistic::lockRequests();
+     315             :   ActionWithArguments::lockRequests();
+     316          30 : }
+     317             : 
+     318             : inline
+     319          30 : void EMMI::unlockRequests() {
+     320             :   ActionAtomistic::unlockRequests();
+     321             :   ActionWithArguments::unlockRequests();
+     322          30 : }
+     323             : 
+     324             : inline
+     325           9 : void EMMI::calculateNumericalDerivatives( ActionWithValue* a=NULL ) {
+     326           9 :   if( getNumberOfArguments()>0 ) {
+     327           0 :     ActionWithArguments::calculateNumericalDerivatives( a );
+     328             :   }
+     329           9 :   if( getNumberOfAtoms()>0 ) {
+     330           9 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
+     331          39 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     332          30 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) if(getPntrToComponent(j)->hasDerivatives()) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
+     333             :     }
+     334           9 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
+     335          39 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     336          30 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) if(getPntrToComponent(j)->hasDerivatives()) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
+     337             :     }
+     338             :   }
+     339           9 : }
+     340             : 
+     341             : inline
+     342          30 : void EMMI::apply() {
+     343          30 :   bool wasforced=false; forcesToApply.assign(forcesToApply.size(),0.0);
+     344         162 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     345         132 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
+     346             :       wasforced=true;
+     347           0 :       for(unsigned i=0; i<forces.size(); ++i) forcesToApply[i]+=forces[i];
+     348             :     }
+     349             :   }
+     350          30 :   if( wasforced ) {
+     351           0 :     addForcesOnArguments( forcesToApply );
+     352           0 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, getNumberOfArguments() );
+     353             :   }
+     354          30 : }
+     355             : 
+     356             : inline
+     357             : void EMMI::setArgDerivatives(Value *v, const double &d) {
+     358             :   v->addDerivative(0,d);
+     359             : }
+     360             : 
+     361             : inline
+     362     9844626 : void EMMI::setAtomsDerivatives(Value*v, const unsigned i, const Vector&d) {
+     363     9844626 :   const unsigned noa=getNumberOfArguments();
+     364     9844626 :   v->addDerivative(noa+3*i+0,d[0]);
+     365     9844626 :   v->addDerivative(noa+3*i+1,d[1]);
+     366     9844626 :   v->addDerivative(noa+3*i+2,d[2]);
+     367     9844626 : }
+     368             : 
+     369             : inline
+     370       16365 : void EMMI::setBoxDerivatives(Value* v,const Tensor&d) {
+     371       16365 :   const unsigned noa=getNumberOfArguments();
+     372             :   const unsigned nat=getNumberOfAtoms();
+     373       16365 :   v->addDerivative(noa+3*nat+0,d(0,0));
+     374       16365 :   v->addDerivative(noa+3*nat+1,d(0,1));
+     375       16365 :   v->addDerivative(noa+3*nat+2,d(0,2));
+     376       16365 :   v->addDerivative(noa+3*nat+3,d(1,0));
+     377       16365 :   v->addDerivative(noa+3*nat+4,d(1,1));
+     378       16365 :   v->addDerivative(noa+3*nat+5,d(1,2));
+     379       16365 :   v->addDerivative(noa+3*nat+6,d(2,0));
+     380       16365 :   v->addDerivative(noa+3*nat+7,d(2,1));
+     381       16365 :   v->addDerivative(noa+3*nat+8,d(2,2));
+     382       16365 : }
+     383             : 
+     384       10459 : PLUMED_REGISTER_ACTION(EMMI,"EMMI")
+     385             : 
+     386          21 : void EMMI::registerKeywords( Keywords& keys ) {
+     387          21 :   Action::registerKeywords( keys );
+     388          21 :   ActionAtomistic::registerKeywords( keys );
+     389          21 :   ActionWithValue::registerKeywords( keys );
+     390          21 :   ActionWithArguments::registerKeywords( keys );
+     391          21 :   keys.use("ARG");
+     392          42 :   keys.add("atoms","ATOMS","atoms for which we calculate the density map, typically all heavy atoms");
+     393          42 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     394          42 :   keys.add("compulsory","GMM_FILE","file with the parameters of the GMM components");
+     395          42 :   keys.add("compulsory","NL_CUTOFF","The cutoff in overlap for the neighbor list");
+     396          42 :   keys.add("compulsory","NL_STRIDE","The frequency with which we are updating the neighbor list");
+     397          42 :   keys.add("compulsory","SIGMA_MIN","minimum uncertainty");
+     398          42 :   keys.add("compulsory","RESOLUTION", "Cryo-EM map resolution");
+     399          42 :   keys.add("compulsory","NOISETYPE","functional form of the noise (GAUSS, OUTLIERS, MARGINAL)");
+     400          42 :   keys.add("optional","SIGMA0","initial value of the uncertainty");
+     401          42 :   keys.add("optional","DSIGMA","MC step for uncertainties");
+     402          42 :   keys.add("optional","MC_STRIDE", "Monte Carlo stride");
+     403          42 :   keys.add("optional","ERR_FILE","file with experimental or GMM fit errors");
+     404          42 :   keys.add("optional","OV_FILE","file with experimental overlaps");
+     405          42 :   keys.add("optional","NORM_DENSITY","integral of the experimental density");
+     406          42 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart");
+     407          42 :   keys.add("optional","WRITE_STRIDE","write the status to a file every N steps, this can be used for restart");
+     408          42 :   keys.add("optional","REGRESSION","regression stride");
+     409          42 :   keys.add("optional","REG_SCALE_MIN","regression minimum scale");
+     410          42 :   keys.add("optional","REG_SCALE_MAX","regression maximum scale");
+     411          42 :   keys.add("optional","REG_DSCALE","regression maximum scale MC move");
+     412          42 :   keys.add("optional","SCALE","scale factor");
+     413          42 :   keys.add("optional","ANNEAL", "Length of annealing cycle");
+     414          42 :   keys.add("optional","ANNEAL_FACT", "Annealing temperature factor");
+     415          42 :   keys.add("optional","TEMP","temperature");
+     416          42 :   keys.add("optional","PRIOR", "exponent of uncertainty prior");
+     417          42 :   keys.add("optional","WRITE_OV_STRIDE","write model overlaps every N steps");
+     418          42 :   keys.add("optional","WRITE_OV","write a file with model overlaps");
+     419          42 :   keys.add("optional","AVERAGING", "Averaging window for weights");
+     420          42 :   keys.addFlag("NO_AVER",false,"don't do ensemble averaging in multi-replica mode");
+     421          42 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the ARG as energy");
+     422          21 :   componentsAreNotOptional(keys);
+     423          42 :   keys.addOutputComponent("scoreb","default","Bayesian score");
+     424          42 :   keys.addOutputComponent("acc",   "NOISETYPE","MC acceptance for uncertainty");
+     425          42 :   keys.addOutputComponent("scale", "REGRESSION","scale factor");
+     426          42 :   keys.addOutputComponent("accscale", "REGRESSION","MC acceptance for scale regression");
+     427          42 :   keys.addOutputComponent("enescale", "REGRESSION","MC energy for scale regression");
+     428          42 :   keys.addOutputComponent("anneal","ANNEAL","annealing factor");
+     429          42 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+     430          42 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+     431          42 :   keys.addOutputComponent("sigma",      "NOISETYPE",     "uncertainty in the forward models and experiment");
+     432          42 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+     433          21 : }
+     434             : 
+     435          20 : EMMI::EMMI(const ActionOptions&ao):
+     436             :   Action(ao),
+     437             :   ActionAtomistic(ao),
+     438             :   ActionWithArguments(ao),
+     439             :   ActionWithValue(ao),
+     440          20 :   inv_sqrt2_(0.707106781186548),
+     441          20 :   sqrt2_pi_(0.797884560802865),
+     442          20 :   first_time_(true), no_aver_(false), pbc_(true),
+     443          20 :   MCstride_(1), MCaccept_(0.), MCtrials_(0.),
+     444          40 :   statusstride_(0), first_status_(true),
+     445          20 :   nregres_(0), scale_(1.),
+     446          20 :   dpcutoff_(15.0), nexp_(1000000), nanneal_(0),
+     447          40 :   kanneal_(0.), anneal_(1.), prior_(1.), ovstride_(0),
+     448          20 :   do_reweight_(false), first_time_w_(true), decay_w_(1.)
+     449             : {
+     450             :   // periodic boundary conditions
+     451          20 :   bool nopbc=!pbc_;
+     452          20 :   parseFlag("NOPBC",nopbc);
+     453          20 :   pbc_=!nopbc;
+     454             : 
+     455             :   // list of atoms
+     456             :   std::vector<AtomNumber> atoms;
+     457          40 :   parseAtomList("ATOMS", atoms);
+     458             : 
+     459             :   // file with data GMM
+     460             :   std::string GMM_file;
+     461          40 :   parse("GMM_FILE", GMM_file);
+     462             : 
+     463             :   // type of data noise
+     464             :   std::string noise;
+     465          40 :   parse("NOISETYPE",noise);
+     466          20 :   if      (noise=="GAUSS")   noise_ = 0;
+     467          12 :   else if(noise=="OUTLIERS") noise_ = 1;
+     468           6 :   else if(noise=="MARGINAL") noise_ = 2;
+     469           0 :   else error("Unknown noise type!");
+     470             : 
+     471             :   // minimum value for error
+     472             :   double sigma_min;
+     473          20 :   parse("SIGMA_MIN", sigma_min);
+     474          20 :   if(sigma_min<0) error("SIGMA_MIN should be greater or equal to zero");
+     475             : 
+     476             :   // the following parameters must be specified with noise type 0 and 1
+     477             :   double sigma_ini, dsigma;
+     478          20 :   if(noise_!=2) {
+     479             :     // initial value of the uncertainty
+     480          14 :     parse("SIGMA0", sigma_ini);
+     481          14 :     if(sigma_ini<=0) error("you must specify a positive SIGMA0");
+     482             :     // MC parameters
+     483          14 :     parse("DSIGMA", dsigma);
+     484          14 :     if(dsigma<0) error("you must specify a positive DSIGMA");
+     485          14 :     parse("MC_STRIDE", MCstride_);
+     486          14 :     if(dsigma>0 && MCstride_<=0) error("you must specify a positive MC_STRIDE");
+     487             :     // status file parameters
+     488          14 :     parse("WRITE_STRIDE", statusstride_);
+     489          14 :     if(statusstride_<=0) error("you must specify a positive WRITE_STRIDE");
+     490          28 :     parse("STATUS_FILE",  statusfilename_);
+     491          28 :     if(statusfilename_=="") statusfilename_ = "MISTATUS"+getLabel();
+     492           0 :     else                    statusfilename_ = statusfilename_+getLabel();
+     493             :   }
+     494             : 
+     495             :   // error file
+     496             :   std::string errfile;
+     497          40 :   parse("ERR_FILE", errfile);
+     498             : 
+     499             :   // file with experimental overlaps
+     500             :   std::string ovfile;
+     501          20 :   parse("OV_FILE", ovfile);
+     502             : 
+     503             :   // integral of the experimetal density
+     504          20 :   double norm_d = 0.0;
+     505          20 :   parse("NORM_DENSITY", norm_d);
+     506             : 
+     507             :   // temperature
+     508          20 :   double temp=0.0;
+     509          20 :   parse("TEMP",temp);
+     510             :   // convert temp to kbt
+     511          20 :   if(temp>0.0) kbt_=plumed.getAtoms().getKBoltzmann()*temp;
+     512           0 :   else kbt_=plumed.getAtoms().getKbT();
+     513             : 
+     514             :   // exponent of uncertainty prior
+     515          20 :   parse("PRIOR",prior_);
+     516             : 
+     517             :   // simulated annealing stuff
+     518          20 :   parse("ANNEAL", nanneal_);
+     519          20 :   parse("ANNEAL_FACT", kanneal_);
+     520          20 :   if(nanneal_>0 && kanneal_<=1.0) error("with ANNEAL, ANNEAL_FACT must be greater than 1");
+     521             : 
+     522             :   // regression stride
+     523          20 :   parse("REGRESSION",nregres_);
+     524             :   // other regression parameters
+     525          20 :   if(nregres_>0) {
+     526           0 :     parse("REG_SCALE_MIN",scale_min_);
+     527           0 :     parse("REG_SCALE_MAX",scale_max_);
+     528           0 :     parse("REG_DSCALE",dscale_);
+     529             :     // checks
+     530           0 :     if(scale_max_<=scale_min_) error("with REGRESSION, REG_SCALE_MAX must be greater than REG_SCALE_MIN");
+     531           0 :     if(dscale_<=0.) error("with REGRESSION, REG_DSCALE must be positive");
+     532             :   }
+     533             : 
+     534             :   // scale factor
+     535          20 :   parse("SCALE", scale_);
+     536             : 
+     537             :   // read map resolution
+     538             :   double reso;
+     539          20 :   parse("RESOLUTION", reso);
+     540          20 :   if(reso<=0.) error("RESOLUTION should be strictly positive");
+     541             : 
+     542             :   // neighbor list stuff
+     543          20 :   parse("NL_CUTOFF",nl_cutoff_);
+     544          20 :   if(nl_cutoff_<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     545          20 :   parse("NL_STRIDE",nl_stride_);
+     546          20 :   if(nl_stride_<=0) error("NL_STRIDE should be explicitly specified and positive");
+     547             : 
+     548             :   // averaging or not
+     549          20 :   parseFlag("NO_AVER",no_aver_);
+     550             : 
+     551             :   // write overlap file
+     552          20 :   parse("WRITE_OV_STRIDE", ovstride_);
+     553          20 :   parse("WRITE_OV", ovfilename_);
+     554          20 :   if(ovstride_>0 && ovfilename_=="") error("With WRITE_OV_STRIDE you must specify WRITE_OV");
+     555             : 
+     556             :   // set parallel stuff
+     557          20 :   size_=comm.Get_size();
+     558          20 :   rank_=comm.Get_rank();
+     559             : 
+     560             :   // get number of replicas
+     561          20 :   if(rank_==0) {
+     562          14 :     if(no_aver_) {
+     563          12 :       nrep_ = 1;
+     564             :     } else {
+     565           2 :       nrep_ = multi_sim_comm.Get_size();
+     566             :     }
+     567          14 :     replica_ = multi_sim_comm.Get_rank();
+     568             :   } else {
+     569           6 :     nrep_ = 0;
+     570           6 :     replica_ = 0;
+     571             :   }
+     572          20 :   comm.Sum(&nrep_,1);
+     573          20 :   comm.Sum(&replica_,1);
+     574             : 
+     575             :   // Reweighting flag
+     576          20 :   parseFlag("REWEIGHT", do_reweight_);
+     577          20 :   if(do_reweight_&&getNumberOfArguments()!=1) error("To REWEIGHT one must provide one single bias as an argument");
+     578          20 :   if(do_reweight_&&no_aver_) error("REWEIGHT cannot be used with NO_AVER");
+     579          20 :   if(do_reweight_&&nrep_<2) error("REWEIGHT can only be used in parallel with 2 or more replicas");
+     580          20 :   if(!getRestart()) average_weights_.resize(nrep_, 1./static_cast<double>(nrep_));
+     581           0 :   else average_weights_.resize(nrep_, 0.);
+     582             : 
+     583          20 :   unsigned averaging=0;
+     584          20 :   parse("AVERAGING", averaging);
+     585          20 :   if(averaging>0) {
+     586           2 :     decay_w_ = 1./static_cast<double> (averaging);
+     587             :   }
+     588             : 
+     589          20 :   checkRead();
+     590             : 
+     591          20 :   log.printf("  atoms involved : ");
+     592       10876 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial());
+     593          20 :   log.printf("\n");
+     594          20 :   log.printf("  GMM data file : %s\n", GMM_file.c_str());
+     595          20 :   if(no_aver_) log.printf("  without ensemble averaging\n");
+     596          20 :   log.printf("  type of data noise : %s\n", noise.c_str());
+     597          20 :   log.printf("  neighbor list cutoff : %lf\n", nl_cutoff_);
+     598          20 :   log.printf("  neighbor list stride : %u\n",  nl_stride_);
+     599          20 :   log.printf("  minimum uncertainty : %f\n",sigma_min);
+     600          20 :   log.printf("  scale factor : %lf\n",scale_);
+     601          20 :   if(nregres_>0) {
+     602           0 :     log.printf("  regression stride : %u\n", nregres_);
+     603           0 :     log.printf("  regression minimum scale : %lf\n", scale_min_);
+     604           0 :     log.printf("  regression maximum scale : %lf\n", scale_max_);
+     605           0 :     log.printf("  regression maximum scale MC move : %lf\n", dscale_);
+     606             :   }
+     607          20 :   if(noise_!=2) {
+     608          14 :     log.printf("  initial value of the uncertainty : %f\n",sigma_ini);
+     609          14 :     log.printf("  max MC move in uncertainty : %f\n",dsigma);
+     610          14 :     log.printf("  MC stride : %u\n", MCstride_);
+     611          14 :     log.printf("  reading/writing to status file : %s\n",statusfilename_.c_str());
+     612          14 :     log.printf("  with stride : %u\n",statusstride_);
+     613             :   }
+     614          20 :   if(errfile.size()>0) log.printf("  reading experimental errors from file : %s\n", errfile.c_str());
+     615          20 :   if(ovfile.size()>0)  log.printf("  reading experimental overlaps from file : %s\n", ovfile.c_str());
+     616          20 :   log.printf("  temperature of the system in energy unit : %f\n",kbt_);
+     617          20 :   log.printf("  prior exponent : %f\n",prior_);
+     618          20 :   log.printf("  number of replicas for averaging: %u\n",nrep_);
+     619          20 :   log.printf("  id of the replica : %u\n",replica_);
+     620          20 :   if(nanneal_>0) {
+     621           0 :     log.printf("  length of annealing cycle : %u\n",nanneal_);
+     622           0 :     log.printf("  annealing factor : %f\n",kanneal_);
+     623             :   }
+     624          20 :   if(ovstride_>0) {
+     625           0 :     log.printf("  stride for writing model overlaps : %u\n",ovstride_);
+     626           0 :     log.printf("  file for writing model overlaps : %s\n", ovfilename_.c_str());
+     627             :   }
+     628             : 
+     629             :   // set constant quantity before calculating stuff
+     630          20 :   cfact_ = 1.0/pow( 2.0*pi, 1.5 );
+     631             : 
+     632             :   // calculate model GMM constant parameters
+     633          20 :   std::vector<double> GMM_m_w = get_GMM_m(atoms);
+     634             : 
+     635             :   // read data GMM parameters
+     636          20 :   get_GMM_d(GMM_file);
+     637          20 :   log.printf("  number of GMM components : %u\n", static_cast<unsigned>(GMM_d_m_.size()));
+     638             : 
+     639             :   // normalize atom weight map
+     640          40 :   if(norm_d <= 0.0) norm_d = accumulate(GMM_d_w_.begin(), GMM_d_w_.end(), 0.0);
+     641             :   double norm_m = accumulate(GMM_m_w.begin(),  GMM_m_w.end(),  0.0);
+     642             :   // renormalization
+     643         100 :   for(unsigned i=0; i<GMM_m_w_.size(); ++i) GMM_m_w_[i] *= norm_d / norm_m;
+     644             : 
+     645             :   // read experimental errors
+     646             :   std::vector<double> exp_err;
+     647          20 :   if(errfile.size()>0) exp_err = read_exp_errors(errfile);
+     648             : 
+     649             :   // get self overlaps between data GMM components
+     650          20 :   if(ovfile.size()>0) {
+     651           0 :     ovdd_ = read_exp_overlaps(ovfile);
+     652             :   } else {
+     653        1982 :     for(unsigned i=0; i<GMM_d_m_.size(); ++i) {
+     654        1962 :       double ov = get_self_overlap(i);
+     655        1962 :       ovdd_.push_back(ov);
+     656             :     }
+     657             :   }
+     658             : 
+     659          20 :   log.printf("  number of GMM groups : %u\n", static_cast<unsigned>(GMM_d_grps_.size()));
+     660             :   // cycle on GMM groups
+     661          40 :   for(unsigned Gid=0; Gid<GMM_d_grps_.size(); ++Gid) {
+     662          20 :     log.printf("    group %d\n", Gid);
+     663             :     // calculate median overlap and experimental error
+     664             :     std::vector<double> ovdd;
+     665             :     std::vector<double> err;
+     666             :     // cycle on the group members
+     667        1982 :     for(unsigned i=0; i<GMM_d_grps_[Gid].size(); ++i) {
+     668             :       // GMM id
+     669        1962 :       int GMMid = GMM_d_grps_[Gid][i];
+     670             :       // add to experimental error
+     671        1962 :       if(errfile.size()>0) err.push_back(exp_err[GMMid]);
+     672        1962 :       else                 err.push_back(0.);
+     673             :       // add to GMM overlap
+     674        1962 :       ovdd.push_back(ovdd_[GMMid]);
+     675             :     }
+     676             :     // calculate median quantities
+     677          20 :     double ovdd_m = get_median(ovdd);
+     678          20 :     double err_m  = get_median(err);
+     679             :     // print out statistics
+     680          20 :     log.printf("     # of members : %zu\n", GMM_d_grps_[Gid].size());
+     681          20 :     log.printf("     median overlap : %lf\n", ovdd_m);
+     682          20 :     log.printf("     median error : %lf\n", err_m);
+     683             :     // add minimum value of sigma for this group of GMMs
+     684          20 :     sigma_min_.push_back(std::sqrt(err_m*err_m+sigma_min*ovdd_m*sigma_min*ovdd_m));
+     685             :     // these are only needed with Gaussian and Outliers noise models
+     686          20 :     if(noise_!=2) {
+     687             :       // set dsigma
+     688          14 :       dsigma_.push_back(dsigma * ovdd_m);
+     689             :       // set sigma max
+     690          14 :       sigma_max_.push_back(10.0*ovdd_m + sigma_min_[Gid] + dsigma_[Gid]);
+     691             :       // initialize sigma
+     692          28 :       sigma_.push_back(std::max(sigma_min_[Gid],std::min(sigma_ini*ovdd_m,sigma_max_[Gid])));
+     693             :     }
+     694             :   }
+     695             : 
+     696             :   // read status file if restarting
+     697          20 :   if(getRestart() && noise_!=2) read_status();
+     698             : 
+     699             :   // calculate auxiliary stuff
+     700          20 :   calculate_useful_stuff(reso);
+     701             : 
+     702             :   // prepare data and derivative std::vectors
+     703          20 :   ovmd_.resize(ovdd_.size());
+     704          20 :   ovmd_ave_.resize(ovdd_.size());
+     705          20 :   atom_der_.resize(GMM_m_type_.size());
+     706          20 :   GMMid_der_.resize(ovdd_.size());
+     707             : 
+     708             :   // clear things that are no longer needed
+     709             :   GMM_d_cov_.clear();
+     710             : 
+     711             :   // add components
+     712          40 :   addComponentWithDerivatives("scoreb"); componentIsNotPeriodic("scoreb");
+     713             : 
+     714          48 :   if(noise_!=2) {addComponent("acc"); componentIsNotPeriodic("acc");}
+     715             : 
+     716          20 :   if(nregres_>0) {
+     717           0 :     addComponent("scale");     componentIsNotPeriodic("scale");
+     718           0 :     addComponent("accscale");  componentIsNotPeriodic("accscale");
+     719           0 :     addComponent("enescale");  componentIsNotPeriodic("enescale");
+     720             :   }
+     721             : 
+     722          20 :   if(nanneal_>0) {addComponent("anneal"); componentIsNotPeriodic("anneal");}
+     723             : 
+     724          20 :   if(do_reweight_) {
+     725           2 :     addComponent("biasDer");
+     726           2 :     componentIsNotPeriodic("biasDer");
+     727           2 :     addComponent("weight");
+     728           4 :     componentIsNotPeriodic("weight");
+     729             :   }
+     730             : 
+     731          20 :   addComponent("neff");
+     732          20 :   componentIsNotPeriodic("neff");
+     733             : 
+     734          34 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+     735          14 :     std::string num; Tools::convert(i, num);
+     736          28 :     addComponent("sigma-"+num); componentIsNotPeriodic("sigma-"+num);
+     737          28 :     getPntrToComponent("sigma-"+num)->set(sigma_[i]);
+     738             :   }
+     739             : 
+     740             :   // initialize random seed
+     741             :   unsigned iseed;
+     742          20 :   if(rank_==0) iseed = time(NULL)+replica_;
+     743           6 :   else iseed = 0;
+     744          20 :   comm.Sum(&iseed, 1);
+     745          20 :   random_.setSeed(-iseed);
+     746             : 
+     747             :   // request the atoms
+     748          20 :   requestAtoms(atoms);
+     749          20 :   setDerivatives();
+     750             : 
+     751             :   // print bibliography
+     752          40 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     753          40 :   log<<plumed.cite("Hanot, Bonomi, Greenberg, Sali, Nilges, Vendruscolo, Pellarin, bioRxiv doi: 10.1101/113951 (2017)");
+     754          40 :   log<<plumed.cite("Bonomi, Pellarin, Vendruscolo, Biophys. J. 114, 1604 (2018)");
+     755          24 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     756          24 :   if(!no_aver_ && nrep_>1)log<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     757          20 :   log<<"\n";
+     758          20 : }
+     759             : 
+     760           0 : void EMMI::write_model_overlap(long int step)
+     761             : {
+     762           0 :   OFile ovfile;
+     763           0 :   ovfile.link(*this);
+     764           0 :   std::string num; Tools::convert(step,num);
+     765           0 :   std::string name = ovfilename_+"-"+num;
+     766           0 :   ovfile.open(name);
+     767             :   ovfile.setHeavyFlush();
+     768           0 :   ovfile.fmtField("%10.7e ");
+     769             : // write overlaps
+     770           0 :   for(int i=0; i<ovmd_.size(); ++i) {
+     771           0 :     ovfile.printField("Model", ovmd_[i]);
+     772           0 :     ovfile.printField("ModelScaled", scale_ * ovmd_[i]);
+     773           0 :     ovfile.printField("Data", ovdd_[i]);
+     774           0 :     ovfile.printField();
+     775             :   }
+     776           0 :   ovfile.close();
+     777           0 : }
+     778             : 
+     779          40 : double EMMI::get_median(std::vector<double> &v)
+     780             : {
+     781             : // dimension of std::vector
+     782          40 :   unsigned size = v.size();
+     783             : // in case of only one entry
+     784          40 :   if (size==1) {
+     785           0 :     return v[0];
+     786             :   } else {
+     787             :     // reorder std::vector
+     788          40 :     sort(v.begin(), v.end());
+     789             :     // odd or even?
+     790          40 :     if (size%2==0) {
+     791           4 :       return (v[size/2-1]+v[size/2])/2.0;
+     792             :     } else {
+     793          36 :       return v[size/2];
+     794             :     }
+     795             :   }
+     796             : }
+     797             : 
+     798           0 : void EMMI::read_status()
+     799             : {
+     800             :   double MDtime;
+     801             : // open file
+     802           0 :   auto ifile = Tools::make_unique<IFile>();
+     803           0 :   ifile->link(*this);
+     804           0 :   if(ifile->FileExist(statusfilename_)) {
+     805           0 :     ifile->open(statusfilename_);
+     806           0 :     while(ifile->scanField("MD_time", MDtime)) {
+     807           0 :       for(unsigned i=0; i<sigma_.size(); ++i) {
+     808             :         // convert i to std::string
+     809           0 :         std::string num; Tools::convert(i,num);
+     810             :         // read entries
+     811           0 :         ifile->scanField("s"+num, sigma_[i]);
+     812             :       }
+     813             :       // new line
+     814           0 :       ifile->scanField();
+     815             :     }
+     816           0 :     ifile->close();
+     817             :   } else {
+     818           0 :     error("Cannot find status file "+statusfilename_+"\n");
+     819             :   }
+     820           0 : }
+     821             : 
+     822       10904 : void EMMI::print_status(long int step)
+     823             : {
+     824             : // if first time open the file
+     825       10904 :   if(first_status_) {
+     826          14 :     first_status_ = false;
+     827          14 :     statusfile_.link(*this);
+     828          14 :     statusfile_.open(statusfilename_);
+     829             :     statusfile_.setHeavyFlush();
+     830          28 :     statusfile_.fmtField("%6.3e ");
+     831             :   }
+     832             : // write fields
+     833       10904 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     834       10904 :   statusfile_.printField("MD_time", MDtime);
+     835       21808 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+     836             :     // convert i to std::string
+     837       10904 :     std::string num; Tools::convert(i,num);
+     838             :     // print entry
+     839       21808 :     statusfile_.printField("s"+num, sigma_[i]);
+     840             :   }
+     841       10904 :   statusfile_.printField();
+     842       10904 : }
+     843             : 
+     844           0 : bool EMMI::doAccept(double oldE, double newE, double kbt) {
+     845             :   bool accept = false;
+     846             :   // calculate delta energy
+     847           0 :   double delta = ( newE - oldE ) / kbt;
+     848             :   // if delta is negative always accept move
+     849           0 :   if( delta < 0.0 ) {
+     850             :     accept = true;
+     851             :   } else {
+     852             :     // otherwise extract random number
+     853           0 :     double s = random_.RandU01();
+     854           0 :     if( s < std::exp(-delta) ) { accept = true; }
+     855             :   }
+     856           0 :   return accept;
+     857             : }
+     858             : 
+     859           0 : void EMMI::doMonteCarlo()
+     860             : {
+     861             :   // extract random GMM group
+     862           0 :   unsigned nGMM = static_cast<unsigned>(std::floor(random_.RandU01()*static_cast<double>(GMM_d_grps_.size())));
+     863           0 :   if(nGMM==GMM_d_grps_.size()) nGMM -= 1;
+     864             : 
+     865             :   // generate random move
+     866           0 :   double shift = dsigma_[nGMM] * ( 2.0 * random_.RandU01() - 1.0 );
+     867             :   // new sigma
+     868           0 :   double new_s = sigma_[nGMM] + shift;
+     869             :   // check boundaries
+     870           0 :   if(new_s > sigma_max_[nGMM]) {new_s = 2.0 * sigma_max_[nGMM] - new_s;}
+     871           0 :   if(new_s < sigma_min_[nGMM]) {new_s = 2.0 * sigma_min_[nGMM] - new_s;}
+     872             :   // old s2
+     873           0 :   double old_inv_s2 = 1.0 / sigma_[nGMM] / sigma_[nGMM];
+     874             :   // new s2
+     875           0 :   double new_inv_s2 = 1.0 / new_s / new_s;
+     876             : 
+     877             :   // cycle on GMM group and calculate old and new energy
+     878             :   double old_ene = 0.0;
+     879             :   double new_ene = 0.0;
+     880           0 :   double ng = static_cast<double>(GMM_d_grps_[nGMM].size());
+     881             : 
+     882             :   // in case of Gaussian noise
+     883           0 :   if(noise_==0) {
+     884             :     double chi2 = 0.0;
+     885           0 :     for(unsigned i=0; i<GMM_d_grps_[nGMM].size(); ++i) {
+     886             :       // id GMM component
+     887           0 :       int GMMid = GMM_d_grps_[nGMM][i];
+     888             :       // deviation
+     889           0 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] );
+     890             :       // add to chi2
+     891           0 :       chi2 += dev * dev;
+     892             :     }
+     893             :     // final energy calculation: add normalization and prior
+     894           0 :     old_ene = 0.5 * kbt_ * ( chi2 * old_inv_s2 - (ng+prior_) * std::log(old_inv_s2) );
+     895           0 :     new_ene = 0.5 * kbt_ * ( chi2 * new_inv_s2 - (ng+prior_) * std::log(new_inv_s2) );
+     896             :   }
+     897             : 
+     898             :   // in case of Outliers noise
+     899           0 :   if(noise_==1) {
+     900           0 :     for(unsigned i=0; i<GMM_d_grps_[nGMM].size(); ++i) {
+     901             :       // id GMM component
+     902           0 :       int GMMid = GMM_d_grps_[nGMM][i];
+     903             :       // calculate deviation
+     904           0 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] );
+     905             :       // add to energies
+     906           0 :       old_ene += std::log( 1.0 + 0.5 * dev * dev * old_inv_s2);
+     907           0 :       new_ene += std::log( 1.0 + 0.5 * dev * dev * new_inv_s2);
+     908             :     }
+     909             :     // final energy calculation: add normalization and prior
+     910           0 :     old_ene = kbt_ * ( old_ene + (ng+prior_) * std::log(sigma_[nGMM]) );
+     911           0 :     new_ene = kbt_ * ( new_ene + (ng+prior_) * std::log(new_s) );
+     912             :   }
+     913             : 
+     914             :   // increment number of trials
+     915           0 :   MCtrials_ += 1.0;
+     916             : 
+     917             :   // accept or reject
+     918           0 :   bool accept = doAccept(old_ene/anneal_, new_ene/anneal_, kbt_);
+     919           0 :   if(accept) {
+     920           0 :     sigma_[nGMM] = new_s;
+     921           0 :     MCaccept_ += 1.0;
+     922             :   }
+     923             :   // local communication
+     924           0 :   if(rank_!=0) {
+     925           0 :     for(unsigned i=0; i<sigma_.size(); ++i) sigma_[i] = 0.0;
+     926           0 :     MCaccept_ = 0.0;
+     927             :   }
+     928           0 :   if(size_>1) {
+     929           0 :     comm.Sum(&sigma_[0], sigma_.size());
+     930           0 :     comm.Sum(&MCaccept_, 1);
+     931             :   }
+     932             : 
+     933             :   // update sigma output
+     934           0 :   std::string num; Tools::convert(nGMM, num);
+     935           0 :   getPntrToComponent("sigma-"+num)->set(sigma_[nGMM]);
+     936           0 : }
+     937             : 
+     938           0 : std::vector<double> EMMI::read_exp_errors(std::string errfile)
+     939             : {
+     940             :   int nexp, idcomp;
+     941             :   double err;
+     942             :   std::vector<double> exp_err;
+     943             : // open file
+     944           0 :   IFile *ifile = new IFile();
+     945           0 :   if(ifile->FileExist(errfile)) {
+     946           0 :     ifile->open(errfile);
+     947             :     // scan for number of experimental errors
+     948           0 :     ifile->scanField("Nexp", nexp);
+     949             :     // cycle on GMM components
+     950           0 :     while(ifile->scanField("Id",idcomp)) {
+     951             :       // total experimental error
+     952           0 :       double err_tot = 0.0;
+     953             :       // cycle on number of experimental overlaps
+     954           0 :       for(unsigned i=0; i<nexp; ++i) {
+     955           0 :         std::string ss; Tools::convert(i,ss);
+     956           0 :         ifile->scanField("Err"+ss, err);
+     957             :         // add to total error
+     958           0 :         err_tot += err*err;
+     959             :       }
+     960             :       // new line
+     961           0 :       ifile->scanField();
+     962             :       // calculate RMSE
+     963           0 :       err_tot = std::sqrt(err_tot/static_cast<double>(nexp));
+     964             :       // add to global
+     965           0 :       exp_err.push_back(err_tot);
+     966             :     }
+     967           0 :     ifile->close();
+     968             :   } else {
+     969           0 :     error("Cannot find ERR_FILE "+errfile+"\n");
+     970             :   }
+     971           0 :   return exp_err;
+     972             : }
+     973             : 
+     974           0 : std::vector<double> EMMI::read_exp_overlaps(std::string ovfile)
+     975             : {
+     976             :   int idcomp;
+     977             :   double ov;
+     978             :   std::vector<double> ovdd;
+     979             : // open file
+     980           0 :   IFile *ifile = new IFile();
+     981           0 :   if(ifile->FileExist(ovfile)) {
+     982           0 :     ifile->open(ovfile);
+     983             :     // cycle on GMM components
+     984           0 :     while(ifile->scanField("Id",idcomp)) {
+     985             :       // read experimental overlap
+     986           0 :       ifile->scanField("Overlap", ov);
+     987             :       // add to ovdd
+     988           0 :       ovdd.push_back(ov);
+     989             :       // new line
+     990           0 :       ifile->scanField();
+     991             :     }
+     992           0 :     ifile->close();
+     993             :   } else {
+     994           0 :     error("Cannot find OV_FILE "+ovfile+"\n");
+     995             :   }
+     996           0 :   return ovdd;
+     997             : }
+     998             : 
+     999          20 : std::vector<double> EMMI::get_GMM_m(std::vector<AtomNumber> &atoms)
+    1000             : {
+    1001             :   // list of weights - one per atom
+    1002             :   std::vector<double> GMM_m_w;
+    1003             : 
+    1004          20 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    1005             :   // map of atom types to A and B coefficients of scattering factor
+    1006             :   // f(s) = A * exp(-B*s**2)
+    1007             :   // B is in Angstrom squared
+    1008             :   // map between an atom type and an index
+    1009             :   std::map<std::string, unsigned> type_map;
+    1010          20 :   type_map["C"]=0;
+    1011          20 :   type_map["O"]=1;
+    1012          20 :   type_map["N"]=2;
+    1013          20 :   type_map["S"]=3;
+    1014             :   // fill in sigma std::vector
+    1015          20 :   GMM_m_s_.push_back(0.01*15.146);  // type 0
+    1016          20 :   GMM_m_s_.push_back(0.01*8.59722); // type 1
+    1017          20 :   GMM_m_s_.push_back(0.01*11.1116); // type 2
+    1018          20 :   GMM_m_s_.push_back(0.01*15.8952); // type 3
+    1019             :   // fill in weight std::vector
+    1020          20 :   GMM_m_w_.push_back(2.49982); // type 0
+    1021          20 :   GMM_m_w_.push_back(1.97692); // type 1
+    1022          20 :   GMM_m_w_.push_back(2.20402); // type 2
+    1023          20 :   GMM_m_w_.push_back(5.14099); // type 3
+    1024             : 
+    1025             :   // check if MOLINFO line is present
+    1026          20 :   if( moldat ) {
+    1027          20 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+    1028       10876 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    1029             :       // get atom name
+    1030       10856 :       std::string name = moldat->getAtomName(atoms[i]);
+    1031             :       char type;
+    1032             :       // get atom type
+    1033       10856 :       char first = name.at(0);
+    1034             :       // GOLDEN RULE: type is first letter, if not a number
+    1035       10856 :       if (!isdigit(first)) {
+    1036             :         type = first;
+    1037             :         // otherwise is the second
+    1038             :       } else {
+    1039           0 :         type = name.at(1);
+    1040             :       }
+    1041             :       // check if key in map
+    1042       10856 :       std::string type_s = std::string(1,type);
+    1043       10856 :       if(type_map.find(type_s) != type_map.end()) {
+    1044             :         // save atom type
+    1045       10856 :         GMM_m_type_.push_back(type_map[type_s]);
+    1046             :         // this will be normalized in the final density
+    1047       10856 :         GMM_m_w.push_back(GMM_m_w_[type_map[type_s]]);
+    1048             :       } else {
+    1049           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    1050             :       }
+    1051             :     }
+    1052             :   } else {
+    1053           0 :     error("MOLINFO DATA not found\n");
+    1054             :   }
+    1055          20 :   return GMM_m_w;
+    1056             : }
+    1057             : 
+    1058        1962 : void EMMI::check_GMM_d(const VectorGeneric<6> &cov, double w)
+    1059             : {
+    1060             : 
+    1061             : // check if positive defined, by calculating the 3 leading principal minors
+    1062        1962 :   double pm1 = cov[0];
+    1063        1962 :   double pm2 = cov[0]*cov[3]-cov[1]*cov[1];
+    1064        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]);
+    1065             : // apply Sylvester’s criterion
+    1066        1962 :   if(pm1<=0.0 || pm2<=0.0 || pm3<=0.0)
+    1067           0 :     error("check data GMM: covariance matrix is not positive defined");
+    1068             : 
+    1069             : // check if weight is positive
+    1070        1962 :   if(w<=0) error("check data GMM: weight must be positive");
+    1071        1962 : }
+    1072             : 
+    1073             : // read GMM data file in PLUMED format:
+    1074          20 : void EMMI::get_GMM_d(std::string GMM_file)
+    1075             : {
+    1076          20 :   VectorGeneric<6> cov;
+    1077             : 
+    1078             : // open file
+    1079          20 :   auto ifile=Tools::make_unique<IFile>();
+    1080          20 :   if(ifile->FileExist(GMM_file)) {
+    1081          20 :     ifile->open(GMM_file);
+    1082             :     int idcomp;
+    1083        3964 :     while(ifile->scanField("Id",idcomp)) {
+    1084             :       int beta;
+    1085             :       double w, m0, m1, m2;
+    1086        3924 :       ifile->scanField("Weight",w);
+    1087        3924 :       ifile->scanField("Mean_0",m0);
+    1088        3924 :       ifile->scanField("Mean_1",m1);
+    1089        3924 :       ifile->scanField("Mean_2",m2);
+    1090        3924 :       ifile->scanField("Cov_00",cov[0]);
+    1091        3924 :       ifile->scanField("Cov_01",cov[1]);
+    1092        3924 :       ifile->scanField("Cov_02",cov[2]);
+    1093        3924 :       ifile->scanField("Cov_11",cov[3]);
+    1094        3924 :       ifile->scanField("Cov_12",cov[4]);
+    1095        3924 :       ifile->scanField("Cov_22",cov[5]);
+    1096        1962 :       ifile->scanField("Beta",beta);
+    1097             :       // check input
+    1098        1962 :       check_GMM_d(cov, w);
+    1099             :       // check beta
+    1100        1962 :       if(beta<0) error("Beta must be positive!");
+    1101             :       // center of the Gaussian
+    1102        1962 :       GMM_d_m_.push_back(Vector(m0,m1,m2));
+    1103             :       // covariance matrix
+    1104        1962 :       GMM_d_cov_.push_back(cov);
+    1105             :       // weight
+    1106        1962 :       GMM_d_w_.push_back(w);
+    1107             :       // beta
+    1108        1962 :       GMM_d_beta_.push_back(beta);
+    1109             :       // new line
+    1110        1962 :       ifile->scanField();
+    1111             :     }
+    1112             :   } else {
+    1113           0 :     error("Cannot find GMM_FILE "+GMM_file+"\n");
+    1114             :   }
+    1115             :   // now create a set from beta (unique set of values)
+    1116          20 :   std::set<int> bu(GMM_d_beta_.begin(), GMM_d_beta_.end());
+    1117             :   // now prepare the group std::vector
+    1118          20 :   GMM_d_grps_.resize(bu.size());
+    1119             :   // and fill it in
+    1120        1982 :   for(unsigned i=0; i<GMM_d_beta_.size(); ++i) {
+    1121        1962 :     if(GMM_d_beta_[i]>=GMM_d_grps_.size()) error("Check Beta values");
+    1122        1962 :     GMM_d_grps_[GMM_d_beta_[i]].push_back(i);
+    1123             :   }
+    1124          20 : }
+    1125             : 
+    1126          20 : void EMMI::calculate_useful_stuff(double reso)
+    1127             : {
+    1128             :   // We use the following definition for resolution:
+    1129             :   // the Fourier transform of the density distribution in real space
+    1130             :   // f(s) falls to 1/e of its maximum value at wavenumber 1/resolution
+    1131             :   // i.e. from f(s) = A * exp(-B*s**2) -> Res = std::sqrt(B).
+    1132             :   // average value of B
+    1133             :   double Bave = 0.0;
+    1134       10876 :   for(unsigned i=0; i<GMM_m_type_.size(); ++i) {
+    1135       10856 :     Bave += GMM_m_s_[GMM_m_type_[i]];
+    1136             :   }
+    1137          20 :   Bave /= static_cast<double>(GMM_m_type_.size());
+    1138             :   // calculate blur factor
+    1139             :   double blur = 0.0;
+    1140          20 :   if(reso*reso>Bave) blur = reso*reso-Bave;
+    1141          36 :   else warning("PLUMED should not be used with maps at resolution better than 0.3 nm");
+    1142             :   // add blur to B
+    1143         100 :   for(unsigned i=0; i<GMM_m_s_.size(); ++i) GMM_m_s_[i] += blur;
+    1144             :   // calculate average resolution
+    1145             :   double ave_res = 0.0;
+    1146       10876 :   for(unsigned i=0; i<GMM_m_type_.size(); ++i) {
+    1147       10856 :     ave_res += std::sqrt(GMM_m_s_[GMM_m_type_[i]]);
+    1148             :   }
+    1149          20 :   ave_res = ave_res / static_cast<double>(GMM_m_type_.size());
+    1150          20 :   log.printf("  experimental map resolution : %3.2f\n", reso);
+    1151          20 :   log.printf("  predicted map resolution : %3.2f\n", ave_res);
+    1152          20 :   log.printf("  blur factor : %f\n", blur);
+    1153             :   // now calculate useful stuff
+    1154          20 :   VectorGeneric<6> cov, sum, inv_sum;
+    1155             :   // cycle on all atoms types (4 for the moment)
+    1156         100 :   for(unsigned i=0; i<GMM_m_s_.size(); ++i) {
+    1157             :     // the Gaussian in density (real) space is the FT of scattering factor
+    1158             :     // f(r) = A * (pi/B)**1.5 * exp(-pi**2/B*r**2)
+    1159          80 :     double s = std::sqrt ( 0.5 * GMM_m_s_[i] ) / pi;
+    1160             :     // covariance matrix for spherical Gaussian
+    1161          80 :     cov[0]=s*s; cov[1]=0.0; cov[2]=0.0;
+    1162          80 :     cov[3]=s*s; cov[4]=0.0;
+    1163          80 :     cov[5]=s*s;
+    1164             :     // cycle on all data GMM
+    1165        7928 :     for(unsigned j=0; j<GMM_d_m_.size(); ++j) {
+    1166             :       // we need the sum of the covariance matrices
+    1167       54936 :       for(unsigned k=0; k<6; ++k) sum[k] = cov[k] + GMM_d_cov_[j][k];
+    1168             :       // and to calculate its determinant
+    1169        7848 :       double det = sum[0]*(sum[3]*sum[5]-sum[4]*sum[4]);
+    1170        7848 :       det -= sum[1]*(sum[1]*sum[5]-sum[4]*sum[2]);
+    1171        7848 :       det += sum[2]*(sum[1]*sum[4]-sum[3]*sum[2]);
+    1172             :       // calculate prefactor - model weights are already normalized
+    1173        7848 :       double pre_fact =  cfact_ / std::sqrt(det) * GMM_d_w_[j] * GMM_m_w_[i];
+    1174             :       // and its inverse
+    1175        7848 :       inv_sum[0] = (sum[3]*sum[5] - sum[4]*sum[4])/det;
+    1176        7848 :       inv_sum[1] = (sum[2]*sum[4] - sum[1]*sum[5])/det;
+    1177        7848 :       inv_sum[2] = (sum[1]*sum[4] - sum[2]*sum[3])/det;
+    1178        7848 :       inv_sum[3] = (sum[0]*sum[5] - sum[2]*sum[2])/det;
+    1179        7848 :       inv_sum[4] = (sum[2]*sum[1] - sum[0]*sum[4])/det;
+    1180        7848 :       inv_sum[5] = (sum[0]*sum[3] - sum[1]*sum[1])/det;
+    1181             :       // now we store the prefactor
+    1182        7848 :       pre_fact_.push_back(pre_fact);
+    1183             :       // and the inverse of the sum
+    1184        7848 :       inv_cov_md_.push_back(inv_sum);
+    1185             :     }
+    1186             :   }
+    1187             :   // tabulate exponential
+    1188          20 :   dexp_ = dpcutoff_ / static_cast<double> (nexp_-1);
+    1189    20000020 :   for(unsigned i=0; i<nexp_; ++i) {
+    1190    20000000 :     tab_exp_.push_back(std::exp(-static_cast<double>(i) * dexp_));
+    1191             :   }
+    1192          20 : }
+    1193             : 
+    1194             : // get prefactors
+    1195     1621458 : double EMMI::get_prefactor_inverse
+    1196             : (const VectorGeneric<6> &GMM_cov_0, const VectorGeneric<6> &GMM_cov_1,
+    1197             :  double GMM_w_0, double GMM_w_1,
+    1198             :  VectorGeneric<6> &sum, VectorGeneric<6> &inv_sum)
+    1199             : {
+    1200             : // we need the sum of the covariance matrices
+    1201    11350206 :   for(unsigned k=0; k<6; ++k) sum[k] = GMM_cov_0[k] + GMM_cov_1[k];
+    1202             : 
+    1203             : // and to calculate its determinant
+    1204     1621458 :   double det = sum[0]*(sum[3]*sum[5]-sum[4]*sum[4]);
+    1205     1621458 :   det -= sum[1]*(sum[1]*sum[5]-sum[4]*sum[2]);
+    1206     1621458 :   det += sum[2]*(sum[1]*sum[4]-sum[3]*sum[2]);
+    1207             : 
+    1208             : // the prefactor is
+    1209     1621458 :   double pre_fact =  cfact_ / std::sqrt(det) * GMM_w_0 * GMM_w_1;
+    1210             : 
+    1211             : // and its inverse
+    1212     1621458 :   inv_sum[0] = (sum[3]*sum[5] - sum[4]*sum[4])/det;
+    1213     1621458 :   inv_sum[1] = (sum[2]*sum[4] - sum[1]*sum[5])/det;
+    1214     1621458 :   inv_sum[2] = (sum[1]*sum[4] - sum[2]*sum[3])/det;
+    1215     1621458 :   inv_sum[3] = (sum[0]*sum[5] - sum[2]*sum[2])/det;
+    1216     1621458 :   inv_sum[4] = (sum[2]*sum[1] - sum[0]*sum[4])/det;
+    1217     1621458 :   inv_sum[5] = (sum[0]*sum[3] - sum[1]*sum[1])/det;
+    1218             : 
+    1219             : // return pre-factor
+    1220     1621458 :   return pre_fact;
+    1221             : }
+    1222             : 
+    1223        1962 : double EMMI::get_self_overlap(unsigned id)
+    1224             : {
+    1225             :   double ov_tot = 0.0;
+    1226        1962 :   VectorGeneric<6> sum, inv_sum;
+    1227        1962 :   Vector ov_der;
+    1228             : // start loop
+    1229     1623420 :   for(unsigned i=0; i<GMM_d_m_.size(); ++i) {
+    1230             :     // call auxiliary method
+    1231     1621458 :     double pre_fact = get_prefactor_inverse(GMM_d_cov_[id], GMM_d_cov_[i],
+    1232     1621458 :                                             GMM_d_w_[id],   GMM_d_w_[i], sum, inv_sum);
+    1233             :     // add overlap to ov_tot
+    1234     1621458 :     ov_tot += get_overlap(GMM_d_m_[id], GMM_d_m_[i], pre_fact, inv_sum, ov_der);
+    1235             :   }
+    1236             : // and return it
+    1237        1962 :   return ov_tot;
+    1238             : }
+    1239             : 
+    1240             : // get overlap and derivatives
+    1241     3732816 : double EMMI::get_overlap(const Vector &m_m, const Vector &d_m, double pre_fact,
+    1242             :                          const VectorGeneric<6> &inv_cov_md, Vector &ov_der)
+    1243             : {
+    1244     3732816 :   Vector md;
+    1245             :   // calculate std::vector difference m_m-d_m with/without pbc
+    1246     3732816 :   if(pbc_) md = pbcDistance(d_m, m_m);
+    1247     3732816 :   else     md = delta(d_m, m_m);
+    1248             :   // calculate product of transpose of md and inv_cov_md
+    1249     3732816 :   double p_x = md[0]*inv_cov_md[0]+md[1]*inv_cov_md[1]+md[2]*inv_cov_md[2];
+    1250     3732816 :   double p_y = md[0]*inv_cov_md[1]+md[1]*inv_cov_md[3]+md[2]*inv_cov_md[4];
+    1251     3732816 :   double p_z = md[0]*inv_cov_md[2]+md[1]*inv_cov_md[4]+md[2]*inv_cov_md[5];
+    1252             :   // calculate product of prod and md
+    1253     3732816 :   double ov = md[0]*p_x+md[1]*p_y+md[2]*p_z;
+    1254             :   // final calculation
+    1255     3732816 :   ov = pre_fact * std::exp(-0.5*ov);
+    1256             :   // derivatives
+    1257     3732816 :   ov_der = ov * Vector(p_x, p_y, p_z);
+    1258     3732816 :   return ov;
+    1259             : }
+    1260             : 
+    1261             : // get the exponent of the overlap
+    1262    59085036 : double EMMI::get_exp_overlap(const Vector &m_m, const Vector &d_m,
+    1263             :                              const VectorGeneric<6> &inv_cov_md)
+    1264             : {
+    1265    59085036 :   Vector md;
+    1266             :   // calculate std::vector difference m_m-d_m with/without pbc
+    1267    59085036 :   if(pbc_) md = pbcDistance(d_m, m_m);
+    1268    59085036 :   else     md = delta(d_m, m_m);
+    1269             :   // calculate product of transpose of md and inv_cov_md
+    1270    59085036 :   double p_x = md[0]*inv_cov_md[0]+md[1]*inv_cov_md[1]+md[2]*inv_cov_md[2];
+    1271    59085036 :   double p_y = md[0]*inv_cov_md[1]+md[1]*inv_cov_md[3]+md[2]*inv_cov_md[4];
+    1272    59085036 :   double p_z = md[0]*inv_cov_md[2]+md[1]*inv_cov_md[4]+md[2]*inv_cov_md[5];
+    1273             :   // calculate product of prod and md
+    1274    59085036 :   double ov = md[0]*p_x+md[1]*p_y+md[2]*p_z;
+    1275    59085036 :   return ov;
+    1276             : }
+    1277             : 
+    1278       16355 : void EMMI::update_neighbor_list()
+    1279             : {
+    1280             :   // dimension of GMM and atom std::vectors
+    1281       16355 :   unsigned GMM_d_size = GMM_d_m_.size();
+    1282       16355 :   unsigned GMM_m_size = GMM_m_type_.size();
+    1283             :   // local neighbor list
+    1284             :   std::vector < unsigned > nl_l;
+    1285             :   // clear old neighbor list
+    1286       16355 :   nl_.clear();
+    1287             : 
+    1288             :   // cycle on GMM components - in parallel
+    1289      116273 :   for(unsigned id=rank_; id<GMM_d_size; id+=size_) {
+    1290             :     // overlap lists and map
+    1291             :     std::vector<double> ov_l;
+    1292             :     std::map<double, unsigned> ov_m;
+    1293             :     // total overlap with id
+    1294             :     double ov_tot = 0.0;
+    1295             :     // cycle on all atoms
+    1296    59184954 :     for(unsigned im=0; im<GMM_m_size; ++im) {
+    1297             :       // get index in auxiliary lists
+    1298    59085036 :       unsigned kaux = GMM_m_type_[im] * GMM_d_size + id;
+    1299             :       // calculate exponent of overlap
+    1300    59085036 :       double expov = get_exp_overlap(GMM_d_m_[id], getPosition(im), inv_cov_md_[kaux]);
+    1301             :       // get index of 0.5*expov in tabulated exponential
+    1302    59085036 :       unsigned itab = static_cast<unsigned> (round( 0.5*expov/dexp_ ));
+    1303             :       // check boundaries and skip atom in case
+    1304    59085036 :       if(itab >= tab_exp_.size()) continue;
+    1305             :       // in case calculate overlap
+    1306     4133388 :       double ov = pre_fact_[kaux] * tab_exp_[itab];
+    1307             :       // add to list
+    1308     4133388 :       ov_l.push_back(ov);
+    1309             :       // and map to retrieve atom index
+    1310     4133388 :       ov_m[ov] = im;
+    1311             :       // increase ov_tot
+    1312     4133388 :       ov_tot += ov;
+    1313             :     }
+    1314             :     // check if zero size -> ov_tot = 0
+    1315       99918 :     if(ov_l.size()==0) continue;
+    1316             :     // define cutoff
+    1317       99842 :     double ov_cut = ov_tot * nl_cutoff_;
+    1318             :     // sort ov_l in ascending order
+    1319       99842 :     std::sort(ov_l.begin(), ov_l.end());
+    1320             :     // integrate ov_l
+    1321             :     double res = 0.0;
+    1322     2146102 :     for(unsigned i=0; i<ov_l.size(); ++i) {
+    1323     2146102 :       res += ov_l[i];
+    1324             :       // if exceeding the cutoff for overlap, stop
+    1325     2146102 :       if(res >= ov_cut) break;
+    1326             :       else ov_m.erase(ov_l[i]);
+    1327             :     }
+    1328             :     // now add atoms to neighborlist
+    1329     2186970 :     for(std::map<double, unsigned>::iterator it=ov_m.begin(); it!=ov_m.end(); ++it)
+    1330     2087128 :       nl_l.push_back(id*GMM_m_size+it->second);
+    1331             :     // end cycle on GMM components in parallel
+    1332             :   }
+    1333             :   // find total dimension of neighborlist
+    1334       16355 :   std::vector <int> recvcounts(size_, 0);
+    1335       16355 :   recvcounts[rank_] = nl_l.size();
+    1336       16355 :   comm.Sum(&recvcounts[0], size_);
+    1337             :   int tot_size = accumulate(recvcounts.begin(), recvcounts.end(), 0);
+    1338             :   // resize neighbor stuff
+    1339       16355 :   nl_.resize(tot_size);
+    1340             :   // calculate std::vector of displacement
+    1341       16355 :   std::vector<int> disp(size_);
+    1342       16355 :   disp[0] = 0;
+    1343             :   int rank_size = 0;
+    1344       27257 :   for(unsigned i=0; i<size_-1; ++i) {
+    1345       10902 :     rank_size += recvcounts[i];
+    1346       10902 :     disp[i+1] = rank_size;
+    1347             :   }
+    1348             :   // Allgather neighbor list
+    1349       16355 :   comm.Allgatherv(&nl_l[0], recvcounts[rank_], &nl_[0], &recvcounts[0], &disp[0]);
+    1350             :   // now resize derivatives
+    1351       16355 :   ovmd_der_.resize(tot_size);
+    1352       16355 : }
+    1353             : 
+    1354          30 : void EMMI::prepare()
+    1355             : {
+    1356          30 :   if(getExchangeStep()) first_time_=true;
+    1357          30 : }
+    1358             : 
+    1359             : // overlap calculator
+    1360       16365 : void EMMI::calculate_overlap() {
+    1361             : 
+    1362       16365 :   if(first_time_ || getExchangeStep() || getStep()%nl_stride_==0) {
+    1363       16355 :     update_neighbor_list();
+    1364       16355 :     first_time_=false;
+    1365             :   }
+    1366             : 
+    1367             :   // clean temporary std::vectors
+    1368      174342 :   for(unsigned i=0; i<ovmd_.size(); ++i)     ovmd_[i] = 0.0;
+    1369     3168864 :   for(unsigned i=0; i<ovmd_der_.size(); ++i) ovmd_der_[i] = Vector(0,0,0);
+    1370             : 
+    1371             :   // we have to cycle over all model and data GMM components in the neighbor list
+    1372       16365 :   unsigned GMM_d_size = GMM_d_m_.size();
+    1373       16365 :   unsigned GMM_m_size = GMM_m_type_.size();
+    1374     2127723 :   for(unsigned i=rank_; i<nl_.size(); i=i+size_) {
+    1375             :     // get data (id) and atom (im) indexes
+    1376     2111358 :     unsigned id = nl_[i] / GMM_m_size;
+    1377     2111358 :     unsigned im = nl_[i] % GMM_m_size;
+    1378             :     // get index in auxiliary lists
+    1379     2111358 :     unsigned kaux = GMM_m_type_[im] * GMM_d_size + id;
+    1380             :     // add overlap with im component of model GMM
+    1381     2111358 :     ovmd_[id] += get_overlap(GMM_d_m_[id], getPosition(im), pre_fact_[kaux],
+    1382     2111358 :                              inv_cov_md_[kaux], ovmd_der_[i]);
+    1383             :   }
+    1384             :   // communicate stuff
+    1385       16365 :   if(size_>1) {
+    1386       10902 :     comm.Sum(&ovmd_[0], ovmd_.size());
+    1387       10902 :     comm.Sum(&ovmd_der_[0][0], 3*ovmd_der_.size());
+    1388             :   }
+    1389       16365 : }
+    1390             : 
+    1391           0 : double EMMI::scaleEnergy(double s)
+    1392             : {
+    1393             :   double ene = 0.0;
+    1394           0 :   for(unsigned i=0; i<ovdd_.size(); ++i) {
+    1395           0 :     ene += std::log( abs ( s * ovmd_ave_[i] - ovdd_[i] ) );
+    1396             :   }
+    1397           0 :   return ene;
+    1398             : }
+    1399             : 
+    1400           0 : double EMMI::doRegression()
+    1401             : {
+    1402             : // standard MC parameters
+    1403             :   unsigned MCsteps = 100000;
+    1404             :   double kbtmin = 1.0;
+    1405             :   double kbtmax = 10.0;
+    1406             :   unsigned ncold = 5000;
+    1407             :   unsigned nhot = 2000;
+    1408             :   double MCacc = 0.0;
+    1409             :   double kbt, ebest, scale_best;
+    1410             : 
+    1411             : // initial value of scale factor and energy
+    1412           0 :   double scale = random_.RandU01() * ( scale_max_ - scale_min_ ) + scale_min_;
+    1413           0 :   double ene = scaleEnergy(scale);
+    1414             : // set best energy
+    1415           0 :   ebest = ene;
+    1416             : 
+    1417             : // MC loop
+    1418           0 :   for(unsigned istep=0; istep<MCsteps; ++istep) {
+    1419             :     // get temperature
+    1420           0 :     if(istep%(ncold+nhot)<ncold) kbt = kbtmin;
+    1421             :     else kbt = kbtmax;
+    1422             :     // propose move in scale
+    1423           0 :     double ds = dscale_ * ( 2.0 * random_.RandU01() - 1.0 );
+    1424           0 :     double new_scale = scale + ds;
+    1425             :     // check boundaries
+    1426           0 :     if(new_scale > scale_max_) {new_scale = 2.0 * scale_max_ - new_scale;}
+    1427           0 :     if(new_scale < scale_min_) {new_scale = 2.0 * scale_min_ - new_scale;}
+    1428             :     // new energy
+    1429           0 :     double new_ene = scaleEnergy(new_scale);
+    1430             :     // accept or reject
+    1431           0 :     bool accept = doAccept(ene, new_ene, kbt);
+    1432             :     // in case of acceptance
+    1433           0 :     if(accept) {
+    1434             :       scale = new_scale;
+    1435             :       ene = new_ene;
+    1436           0 :       MCacc += 1.0;
+    1437             :     }
+    1438             :     // save best
+    1439           0 :     if(ene<ebest) {
+    1440           0 :       ebest = ene;
+    1441           0 :       scale_best = scale;
+    1442             :     }
+    1443             :   }
+    1444             : // calculate acceptance
+    1445           0 :   double accscale = MCacc / static_cast<double>(MCsteps);
+    1446             : // global communication
+    1447           0 :   if(!no_aver_ && nrep_>1) {
+    1448           0 :     if(replica_!=0) {
+    1449           0 :       scale_best = 0.0;
+    1450           0 :       ebest = 0.0;
+    1451           0 :       accscale = 0.0;
+    1452             :     }
+    1453           0 :     if(rank_==0) {
+    1454           0 :       multi_sim_comm.Sum(&scale_best, 1);
+    1455           0 :       multi_sim_comm.Sum(&ebest, 1);
+    1456           0 :       multi_sim_comm.Sum(&accscale, 1);
+    1457             :     }
+    1458             :   }
+    1459             :   // local communication
+    1460           0 :   if(rank_!=0) {
+    1461           0 :     scale_best = 0.0;
+    1462           0 :     ebest = 0.0;
+    1463           0 :     accscale = 0.0;
+    1464             :   }
+    1465           0 :   if(size_>1) {
+    1466           0 :     comm.Sum(&scale_best, 1);
+    1467           0 :     comm.Sum(&ebest, 1);
+    1468           0 :     comm.Sum(&accscale, 1);
+    1469             :   }
+    1470             : // set scale parameters
+    1471           0 :   getPntrToComponent("accscale")->set(accscale);
+    1472           0 :   getPntrToComponent("enescale")->set(ebest);
+    1473             : // return scale value
+    1474           0 :   return scale_best;
+    1475             : }
+    1476             : 
+    1477           0 : double EMMI::get_annealing(long int step)
+    1478             : {
+    1479             : // default no annealing
+    1480             :   double fact = 1.0;
+    1481             : // position in annealing cycle
+    1482           0 :   unsigned nc = step%(4*nanneal_);
+    1483             : // useful doubles
+    1484           0 :   double ncd = static_cast<double>(nc);
+    1485           0 :   double nn  = static_cast<double>(nanneal_);
+    1486             : // set fact
+    1487           0 :   if(nc>=nanneal_   && nc<2*nanneal_) fact = (kanneal_-1.0) / nn * ( ncd - nn ) + 1.0;
+    1488           0 :   if(nc>=2*nanneal_ && nc<3*nanneal_) fact = kanneal_;
+    1489           0 :   if(nc>=3*nanneal_)                  fact = (1.0-kanneal_) / nn * ( ncd - 3.0*nn) + kanneal_;
+    1490           0 :   return fact;
+    1491             : }
+    1492             : 
+    1493       16365 : void EMMI::get_weights(double &weight, double &norm, double &neff)
+    1494             : {
+    1495       16365 :   const double dnrep = static_cast<double>(nrep_);
+    1496             :   // calculate the weights either from BIAS
+    1497       16365 :   if(do_reweight_) {
+    1498          12 :     std::vector<double> bias(nrep_,0);
+    1499          12 :     if(rank_==0) {
+    1500          12 :       bias[replica_] = getArgument(0);
+    1501          12 :       if(nrep_>1) multi_sim_comm.Sum(&bias[0], nrep_);
+    1502             :     }
+    1503          12 :     comm.Sum(&bias[0], nrep_);
+    1504             : 
+    1505             :     // accumulate weights
+    1506          12 :     if(!first_time_w_) {
+    1507          30 :       for(unsigned i=0; i<nrep_; ++i) {
+    1508          20 :         const double delta=bias[i]-average_weights_[i];
+    1509             :         // FIXME: multiplying by fractional decay here causes problems with numerical derivatives,
+    1510             :         // probably because we're making several calls to calculate(), causing accumulation
+    1511             :         // of epsilons. Maybe we can work on a temporary copy of the action instead?
+    1512          20 :         average_weights_[i]+=decay_w_*delta;
+    1513             :       }
+    1514             :     } else {
+    1515           2 :       first_time_w_ = false;
+    1516           6 :       for(unsigned i=0; i<nrep_; ++i) average_weights_[i] = bias[i];
+    1517             :     }
+    1518             : 
+    1519             :     // set average back into bias and set norm to one
+    1520          12 :     const double maxbias = *(std::max_element(average_weights_.begin(), average_weights_.end()));
+    1521          36 :     for(unsigned i=0; i<nrep_; ++i) bias[i] = std::exp((average_weights_[i]-maxbias)/kbt_);
+    1522             :     // set local weight, norm and weight variance
+    1523          12 :     weight = bias[replica_];
+    1524             :     double w2=0.;
+    1525          36 :     for(unsigned i=0; i<nrep_; ++i) {
+    1526          24 :       w2 += bias[i]*bias[i];
+    1527          24 :       norm += bias[i];
+    1528             :     }
+    1529          12 :     neff = norm*norm/w2;
+    1530          24 :     getPntrToComponent("weight")->set(weight/norm);
+    1531             :   } else {
+    1532             :     // or arithmetic ones
+    1533       16353 :     neff = dnrep;
+    1534       16353 :     weight = 1.0;
+    1535       16353 :     norm = dnrep;
+    1536             :   }
+    1537       16365 :   getPntrToComponent("neff")->set(neff);
+    1538       16365 : }
+    1539             : 
+    1540       16365 : void EMMI::calculate()
+    1541             : {
+    1542             : 
+    1543             : // calculate CV
+    1544       16365 :   calculate_overlap();
+    1545             : 
+    1546             :   // rescale factor for ensemble average
+    1547       16365 :   double weight = 0.;
+    1548       16365 :   double neff = 0.;
+    1549       16365 :   double norm = 0.;
+    1550       16365 :   get_weights(weight, norm, neff);
+    1551             : 
+    1552             :   // in case of ensemble averaging, calculate average overlap
+    1553       16365 :   if(!no_aver_ && nrep_>1) {
+    1554             :     // if master node, calculate average across replicas
+    1555          12 :     if(rank_==0) {
+    1556       10812 :       for(unsigned i=0; i<ovmd_.size(); ++i) ovmd_ave_[i] = weight / norm * ovmd_[i];
+    1557          12 :       multi_sim_comm.Sum(&ovmd_ave_[0], ovmd_ave_.size());
+    1558             :     } else {
+    1559           0 :       for(unsigned i=0; i<ovmd_ave_.size(); ++i) ovmd_ave_[i] = 0.0;
+    1560             :     }
+    1561             :     // local communication
+    1562          12 :     if(size_>1) comm.Sum(&ovmd_ave_[0], ovmd_ave_.size());
+    1563             :   } else {
+    1564      163530 :     for(unsigned i=0; i<ovmd_.size(); ++i) ovmd_ave_[i] = ovmd_[i];
+    1565             :   }
+    1566             : 
+    1567             :   // get time step
+    1568       16365 :   long int step = getStep();
+    1569             : 
+    1570             :   // do regression
+    1571       16365 :   if(nregres_>0) {
+    1572           0 :     if(step%nregres_==0 && !getExchangeStep()) scale_ = doRegression();
+    1573             :     // set scale component
+    1574           0 :     getPntrToComponent("scale")->set(scale_);
+    1575             :   }
+    1576             : 
+    1577             :   // write model overlap to file
+    1578       16365 :   if(ovstride_>0 && step%ovstride_==0) write_model_overlap(step);
+    1579             : 
+    1580             :   // clear energy and virial
+    1581       16365 :   ene_ = 0.0;
+    1582       16365 :   virial_.zero();
+    1583             : 
+    1584             :   // Gaussian noise
+    1585       16365 :   if(noise_==0) calculate_Gauss();
+    1586             : 
+    1587             :   // Outliers noise
+    1588       16365 :   if(noise_==1) calculate_Outliers();
+    1589             : 
+    1590             :   // Marginal noise
+    1591       16365 :   if(noise_==2) calculate_Marginal();
+    1592             : 
+    1593             :   // get annealing rescale factor
+    1594       16365 :   if(nanneal_>0) {
+    1595           0 :     anneal_ = get_annealing(step);
+    1596           0 :     getPntrToComponent("anneal")->set(anneal_);
+    1597             :   }
+    1598             : 
+    1599             :   // annealing rescale
+    1600       16365 :   ene_ /= anneal_;
+    1601             : 
+    1602       16365 :   std::vector<double> GMMid_der_av_(GMMid_der_.size(), 0.0);
+    1603             :   // in case of ensemble averaging
+    1604       16365 :   if(!no_aver_ && nrep_>1) {
+    1605             :     // if master node, sum der_GMMid derivatives and ene
+    1606          12 :     if(rank_==0) {
+    1607       10812 :       for(unsigned i=0; i<GMMid_der_.size(); ++i) {
+    1608       10800 :         GMMid_der_av_[i] = (weight / norm) * GMMid_der_[i];
+    1609             :       }
+    1610          12 :       multi_sim_comm.Sum(&GMMid_der_av_[0], GMMid_der_av_.size());
+    1611          12 :       multi_sim_comm.Sum(&ene_, 1);
+    1612             :     } else {
+    1613             :       // set der_GMMid derivatives and energy to zero
+    1614           0 :       for(unsigned i=0; i<GMMid_der_av_.size(); ++i) GMMid_der_av_[i]=0.0;
+    1615           0 :       ene_ = 0.0;
+    1616             :     }
+    1617             :     // local communication
+    1618          12 :     if(size_>1) {
+    1619           0 :       comm.Sum(&GMMid_der_av_[0], GMMid_der_av_.size());
+    1620           0 :       comm.Sum(&ene_, 1);
+    1621             :     }
+    1622             :   } else {
+    1623      163530 :     for (unsigned i = 0; i < GMMid_der_.size(); ++i) {
+    1624      147177 :       GMMid_der_av_[i] = GMMid_der_[i];
+    1625             :     }
+    1626             :   }
+    1627             : 
+    1628             :   // clean temporary std::vector
+    1629     9860991 :   for(unsigned i=0; i<atom_der_.size(); ++i) atom_der_[i] = Vector(0,0,0);
+    1630             : 
+    1631             :   // get derivatives of bias with respect to atoms
+    1632     2127723 :   for(unsigned i=rank_; i<nl_.size(); i=i+size_) {
+    1633             :     // get indexes of data and model component
+    1634     2111358 :     unsigned id = nl_[i] / GMM_m_type_.size();
+    1635     2111358 :     unsigned im = nl_[i] % GMM_m_type_.size();
+    1636             :     // chain rule + replica normalization
+    1637     2111358 :     Vector tot_der = GMMid_der_av_[id] * ovmd_der_[i] * scale_ / anneal_;
+    1638     2111358 :     Vector pos;
+    1639     2111358 :     if(pbc_) pos = pbcDistance(GMM_d_m_[id], getPosition(im)) + GMM_d_m_[id];
+    1640     2111358 :     else     pos = getPosition(im);
+    1641             :     // increment derivatives and virial
+    1642     2111358 :     atom_der_[im] += tot_der;
+    1643     2111358 :     virial_ += Tensor(pos, -tot_der);
+    1644             :   }
+    1645             : 
+    1646             :   // communicate local derivatives and virial
+    1647       16365 :   if(size_>1) {
+    1648       10902 :     comm.Sum(&atom_der_[0][0], 3*atom_der_.size());
+    1649       10902 :     comm.Sum(virial_);
+    1650             :   }
+    1651             : 
+    1652             :   // set derivatives, virial, and score
+    1653     9860991 :   for(unsigned i=0; i<atom_der_.size(); ++i) setAtomsDerivatives(getPntrToComponent("scoreb"), i, atom_der_[i]);
+    1654       16365 :   setBoxDerivatives(getPntrToComponent("scoreb"), virial_);
+    1655       16365 :   getPntrToComponent("scoreb")->set(ene_);
+    1656             : 
+    1657       16365 :   if (do_reweight_) {
+    1658             :     double w_tmp = 0.;
+    1659       10812 :     for (unsigned i = 0; i < ovmd_.size(); ++i) {
+    1660       10800 :       w_tmp += (ovmd_[i] - ovmd_ave_[i]) * GMMid_der_[i];
+    1661             :     }
+    1662          12 :     w_tmp *= scale_ * (weight / norm) / kbt_ * decay_w_;
+    1663             : 
+    1664          12 :     setArgDerivatives(getPntrToComponent("scoreb"), w_tmp);
+    1665          24 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1666             :   }
+    1667             : 
+    1668             :   // This part is needed only for Gaussian and Outliers noise models
+    1669       16365 :   if(noise_!=2) {
+    1670             : 
+    1671             :     // do Montecarlo
+    1672       10914 :     if(dsigma_[0]>0 && step%MCstride_==0 && !getExchangeStep()) doMonteCarlo();
+    1673             : 
+    1674             :     // print status
+    1675       10914 :     if(step%statusstride_==0) print_status(step);
+    1676             : 
+    1677             :     // calculate acceptance ratio
+    1678       10914 :     double acc = MCaccept_ / MCtrials_;
+    1679             : 
+    1680             :     // set value
+    1681       21828 :     getPntrToComponent("acc")->set(acc);
+    1682             : 
+    1683             :   }
+    1684             : 
+    1685       16365 : }
+    1686             : 
+    1687        5463 : void EMMI::calculate_Gauss()
+    1688             : {
+    1689             :   // cycle on all the GMM groups
+    1690       10926 :   for(unsigned i=0; i<GMM_d_grps_.size(); ++i) {
+    1691             :     double eneg = 0.0;
+    1692             :     // cycle on all the members of the group
+    1693       65322 :     for(unsigned j=0; j<GMM_d_grps_[i].size(); ++j) {
+    1694             :       // id of the GMM component
+    1695       59859 :       int GMMid = GMM_d_grps_[i][j];
+    1696             :       // calculate deviation
+    1697       59859 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] ) / sigma_[i];
+    1698             :       // add to group energy
+    1699       59859 :       eneg += 0.5 * dev * dev;
+    1700             :       // store derivative for later
+    1701       59859 :       GMMid_der_[GMMid] = kbt_ * dev / sigma_[i];
+    1702             :     }
+    1703             :     // add to total energy along with normalizations and prior
+    1704        5463 :     ene_ += kbt_ * ( eneg + (static_cast<double>(GMM_d_grps_[i].size())+prior_) * std::log(sigma_[i]) );
+    1705             :   }
+    1706        5463 : }
+    1707             : 
+    1708        5451 : void EMMI::calculate_Outliers()
+    1709             : {
+    1710             :   // cycle on all the GMM groups
+    1711       10902 :   for(unsigned i=0; i<GMM_d_grps_.size(); ++i) {
+    1712             :     // cycle on all the members of the group
+    1713             :     double eneg = 0.0;
+    1714       54510 :     for(unsigned j=0; j<GMM_d_grps_[i].size(); ++j) {
+    1715             :       // id of the GMM component
+    1716       49059 :       int GMMid = GMM_d_grps_[i][j];
+    1717             :       // calculate deviation
+    1718       49059 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] ) / sigma_[i];
+    1719             :       // add to group energy
+    1720       49059 :       eneg += std::log( 1.0 + 0.5 * dev * dev );
+    1721             :       // store derivative for later
+    1722       49059 :       GMMid_der_[GMMid] = kbt_ / ( 1.0 + 0.5 * dev * dev ) * dev / sigma_[i];
+    1723             :     }
+    1724             :     // add to total energy along with normalizations and prior
+    1725        5451 :     ene_ += kbt_ * ( eneg + (static_cast<double>(GMM_d_grps_[i].size())+prior_) * std::log(sigma_[i]) );
+    1726             :   }
+    1727        5451 : }
+    1728             : 
+    1729        5451 : void EMMI::calculate_Marginal()
+    1730             : {
+    1731             :   // cycle on all the GMM groups
+    1732       10902 :   for(unsigned i=0; i<GMM_d_grps_.size(); ++i) {
+    1733             :     // cycle on all the members of the group
+    1734       54510 :     for(unsigned j=0; j<GMM_d_grps_[i].size(); ++j) {
+    1735             :       // id of the GMM component
+    1736       49059 :       int GMMid = GMM_d_grps_[i][j];
+    1737             :       // calculate deviation
+    1738       49059 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] );
+    1739             :       // calculate errf
+    1740       49059 :       double errf = erf ( dev * inv_sqrt2_ / sigma_min_[i] );
+    1741             :       // add to group energy
+    1742       49059 :       ene_ += -kbt_ * std::log ( 0.5 / dev * errf ) ;
+    1743             :       // store derivative for later
+    1744       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;
+    1745             :     }
+    1746             :   }
+    1747        5451 : }
+    1748             : 
+    1749             : }
+    1750             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..c563431e50 --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:363894.7 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb14FretEfficiencyC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe936createERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiencyC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiency16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD4isdb14FretEfficiency9calculateEv238
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe93C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe93D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.func.html b/coverage/isdb/FretEfficiency.cpp.func.html new file mode 100644 index 0000000000..fc13a04356 --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:363894.7 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe936createERKNS_13ActionOptionsE14
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe93C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe93D2Ev3473
_ZN4PLMD4isdb14FretEfficiency16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD4isdb14FretEfficiency9calculateEv238
_ZN4PLMD4isdb14FretEfficiencyC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiencyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.gcov.html b/coverage/isdb/FretEfficiency.cpp.gcov.html new file mode 100644 index 0000000000..cd9a817d7e --- /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:363894.7 %
Date:2024-06-10 08:19:14Functions: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 "colvar/Colvar.h"
+      23             : #include "colvar/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       10447 : PLUMED_REGISTER_ACTION(FretEfficiency,"FRET")
+      94             : 
+      95          15 : void FretEfficiency::registerKeywords( Keywords& keys ) {
+      96          15 :   Colvar::registerKeywords( keys );
+      97          30 :   keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
+      98          30 :   keys.add("compulsory","R0","The value of the Forster radius.");
+      99          15 : }
+     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         238 :   setAtomsDerivatives(1, inv_dist_mod*der*distance);
+     146         238 :   setBoxDerivativesNoPbc();
+     147         238 :   setValue(fret_eff);
+     148             : 
+     149         238 : }
+     150             : 
+     151             : }
+     152             : }
+     153             : 
+     154             : 
+     155             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..be3de4906f --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb9JCouplingC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe1066createERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCouplingC1ERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCoupling16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD4isdb9JCoupling6updateEv16
_ZN4PLMD4isdb9JCoupling9calculateEv16
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe106C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe106D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.func.html b/coverage/isdb/Jcoupling.cpp.func.html new file mode 100644 index 0000000000..080279d75d --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe1066createERKNS_13ActionOptionsE6
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe106C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe106D2Ev3473
_ZN4PLMD4isdb9JCoupling16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD4isdb9JCoupling6updateEv16
_ZN4PLMD4isdb9JCoupling9calculateEv16
_ZN4PLMD4isdb9JCouplingC1ERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCouplingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.gcov.html b/coverage/isdb/Jcoupling.cpp.gcov.html new file mode 100644 index 0000000000..a3a323e525 --- /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-06-10 08:19:14Functions: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 "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       10431 : PLUMED_REGISTER_ACTION(JCoupling, "JCOUPLING")
+     107             : 
+     108           7 : void JCoupling::registerKeywords(Keywords& keys) {
+     109           7 :   componentsAreNotOptional(keys);
+     110           7 :   MetainferenceBase::registerKeywords(keys);
+     111          14 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     112          14 :   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          14 :   keys.reset_style("ATOMS", "atoms");
+     116          14 :   keys.add("compulsory", "TYPE", "Type of J-coupling to compute (HAN,HAHN,CCG,NCG,CUSTOM)");
+     117          14 :   keys.add("optional", "A", "Karplus parameter A");
+     118          14 :   keys.add("optional", "B", "Karplus parameter B");
+     119          14 :   keys.add("optional", "C", "Karplus parameter C");
+     120          14 :   keys.add("optional", "SHIFT", "Angle shift in radians");
+     121          14 :   keys.add("numbered", "COUPLING", "Add an experimental value for each coupling");
+     122          14 :   keys.addOutputComponent("j", "default", "the calculated J-coupling");
+     123          14 :   keys.addOutputComponent("exp", "COUPLING", "the experimental J-coupling");
+     124           7 : }
+     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          21 :       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           7 :       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           7 :       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             :     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.15
+
+ + + 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 0000000000..f8681a3bd8 --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func-sort-c.html @@ -0,0 +1,193 @@ + + + + + + + + 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:74188084.2 %
Date:2024-06-10 08:19:14Functions:273090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb13Metainference18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb13MetainferenceC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb13MetainferenceD2Ev0
_ZN4PLMD4isdb13Metainference16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe2856createERKNS_13ActionOptionsE19
_ZN4PLMD4isdb13Metainference11writeStatusEv19
_ZN4PLMD4isdb13MetainferenceC1ERKNS_13ActionOptionsE19
_ZN4PLMD4isdb13MetainferenceD0Ev19
_ZN4PLMD4isdb13MetainferenceD1Ev19
_ZN4PLMD4isdb13Metainference16registerKeywordsERNS_8KeywordsE20
_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
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe285C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe285D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.func.html b/coverage/isdb/Metainference.cpp.func.html new file mode 100644 index 0000000000..e19cbb00c2 --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func.html @@ -0,0 +1,193 @@ + + + + + + + + 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:74188084.2 %
Date:2024-06-10 08:19:14Functions:273090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe2856createERKNS_13ActionOptionsE19
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe285C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe285D2Ev3473
_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_8KeywordsE20
_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.15
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.gcov.html b/coverage/isdb/Metainference.cpp.gcov.html new file mode 100644 index 0000000000..55ecd55332 --- /dev/null +++ b/coverage/isdb/Metainference.cpp.gcov.html @@ -0,0 +1,1882 @@ + + + + + + + + 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:74188084.2 %
Date:2024-06-10 08:19:14Functions:273090.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             : #include "bias/Bias.h"
+      24             : #include "bias/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Atoms.h"
+      27             : #include "core/Value.h"
+      28             : #include "tools/File.h"
+      29             : #include "tools/OpenMP.h"
+      30             : #include "tools/Random.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 unsigned MCaccept_;
+     206             :   long unsigned MCacceptScale_;
+     207             :   long unsigned MCacceptFT_;
+     208             :   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       10457 : PLUMED_REGISTER_ACTION(Metainference,"METAINFERENCE")
+     286             : 
+     287          20 : void Metainference::registerKeywords(Keywords& keys) {
+     288          20 :   Bias::registerKeywords(keys);
+     289          20 :   keys.use("ARG");
+     290          40 :   keys.add("optional","PARARG","reference values for the experimental data, these can be provided as arguments without derivatives");
+     291          40 :   keys.add("optional","PARAMETERS","reference values for the experimental data");
+     292          40 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+     293          40 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the latest ARG as energy");
+     294          40 :   keys.add("optional","AVERAGING", "Stride for calculation of averaged weights and sigma_mean");
+     295          40 :   keys.add("compulsory","NOISETYPE","MGAUSS","functional form of the noise (GAUSS,MGAUSS,OUTLIERS,MOUTLIERS,GENERIC)");
+     296          40 :   keys.add("compulsory","LIKELIHOOD","GAUSS","the likelihood for the GENERIC metainference model, GAUSS or LOGN");
+     297          40 :   keys.add("compulsory","DFTILDE","0.1","fraction of sigma_mean used to evolve ftilde");
+     298          40 :   keys.addFlag("SCALEDATA",false,"Set to TRUE if you want to sample a scaling factor common to all values and replicas");
+     299          40 :   keys.add("compulsory","SCALE0","1.0","initial value of the scaling factor");
+     300          40 :   keys.add("compulsory","SCALE_PRIOR","FLAT","either FLAT or GAUSSIAN");
+     301          40 :   keys.add("optional","SCALE_MIN","minimum value of the scaling factor");
+     302          40 :   keys.add("optional","SCALE_MAX","maximum value of the scaling factor");
+     303          40 :   keys.add("optional","DSCALE","maximum MC move of the scaling factor");
+     304          40 :   keys.addFlag("ADDOFFSET",false,"Set to TRUE if you want to sample an offset common to all values and replicas");
+     305          40 :   keys.add("compulsory","OFFSET0","0.0","initial value of the offset");
+     306          40 :   keys.add("compulsory","OFFSET_PRIOR","FLAT","either FLAT or GAUSSIAN");
+     307          40 :   keys.add("optional","OFFSET_MIN","minimum value of the offset");
+     308          40 :   keys.add("optional","OFFSET_MAX","maximum value of the offset");
+     309          40 :   keys.add("optional","DOFFSET","maximum MC move of the offset");
+     310          40 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+     311          40 :   keys.add("compulsory","SIGMA0","1.0","initial value of the uncertainty parameter");
+     312          40 :   keys.add("compulsory","SIGMA_MIN","0.0","minimum value of the uncertainty parameter");
+     313          40 :   keys.add("compulsory","SIGMA_MAX","10.","maximum value of the uncertainty parameter");
+     314          40 :   keys.add("optional","DSIGMA","maximum MC move of the uncertainty parameter");
+     315          40 :   keys.add("compulsory","OPTSIGMAMEAN","NONE","Set to NONE/SEM to manually set sigma mean, or to estimate it on the fly");
+     316          40 :   keys.add("optional","SIGMA_MEAN0","starting value for the uncertainty in the mean estimate");
+     317          40 :   keys.add("optional","SIGMA_MAX_STEPS", "Number of steps used to optimise SIGMA_MAX, before that the SIGMA_MAX value is used");
+     318          40 :   keys.add("optional","TEMP","the system temperature - this is only needed if code doesn't pass the temperature to plumed");
+     319          40 :   keys.add("optional","MC_STEPS","number of MC steps");
+     320          40 :   keys.add("optional","MC_CHUNKSIZE","MC chunksize");
+     321          40 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart/continuation of Metainference");
+     322          40 :   keys.add("compulsory","WRITE_STRIDE","10000","write the status to a file every N steps, this can be used for restart/continuation");
+     323          40 :   keys.add("optional","SELECTOR","name of selector");
+     324          40 :   keys.add("optional","NSELECT","range of values for selector [0, N-1]");
+     325          20 :   keys.use("RESTART");
+     326          40 :   keys.addOutputComponent("sigma",        "default",      "uncertainty parameter");
+     327          40 :   keys.addOutputComponent("sigmaMean",    "default",      "uncertainty in the mean estimate");
+     328          40 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+     329          40 :   keys.addOutputComponent("acceptSigma",  "default",      "MC acceptance for sigma values");
+     330          40 :   keys.addOutputComponent("acceptScale",  "SCALEDATA",    "MC acceptance for scale value");
+     331          40 :   keys.addOutputComponent("acceptFT",     "GENERIC",      "MC acceptance for general metainference f tilde value");
+     332          40 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+     333          40 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+     334          40 :   keys.addOutputComponent("scale",        "SCALEDATA",    "scale parameter");
+     335          40 :   keys.addOutputComponent("offset",       "ADDOFFSET",    "offset parameter");
+     336          40 :   keys.addOutputComponent("ftilde",       "GENERIC",      "ensemble average estimator");
+     337          20 : }
+     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 :   double temp=0.0;
+     599          19 :   parse("TEMP",temp);
+     600          19 :   if(temp>0.0) kbt_=plumed.getAtoms().getKBoltzmann()*temp;
+     601           0 :   else kbt_=plumed.getAtoms().getKbT();
+     602          19 :   if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, you must specify it using TEMP");
+     603             : 
+     604          19 :   checkRead();
+     605             : 
+     606             :   // set sigma_bias
+     607          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     608          13 :     if(sigma_.size()==1) {
+     609          13 :       double tmp = sigma_[0];
+     610          13 :       sigma_.resize(narg, tmp);
+     611           0 :     } else if(sigma_.size()>1&&sigma_.size()!=narg) {
+     612           0 :       error("SIGMA0 can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     613             :     }
+     614          13 :     if(sigma_min_.size()==1) {
+     615          13 :       double tmp = sigma_min_[0];
+     616          13 :       sigma_min_.resize(narg, tmp);
+     617           0 :     } else if(sigma_min_.size()>1&&sigma_min_.size()!=narg) {
+     618           0 :       error("SIGMA_MIN can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     619             :     }
+     620          13 :     if(sigma_max_.size()==1) {
+     621          13 :       double tmp = sigma_max_[0];
+     622          13 :       sigma_max_.resize(narg, tmp);
+     623           0 :     } else if(sigma_max_.size()>1&&sigma_max_.size()!=narg) {
+     624           0 :       error("SIGMA_MAX can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     625             :     }
+     626          13 :     if(Dsigma_.size()==1) {
+     627          13 :       double tmp = Dsigma_[0];
+     628          13 :       Dsigma_.resize(narg, tmp);
+     629           0 :     } else if(Dsigma_.size()>1&&Dsigma_.size()!=narg) {
+     630           0 :       error("DSIGMA can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     631             :     }
+     632             :   }
+     633             : 
+     634          19 :   sigma_max_est_.resize(sigma_max_.size(), 0.);
+     635             : 
+     636          19 :   IFile restart_sfile;
+     637          19 :   restart_sfile.link(*this);
+     638          19 :   if(getRestart()&&restart_sfile.FileExist(status_file_name_)) {
+     639           4 :     firstTime = false;
+     640           8 :     for(unsigned i=0; i<nsel; i++) firstTimeW[i] = false;
+     641           4 :     restart_sfile.open(status_file_name_);
+     642           4 :     log.printf("  Restarting from %s\n", status_file_name_.c_str());
+     643             :     double dummy;
+     644           8 :     if(restart_sfile.scanField("time",dummy)) {
+     645             :       // check for syncronisation
+     646           4 :       std::vector<double> dummy_time(nrep_,0);
+     647           4 :       if(master&&nrep_>1) {
+     648           2 :         dummy_time[replica_] = dummy;
+     649           2 :         multi_sim_comm.Sum(dummy_time);
+     650             :       }
+     651           4 :       comm.Sum(dummy_time);
+     652           8 :       for(unsigned i=1; i<nrep_; i++) {
+     653           4 :         std::string msg = "METAINFERENCE restart files " + status_file_name_ + "  are not in sync";
+     654           4 :         if(dummy_time[i]!=dummy_time[0]) plumed_merror(msg);
+     655             :       }
+     656             :       // nsel
+     657           8 :       for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+     658             :         std::string msg_i;
+     659           4 :         Tools::convert(i,msg_i);
+     660             :         // narg
+     661           4 :         if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     662          20 :           for(unsigned j=0; j<narg; ++j) {
+     663             :             std::string msg_j;
+     664          16 :             Tools::convert(j,msg_j);
+     665          16 :             std::string msg = msg_i+"_"+msg_j;
+     666             :             double read_sm;
+     667          16 :             restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     668          16 :             sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     669             :           }
+     670             :         }
+     671           4 :         if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+     672             :           double read_sm;
+     673             :           std::string msg_j;
+     674           0 :           Tools::convert(0,msg_j);
+     675           0 :           std::string msg = msg_i+"_"+msg_j;
+     676           0 :           restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     677           0 :           for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     678             :         }
+     679             :       }
+     680             : 
+     681          20 :       for(unsigned i=0; i<sigma_.size(); ++i) {
+     682             :         std::string msg;
+     683          16 :         Tools::convert(i,msg);
+     684          32 :         restart_sfile.scanField("sigma_"+msg,sigma_[i]);
+     685             :       }
+     686          20 :       for(unsigned i=0; i<sigma_max_.size(); ++i) {
+     687             :         std::string msg;
+     688          16 :         Tools::convert(i,msg);
+     689          16 :         restart_sfile.scanField("sigma_max_"+msg,sigma_max_[i]);
+     690          16 :         sigmamax_opt_done_=true;
+     691             :       }
+     692           4 :       if(noise_type_==GENERIC) {
+     693           0 :         for(unsigned i=0; i<ftilde_.size(); ++i) {
+     694             :           std::string msg;
+     695           0 :           Tools::convert(i,msg);
+     696           0 :           restart_sfile.scanField("ftilde_"+msg,ftilde_[i]);
+     697             :         }
+     698             :       }
+     699           4 :       restart_sfile.scanField("scale0_",scale_);
+     700           4 :       restart_sfile.scanField("offset0_",offset_);
+     701             : 
+     702           8 :       for(unsigned i=0; i<nsel; i++) {
+     703             :         std::string msg;
+     704           4 :         Tools::convert(i,msg);
+     705             :         double tmp_w;
+     706           4 :         restart_sfile.scanField("weight_"+msg,tmp_w);
+     707           4 :         if(master) {
+     708           2 :           average_weights_[i][replica_] = tmp_w;
+     709           2 :           if(nrep_>1) multi_sim_comm.Sum(&average_weights_[i][0], nrep_);
+     710             :         }
+     711           4 :         comm.Sum(&average_weights_[i][0], nrep_);
+     712             :       }
+     713             : 
+     714             :     }
+     715           4 :     restart_sfile.scanField();
+     716           4 :     restart_sfile.close();
+     717             :   }
+     718             : 
+     719             :   /* If DSIGMA is not yet initialised do it now */
+     720        2415 :   for(unsigned i=0; i<sigma_max_.size(); i++) if(Dsigma_[i]==-1) Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+     721             : 
+     722          19 :   switch(noise_type_) {
+     723           1 :   case GENERIC:
+     724           1 :     log.printf("  with general metainference ");
+     725           1 :     if(gen_likelihood_==LIKE_GAUSS) log.printf(" and a gaussian likelihood\n");
+     726           0 :     else if(gen_likelihood_==LIKE_LOGN) log.printf(" and a log-normal likelihood\n");
+     727           1 :     log.printf("  ensemble average parameter sampled with a step %lf of sigma_mean\n", Dftilde_);
+     728             :     break;
+     729           1 :   case GAUSS:
+     730           1 :     log.printf("  with gaussian noise and a single noise parameter for all the data\n");
+     731             :     break;
+     732           8 :   case MGAUSS:
+     733           8 :     log.printf("  with gaussian noise and a noise parameter for each data point\n");
+     734             :     break;
+     735           5 :   case OUTLIERS:
+     736           5 :     log.printf("  with long tailed gaussian noise and a single noise parameter for all the data\n");
+     737             :     break;
+     738           4 :   case MOUTLIERS:
+     739           4 :     log.printf("  with long tailed gaussian noise and a noise parameter for each data point\n");
+     740             :     break;
+     741             :   }
+     742             : 
+     743          19 :   if(doscale_) {
+     744             :     // check that the scale value is the same for all replicas
+     745          12 :     std::vector<double> dummy_scale(nrep_,0);
+     746          12 :     if(master&&nrep_>1) {
+     747           6 :       dummy_scale[replica_] = scale_;
+     748           6 :       multi_sim_comm.Sum(dummy_scale);
+     749             :     }
+     750          12 :     comm.Sum(dummy_scale);
+     751          24 :     for(unsigned i=1; i<nrep_; i++) {
+     752          12 :       std::string msg = "The SCALE value must be the same for all replicas: check your input or restart file";
+     753          12 :       if(dummy_scale[i]!=dummy_scale[0]) plumed_merror(msg);
+     754             :     }
+     755          12 :     log.printf("  sampling a common scaling factor with:\n");
+     756          12 :     log.printf("    initial scale parameter %f\n",scale_);
+     757          12 :     if(scale_prior_==SC_GAUSS) {
+     758           0 :       log.printf("    gaussian prior with mean %f and width %f\n",scale_mu_,Dscale_);
+     759             :     }
+     760          12 :     if(scale_prior_==SC_FLAT) {
+     761          12 :       log.printf("    flat prior between %f - %f\n",scale_min_,scale_max_);
+     762          12 :       log.printf("    maximum MC move of scale parameter %f\n",Dscale_);
+     763             :     }
+     764             :   }
+     765             : 
+     766          19 :   if(dooffset_) {
+     767             :     // check that the offset value is the same for all replicas
+     768           2 :     std::vector<double> dummy_offset(nrep_,0);
+     769           2 :     if(master&&nrep_>1) {
+     770           0 :       dummy_offset[replica_] = offset_;
+     771           0 :       multi_sim_comm.Sum(dummy_offset);
+     772             :     }
+     773           2 :     comm.Sum(dummy_offset);
+     774           2 :     for(unsigned i=1; i<nrep_; i++) {
+     775           0 :       std::string msg = "The OFFSET value must be the same for all replicas: check your input or restart file";
+     776           0 :       if(dummy_offset[i]!=dummy_offset[0]) plumed_merror(msg);
+     777             :     }
+     778           2 :     log.printf("  sampling a common offset with:\n");
+     779           2 :     log.printf("    initial offset parameter %f\n",offset_);
+     780           2 :     if(offset_prior_==SC_GAUSS) {
+     781           0 :       log.printf("    gaussian prior with mean %f and width %f\n",offset_mu_,Doffset_);
+     782             :     }
+     783           2 :     if(offset_prior_==SC_FLAT) {
+     784           2 :       log.printf("    flat prior between %f - %f\n",offset_min_,offset_max_);
+     785           2 :       log.printf("    maximum MC move of offset parameter %f\n",Doffset_);
+     786             :     }
+     787             :   }
+     788             : 
+     789          19 :   if(doregres_zero_)
+     790           0 :     log.printf("  doing regression with zero intercept with stride: %d\n", nregres_zero_);
+     791             : 
+     792          19 :   log.printf("  number of experimental data points %u\n",narg);
+     793          19 :   log.printf("  number of replicas %u\n",nrep_);
+     794          19 :   log.printf("  initial data uncertainties");
+     795        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f", sigma_[i]);
+     796          19 :   log.printf("\n");
+     797          19 :   log.printf("  minimum data uncertainties");
+     798        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_min_[i]);
+     799          19 :   log.printf("\n");
+     800          19 :   log.printf("  maximum data uncertainties");
+     801        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_max_[i]);
+     802          19 :   log.printf("\n");
+     803          19 :   log.printf("  maximum MC move of data uncertainties");
+     804        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",Dsigma_[i]);
+     805          19 :   log.printf("\n");
+     806          19 :   log.printf("  temperature of the system %f\n",kbt_);
+     807          19 :   log.printf("  MC steps %u\n",MCsteps_);
+     808          19 :   log.printf("  initial standard errors of the mean");
+     809        2415 :   for(unsigned i=0; i<sigma_mean2_.size(); ++i) log.printf(" %f", std::sqrt(sigma_mean2_[i]));
+     810          19 :   log.printf("\n");
+     811             : 
+     812          19 :   if(do_reweight_) {
+     813          16 :     addComponent("biasDer");
+     814          16 :     componentIsNotPeriodic("biasDer");
+     815          16 :     addComponent("weight");
+     816          32 :     componentIsNotPeriodic("weight");
+     817             :   }
+     818             : 
+     819          19 :   addComponent("neff");
+     820          19 :   componentIsNotPeriodic("neff");
+     821             : 
+     822          19 :   if(doscale_ || doregres_zero_) {
+     823          12 :     addComponent("scale");
+     824          12 :     componentIsNotPeriodic("scale");
+     825          12 :     valueScale=getPntrToComponent("scale");
+     826             :   }
+     827             : 
+     828          19 :   if(dooffset_) {
+     829           2 :     addComponent("offset");
+     830           2 :     componentIsNotPeriodic("offset");
+     831           2 :     valueOffset=getPntrToComponent("offset");
+     832             :   }
+     833             : 
+     834          19 :   if(dooffset_||doscale_) {
+     835          14 :     addComponent("acceptScale");
+     836          14 :     componentIsNotPeriodic("acceptScale");
+     837          14 :     valueAcceptScale=getPntrToComponent("acceptScale");
+     838             :   }
+     839             : 
+     840          19 :   if(noise_type_==GENERIC) {
+     841           1 :     addComponent("acceptFT");
+     842           1 :     componentIsNotPeriodic("acceptFT");
+     843           1 :     valueAcceptFT=getPntrToComponent("acceptFT");
+     844             :   }
+     845             : 
+     846          19 :   addComponent("acceptSigma");
+     847          19 :   componentIsNotPeriodic("acceptSigma");
+     848          19 :   valueAccept=getPntrToComponent("acceptSigma");
+     849             : 
+     850          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     851        2403 :     for(unsigned i=0; i<sigma_mean2_.size(); ++i) {
+     852        2390 :       std::string num; Tools::convert(i,num);
+     853        4780 :       addComponent("sigmaMean-"+num); componentIsNotPeriodic("sigmaMean-"+num);
+     854        2390 :       valueSigmaMean.push_back(getPntrToComponent("sigmaMean-"+num));
+     855        2390 :       getPntrToComponent("sigmaMean-"+num)->set(std::sqrt(sigma_mean2_[i]));
+     856        4780 :       addComponent("sigma-"+num); componentIsNotPeriodic("sigma-"+num);
+     857        2390 :       valueSigma.push_back(getPntrToComponent("sigma-"+num));
+     858        2390 :       getPntrToComponent("sigma-"+num)->set(sigma_[i]);
+     859        2390 :       if(noise_type_==GENERIC) {
+     860           4 :         addComponent("ftilde-"+num); componentIsNotPeriodic("ftilde-"+num);
+     861           2 :         valueFtilde.push_back(getPntrToComponent("ftilde-"+num));
+     862             :       }
+     863             :     }
+     864          13 :   } else {
+     865          12 :     addComponent("sigmaMean"); componentIsNotPeriodic("sigmaMean");
+     866           6 :     valueSigmaMean.push_back(getPntrToComponent("sigmaMean"));
+     867           6 :     getPntrToComponent("sigmaMean")->set(std::sqrt(sigma_mean2_[0]));
+     868          12 :     addComponent("sigma"); componentIsNotPeriodic("sigma");
+     869           6 :     valueSigma.push_back(getPntrToComponent("sigma"));
+     870          12 :     getPntrToComponent("sigma")->set(sigma_[0]);
+     871             :   }
+     872             : 
+     873             :   // initialize random seed
+     874             :   unsigned iseed;
+     875          19 :   if(master) {
+     876          11 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     877          11 :     iseed = static_cast<unsigned>(ts)+replica_;
+     878             :   } else {
+     879           8 :     iseed = 0;
+     880             :   }
+     881          19 :   comm.Sum(&iseed, 1);
+     882             :   // this is used for ftilde and sigma both the move and the acceptance
+     883             :   // this is different for each replica
+     884          19 :   random[0].setSeed(-iseed);
+     885          19 :   if(doscale_||dooffset_) {
+     886             :     // in this case we want the same seed everywhere
+     887          14 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     888          14 :     iseed = static_cast<unsigned>(ts);
+     889          14 :     if(master&&nrep_>1) multi_sim_comm.Bcast(iseed,0);
+     890          14 :     comm.Bcast(iseed,0);
+     891             :     // this is used for scale and offset sampling and acceptance
+     892          14 :     random[1].setSeed(-iseed);
+     893             :   }
+     894             :   // this is used for random chunk of sigmas, and it is different for each replica
+     895          19 :   if(master) {
+     896          11 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     897          11 :     iseed = static_cast<unsigned>(ts)+replica_;
+     898             :   } else {
+     899           8 :     iseed = 0;
+     900             :   }
+     901          19 :   comm.Sum(&iseed, 1);
+     902          19 :   random[2].setSeed(-iseed);
+     903             : 
+     904             :   // outfile stuff
+     905          19 :   if(write_stride_>0) {
+     906          19 :     sfile_.link(*this);
+     907          19 :     sfile_.open(status_file_name_);
+     908             :   }
+     909             : 
+     910          38 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     911          51 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     912          19 :   if(do_optsigmamean_>0) log<<plumed.cite("Loehr, Jussupow, Camilloni, J. Chem. Phys. 146, 165102 (2017)");
+     913          38 :   log<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     914          19 :   log<<"\n";
+     915          38 : }
+     916             : 
+     917          38 : Metainference::~Metainference()
+     918             : {
+     919          19 :   if(sfile_.isOpen()) sfile_.close();
+     920         114 : }
+     921             : 
+     922         156 : double Metainference::getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     923             :                                   const double scale, const double offset)
+     924             : {
+     925         156 :   const double scale2 = scale*scale;
+     926         156 :   const double sm2    = sigma_mean2_[0];
+     927         156 :   const double ss2    = sigma[0]*sigma[0] + scale2*sm2;
+     928         156 :   const double sss    = sigma[0]*sigma[0] + sm2;
+     929             : 
+     930             :   double ene = 0.0;
+     931         156 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     932             :   {
+     933             :     #pragma omp for reduction( + : ene)
+     934             :     for(unsigned i=0; i<narg; ++i) {
+     935             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     936             :       const double a2 = 0.5*dev*dev + ss2;
+     937             :       if(sm2 > 0.0) {
+     938             :         ene += std::log(2.0*a2/(1.0-std::exp(-a2/sm2)));
+     939             :       }
+     940             :       else {
+     941             :         ene += std::log(2.0*a2);
+     942             :       }
+     943             :     }
+     944             :   }
+     945             :   // add one single Jeffrey's prior and one normalisation per data point
+     946         156 :   ene += 0.5*std::log(sss) + static_cast<double>(narg)*0.5*std::log(0.5*M_PI*M_PI/ss2);
+     947         156 :   if(doscale_ || doregres_zero_) ene += 0.5*std::log(sss);
+     948         156 :   if(dooffset_) ene += 0.5*std::log(sss);
+     949         156 :   return kbt_ * ene;
+     950             : }
+     951             : 
+     952         144 : double Metainference::getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     953             :                                    const double scale, const double offset)
+     954             : {
+     955         144 :   const double scale2 = scale*scale;
+     956             :   double ene = 0.0;
+     957         144 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     958             :   {
+     959             :     #pragma omp for reduction( + : ene)
+     960             :     for(unsigned i=0; i<narg; ++i) {
+     961             :       const double sm2 = sigma_mean2_[i];
+     962             :       const double ss2 = sigma[i]*sigma[i] + scale2*sm2;
+     963             :       const double sss = sigma[i]*sigma[i] + sm2;
+     964             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     965             :       const double a2  = 0.5*dev*dev + ss2;
+     966             :       if(sm2 > 0.0) {
+     967             :         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)));
+     968             :       }
+     969             :       else {
+     970             :         ene += 0.5*std::log(sss) + 0.5*std::log(0.5*M_PI*M_PI/ss2) + std::log(2.0*a2);
+     971             :       }
+     972             :       if(doscale_ || doregres_zero_)  ene += 0.5*std::log(sss);
+     973             :       if(dooffset_) ene += 0.5*std::log(sss);
+     974             :     }
+     975             :   }
+     976         144 :   return kbt_ * ene;
+     977             : }
+     978             : 
+     979          48 : double Metainference::getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     980             :                                      const double scale, const double offset)
+     981             : {
+     982             :   double ene = 0.0;
+     983          48 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     984             :   {
+     985             :     #pragma omp for reduction( + : ene)
+     986             :     for(unsigned i=0; i<narg; ++i) {
+     987             :       const double inv_sb2  = 1./(sigma[i]*sigma[i]);
+     988             :       const double inv_sm2  = 1./sigma_mean2_[i];
+     989             :       double devb = 0;
+     990             :       if(gen_likelihood_==LIKE_GAUSS)     devb = scale*ftilde[i]-parameters[i]+offset;
+     991             :       else if(gen_likelihood_==LIKE_LOGN) devb = std::log(scale*ftilde[i]/parameters[i]);
+     992             :       double devm = mean[i] - ftilde[i];
+     993             :       // deviation + normalisation + jeffrey
+     994             :       double normb = 0.;
+     995             :       if(gen_likelihood_==LIKE_GAUSS)     normb = -0.5*std::log(0.5/M_PI*inv_sb2);
+     996             :       else if(gen_likelihood_==LIKE_LOGN) normb = -0.5*std::log(0.5/M_PI*inv_sb2/(parameters[i]*parameters[i]));
+     997             :       const double normm         = -0.5*std::log(0.5/M_PI*inv_sm2);
+     998             :       const double jeffreys      = -0.5*std::log(2.*inv_sb2);
+     999             :       ene += 0.5*devb*devb*inv_sb2 + 0.5*devm*devm*inv_sm2 + normb + normm + jeffreys;
+    1000             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+    1001             :       if(dooffset_) ene += jeffreys;
+    1002             :     }
+    1003             :   }
+    1004          48 :   return kbt_ * ene;
+    1005             : }
+    1006             : 
+    1007          36 : double Metainference::getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+    1008             :                                   const double scale, const double offset)
+    1009             : {
+    1010          36 :   const double scale2  = scale*scale;
+    1011          36 :   const double inv_s2  = 1./(sigma[0]*sigma[0] + scale2*sigma_mean2_[0]);
+    1012          36 :   const double inv_sss = 1./(sigma[0]*sigma[0] + sigma_mean2_[0]);
+    1013             : 
+    1014             :   double ene = 0.0;
+    1015          36 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+    1016             :   {
+    1017             :     #pragma omp for reduction( + : ene)
+    1018             :     for(unsigned i=0; i<narg; ++i) {
+    1019             :       double dev = scale*mean[i]-parameters[i]+offset;
+    1020             :       ene += 0.5*dev*dev*inv_s2;
+    1021             :     }
+    1022             :   }
+    1023          36 :   const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+    1024          36 :   const double jeffreys = -0.5*std::log(2.*inv_sss);
+    1025             :   // add Jeffrey's prior in case one sigma for all data points + one normalisation per datapoint
+    1026          36 :   ene += jeffreys + static_cast<double>(narg)*normalisation;
+    1027          36 :   if(doscale_ || doregres_zero_)  ene += jeffreys;
+    1028          36 :   if(dooffset_) ene += jeffreys;
+    1029             : 
+    1030          36 :   return kbt_ * ene;
+    1031             : }
+    1032             : 
+    1033         152 : double Metainference::getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+    1034             :                                    const double scale, const double offset)
+    1035             : {
+    1036         152 :   const double scale2 = scale*scale;
+    1037             : 
+    1038             :   double ene = 0.0;
+    1039         152 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+    1040             :   {
+    1041             :     #pragma omp for reduction( + : ene)
+    1042             :     for(unsigned i=0; i<narg; ++i) {
+    1043             :       const double inv_s2  = 1./(sigma[i]*sigma[i] + scale2*sigma_mean2_[i]);
+    1044             :       const double inv_sss = 1./(sigma[i]*sigma[i] + sigma_mean2_[i]);
+    1045             :       double dev = scale*mean[i]-parameters[i]+offset;
+    1046             :       // deviation + normalisation + jeffrey
+    1047             :       const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+    1048             :       const double jeffreys      = -0.5*std::log(2.*inv_sss);
+    1049             :       ene += 0.5*dev*dev*inv_s2 + normalisation + jeffreys;
+    1050             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+    1051             :       if(dooffset_) ene += jeffreys;
+    1052             :     }
+    1053             :   }
+    1054         152 :   return kbt_ * ene;
+    1055             : }
+    1056             : 
+    1057          12 : void Metainference::moveTilde(const std::vector<double> &mean_, double &old_energy)
+    1058             : {
+    1059          12 :   std::vector<double> new_ftilde(sigma_.size());
+    1060          12 :   new_ftilde = ftilde_;
+    1061             : 
+    1062             :   // change all tildes
+    1063          36 :   for(unsigned j=0; j<sigma_.size(); j++) {
+    1064          24 :     const double r3 = random[0].Gaussian();
+    1065          24 :     const double ds3 = Dftilde_*std::sqrt(sigma_mean2_[j])*r3;
+    1066          24 :     new_ftilde[j] = ftilde_[j] + ds3;
+    1067             :   }
+    1068             :   // calculate new energy
+    1069          12 :   double new_energy = getEnergyMIGEN(mean_,new_ftilde,sigma_,scale_,offset_);
+    1070             : 
+    1071             :   // accept or reject
+    1072          12 :   const double delta = ( new_energy - old_energy ) / kbt_;
+    1073             :   // if delta is negative always accept move
+    1074          12 :   if( delta <= 0.0 ) {
+    1075          12 :     old_energy = new_energy;
+    1076          12 :     ftilde_ = new_ftilde;
+    1077          12 :     MCacceptFT_++;
+    1078             :     // otherwise extract random number
+    1079             :   } else {
+    1080           0 :     const double s = random[0].RandU01();
+    1081           0 :     if( s < std::exp(-delta) ) {
+    1082           0 :       old_energy = new_energy;
+    1083           0 :       ftilde_ = new_ftilde;
+    1084           0 :       MCacceptFT_++;
+    1085             :     }
+    1086             :   }
+    1087          12 : }
+    1088             : 
+    1089         168 : void Metainference::moveScaleOffset(const std::vector<double> &mean_, double &old_energy)
+    1090             : {
+    1091         168 :   double new_scale = scale_;
+    1092             : 
+    1093         168 :   if(doscale_) {
+    1094         144 :     if(scale_prior_==SC_FLAT) {
+    1095         144 :       const double r1 = random[1].Gaussian();
+    1096         144 :       const double ds1 = Dscale_*r1;
+    1097         144 :       new_scale += ds1;
+    1098             :       // check boundaries
+    1099         144 :       if(new_scale > scale_max_) {new_scale = 2.0 * scale_max_ - new_scale;}
+    1100         144 :       if(new_scale < scale_min_) {new_scale = 2.0 * scale_min_ - new_scale;}
+    1101             :     } else {
+    1102           0 :       const double r1 = random[1].Gaussian();
+    1103           0 :       const double ds1 = 0.5*(scale_mu_-new_scale)+Dscale_*std::exp(1)/M_PI*r1;
+    1104           0 :       new_scale += ds1;
+    1105             :     }
+    1106             :   }
+    1107             : 
+    1108         168 :   double new_offset = offset_;
+    1109             : 
+    1110         168 :   if(dooffset_) {
+    1111          24 :     if(offset_prior_==SC_FLAT) {
+    1112          24 :       const double r1 = random[1].Gaussian();
+    1113          24 :       const double ds1 = Doffset_*r1;
+    1114          24 :       new_offset += ds1;
+    1115             :       // check boundaries
+    1116          24 :       if(new_offset > offset_max_) {new_offset = 2.0 * offset_max_ - new_offset;}
+    1117          24 :       if(new_offset < offset_min_) {new_offset = 2.0 * offset_min_ - new_offset;}
+    1118             :     } else {
+    1119           0 :       const double r1 = random[1].Gaussian();
+    1120           0 :       const double ds1 = 0.5*(offset_mu_-new_offset)+Doffset_*std::exp(1)/M_PI*r1;
+    1121           0 :       new_offset += ds1;
+    1122             :     }
+    1123             :   }
+    1124             : 
+    1125             :   // calculate new energy
+    1126             :   double new_energy = 0.;
+    1127             : 
+    1128         168 :   switch(noise_type_) {
+    1129          12 :   case GAUSS:
+    1130          12 :     new_energy = getEnergyGJ(mean_,sigma_,new_scale,new_offset);
+    1131             :     break;
+    1132          48 :   case MGAUSS:
+    1133          48 :     new_energy = getEnergyGJE(mean_,sigma_,new_scale,new_offset);
+    1134             :     break;
+    1135          48 :   case OUTLIERS:
+    1136          48 :     new_energy = getEnergySP(mean_,sigma_,new_scale,new_offset);
+    1137             :     break;
+    1138          48 :   case MOUTLIERS:
+    1139          48 :     new_energy = getEnergySPE(mean_,sigma_,new_scale,new_offset);
+    1140             :     break;
+    1141          12 :   case GENERIC:
+    1142          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,new_scale,new_offset);
+    1143             :     break;
+    1144             :   }
+    1145             : 
+    1146             :   // for the scale/offset we need to consider the total energy
+    1147         168 :   std::vector<double> totenergies(2);
+    1148         168 :   if(master) {
+    1149          96 :     totenergies[0] = old_energy;
+    1150          96 :     totenergies[1] = new_energy;
+    1151          96 :     if(nrep_>1) multi_sim_comm.Sum(totenergies);
+    1152             :   } else {
+    1153          72 :     totenergies[0] = 0;
+    1154          72 :     totenergies[1] = 0;
+    1155             :   }
+    1156         168 :   comm.Sum(totenergies);
+    1157             : 
+    1158             :   // accept or reject
+    1159         168 :   const double delta = ( totenergies[1] - totenergies[0] ) / kbt_;
+    1160             :   // if delta is negative always accept move
+    1161         168 :   if( delta <= 0.0 ) {
+    1162         168 :     old_energy = new_energy;
+    1163         168 :     scale_ = new_scale;
+    1164         168 :     offset_ = new_offset;
+    1165         168 :     MCacceptScale_++;
+    1166             :     // otherwise extract random number
+    1167             :   } else {
+    1168           0 :     double s = random[1].RandU01();
+    1169           0 :     if( s < std::exp(-delta) ) {
+    1170           0 :       old_energy = new_energy;
+    1171           0 :       scale_ = new_scale;
+    1172           0 :       offset_ = new_offset;
+    1173           0 :       MCacceptScale_++;
+    1174             :     }
+    1175             :   }
+    1176         168 : }
+    1177             : 
+    1178         178 : void Metainference::moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow)
+    1179             : {
+    1180         178 :   std::vector<double> new_sigma(sigma_.size());
+    1181         178 :   new_sigma = sigma_;
+    1182             : 
+    1183             :   // change MCchunksize_ sigmas
+    1184         178 :   if (MCchunksize_ > 0) {
+    1185           0 :     if ((MCchunksize_ * i) >= sigma_.size()) {
+    1186             :       // This means we are not moving any sigma, so we should break immediately
+    1187           0 :       breaknow = true;
+    1188             :     }
+    1189             : 
+    1190             :     // change random sigmas
+    1191           0 :     for(unsigned j=0; j<MCchunksize_; j++) {
+    1192           0 :       const unsigned shuffle_index = j + MCchunksize_ * i;
+    1193           0 :       if (shuffle_index >= sigma_.size()) {
+    1194             :         // Going any further will segfault but we should still evaluate the sigmas we changed
+    1195             :         break;
+    1196             :       }
+    1197           0 :       const unsigned index = indices[shuffle_index];
+    1198           0 :       const double r2 = random[0].Gaussian();
+    1199           0 :       const double ds2 = Dsigma_[index]*r2;
+    1200           0 :       new_sigma[index] = sigma_[index] + ds2;
+    1201             :       // check boundaries
+    1202           0 :       if(new_sigma[index] > sigma_max_[index]) {new_sigma[index] = 2.0 * sigma_max_[index] - new_sigma[index];}
+    1203           0 :       if(new_sigma[index] < sigma_min_[index]) {new_sigma[index] = 2.0 * sigma_min_[index] - new_sigma[index];}
+    1204             :     }
+    1205             :   } else {
+    1206             :     // change all sigmas
+    1207        3008 :     for(unsigned j=0; j<sigma_.size(); j++) {
+    1208        2830 :       const double r2 = random[0].Gaussian();
+    1209        2830 :       const double ds2 = Dsigma_[j]*r2;
+    1210        2830 :       new_sigma[j] = sigma_[j] + ds2;
+    1211             :       // check boundaries
+    1212        2830 :       if(new_sigma[j] > sigma_max_[j]) {new_sigma[j] = 2.0 * sigma_max_[j] - new_sigma[j];}
+    1213        2830 :       if(new_sigma[j] < sigma_min_[j]) {new_sigma[j] = 2.0 * sigma_min_[j] - new_sigma[j];}
+    1214             :     }
+    1215             :   }
+    1216             : 
+    1217         178 :   if (breaknow) {
+    1218             :     // We didnt move any sigmas, so no sense in evaluating anything
+    1219             :     return;
+    1220             :   }
+    1221             : 
+    1222             :   // calculate new energy
+    1223             :   double new_energy = 0.;
+    1224         178 :   switch(noise_type_) {
+    1225          12 :   case GAUSS:
+    1226          12 :     new_energy = getEnergyGJ(mean_,new_sigma,scale_,offset_);
+    1227             :     break;
+    1228          52 :   case MGAUSS:
+    1229          52 :     new_energy = getEnergyGJE(mean_,new_sigma,scale_,offset_);
+    1230             :     break;
+    1231          54 :   case OUTLIERS:
+    1232          54 :     new_energy = getEnergySP(mean_,new_sigma,scale_,offset_);
+    1233             :     break;
+    1234          48 :   case MOUTLIERS:
+    1235          48 :     new_energy = getEnergySPE(mean_,new_sigma,scale_,offset_);
+    1236             :     break;
+    1237          12 :   case GENERIC:
+    1238          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,new_sigma,scale_,offset_);
+    1239             :     break;
+    1240             :   }
+    1241             : 
+    1242             :   // accept or reject
+    1243         178 :   const double delta = ( new_energy - old_energy ) / kbt_;
+    1244             :   // if delta is negative always accept move
+    1245         178 :   if( delta <= 0.0 ) {
+    1246         178 :     old_energy = new_energy;
+    1247         178 :     sigma_ = new_sigma;
+    1248         178 :     MCaccept_++;
+    1249             :     // otherwise extract random number
+    1250             :   } else {
+    1251           0 :     const double s = random[0].RandU01();
+    1252           0 :     if( s < std::exp(-delta) ) {
+    1253           0 :       old_energy = new_energy;
+    1254           0 :       sigma_ = new_sigma;
+    1255           0 :       MCaccept_++;
+    1256             :     }
+    1257             :   }
+    1258             : }
+    1259             : 
+    1260         178 : double Metainference::doMonteCarlo(const std::vector<double> &mean_)
+    1261             : {
+    1262             :   // calculate old energy with the updated coordinates
+    1263         178 :   double old_energy=0.;
+    1264             : 
+    1265         178 :   switch(noise_type_) {
+    1266          12 :   case GAUSS:
+    1267          12 :     old_energy = getEnergyGJ(mean_,sigma_,scale_,offset_);
+    1268          12 :     break;
+    1269          52 :   case MGAUSS:
+    1270          52 :     old_energy = getEnergyGJE(mean_,sigma_,scale_,offset_);
+    1271          52 :     break;
+    1272          54 :   case OUTLIERS:
+    1273          54 :     old_energy = getEnergySP(mean_,sigma_,scale_,offset_);
+    1274          54 :     break;
+    1275          48 :   case MOUTLIERS:
+    1276          48 :     old_energy = getEnergySPE(mean_,sigma_,scale_,offset_);
+    1277          48 :     break;
+    1278          12 :   case GENERIC:
+    1279          12 :     old_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,scale_,offset_);
+    1280          12 :     break;
+    1281             :   }
+    1282             : 
+    1283             :   // do not run MC if this is a replica-exchange trial
+    1284         178 :   if(!getExchangeStep()) {
+    1285             : 
+    1286             :     // Create std::vector of random sigma indices
+    1287             :     std::vector<unsigned> indices;
+    1288         178 :     if (MCchunksize_ > 0) {
+    1289           0 :       for (unsigned j=0; j<sigma_.size(); j++) {
+    1290           0 :         indices.push_back(j);
+    1291             :       }
+    1292           0 :       random[2].Shuffle(indices);
+    1293             :     }
+    1294         178 :     bool breaknow = false;
+    1295             : 
+    1296             :     // cycle on MC steps
+    1297         356 :     for(unsigned i=0; i<MCsteps_; ++i) {
+    1298         178 :       MCtrial_++;
+    1299             :       // propose move for ftilde
+    1300         178 :       if(noise_type_==GENERIC) moveTilde(mean_, old_energy);
+    1301             :       // propose move for scale and/or offset
+    1302         178 :       if(doscale_||dooffset_) moveScaleOffset(mean_, old_energy);
+    1303             :       // propose move for sigma
+    1304         178 :       moveSigmas(mean_, old_energy, i, indices, breaknow);
+    1305             :       // exit from the loop if this is the case
+    1306         178 :       if(breaknow) break;
+    1307             :     }
+    1308             : 
+    1309             :     /* save the result of the sampling */
+    1310             :     /* ftilde */
+    1311         178 :     if(noise_type_==GENERIC) {
+    1312          12 :       double accept = static_cast<double>(MCacceptFT_) / static_cast<double>(MCtrial_);
+    1313          12 :       valueAcceptFT->set(accept);
+    1314          36 :       for(unsigned i=0; i<sigma_.size(); i++) valueFtilde[i]->set(ftilde_[i]);
+    1315             :     }
+    1316             :     /* scale and offset */
+    1317         178 :     if(doscale_ || doregres_zero_) valueScale->set(scale_);
+    1318         178 :     if(dooffset_) valueOffset->set(offset_);
+    1319         178 :     if(doscale_||dooffset_) {
+    1320         168 :       double accept = static_cast<double>(MCacceptScale_) / static_cast<double>(MCtrial_);
+    1321         168 :       valueAcceptScale->set(accept);
+    1322             :     }
+    1323             :     /* sigmas */
+    1324        3008 :     for(unsigned i=0; i<sigma_.size(); i++) valueSigma[i]->set(sigma_[i]);
+    1325         178 :     double accept = static_cast<double>(MCaccept_) / static_cast<double>(MCtrial_);
+    1326         178 :     valueAccept->set(accept);
+    1327             :   }
+    1328             : 
+    1329             :   // here we sum the score over the replicas to get the full metainference score that we save as a bias
+    1330         178 :   if(master) {
+    1331         104 :     if(nrep_>1) multi_sim_comm.Sum(old_energy);
+    1332             :   } else {
+    1333          74 :     old_energy=0;
+    1334             :   }
+    1335         178 :   comm.Sum(old_energy);
+    1336             : 
+    1337             :   // this is the energy with current coordinates and parameters
+    1338         178 :   return old_energy;
+    1339             : }
+    1340             : 
+    1341             : /*
+    1342             :    In the following energy-force functions we don't add the normalisation and the jeffreys priors
+    1343             :    because they are not needed for the forces, the correct MetaInference energy is the one calculated
+    1344             :    in the Monte-Carlo
+    1345             : */
+    1346             : 
+    1347          54 : void Metainference::getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1348             :                                      const std::vector<double> &dmean_b)
+    1349             : {
+    1350          54 :   const double scale2 = scale_*scale_;
+    1351          54 :   const double sm2    = sigma_mean2_[0];
+    1352          54 :   const double ss2    = sigma_[0]*sigma_[0] + scale2*sm2;
+    1353          54 :   std::vector<double> f(narg,0);
+    1354             : 
+    1355          54 :   if(master) {
+    1356          30 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1357             :     {
+    1358             :       #pragma omp for
+    1359             :       for(unsigned i=0; i<narg; ++i) {
+    1360             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1361             :         const double a2 = 0.5*dev*dev + ss2;
+    1362             :         if(sm2 > 0.0) {
+    1363             :           const double t = std::exp(-a2/sm2);
+    1364             :           const double dt = 1./t;
+    1365             :           const double dit = 1./(1.-dt);
+    1366             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1367             :         }
+    1368             :         else {
+    1369             :           f[i] = -scale_*dev*(1./a2);
+    1370             :         }
+    1371             :       }
+    1372             :     }
+    1373             :     // collect contribution to forces and energy from other replicas
+    1374          30 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1375             :   }
+    1376             :   // intra-replica summation
+    1377          54 :   comm.Sum(&f[0],narg);
+    1378             : 
+    1379             :   double w_tmp = 0.;
+    1380         288 :   for(unsigned i=0; i<narg; ++i) {
+    1381         234 :     setOutputForce(i, kbt_*f[i]*dmean_x[i]);
+    1382         234 :     w_tmp += kbt_*f[i]*dmean_b[i];
+    1383             :   }
+    1384             : 
+    1385          54 :   if(do_reweight_) {
+    1386          48 :     setOutputForce(narg, w_tmp);
+    1387          96 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1388             :   }
+    1389          54 : }
+    1390             : 
+    1391          48 : void Metainference::getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1392             :                                       const std::vector<double> &dmean_b)
+    1393             : {
+    1394          48 :   const double scale2 = scale_*scale_;
+    1395          48 :   std::vector<double> f(narg,0);
+    1396             : 
+    1397          48 :   if(master) {
+    1398          24 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1399             :     {
+    1400             :       #pragma omp for
+    1401             :       for(unsigned i=0; i<narg; ++i) {
+    1402             :         const double sm2 = sigma_mean2_[i];
+    1403             :         const double ss2 = sigma_[i]*sigma_[i] + scale2*sm2;
+    1404             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1405             :         const double a2  = 0.5*dev*dev + ss2;
+    1406             :         if(sm2 > 0.0) {
+    1407             :           const double t   = std::exp(-a2/sm2);
+    1408             :           const double dt  = 1./t;
+    1409             :           const double dit = 1./(1.-dt);
+    1410             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1411             :         }
+    1412             :         else {
+    1413             :           f[i] = -scale_*dev*(1./a2);
+    1414             :         }
+    1415             :       }
+    1416             :     }
+    1417             :     // collect contribution to forces and energy from other replicas
+    1418          24 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1419             :   }
+    1420          48 :   comm.Sum(&f[0],narg);
+    1421             : 
+    1422             :   double w_tmp = 0.;
+    1423         240 :   for(unsigned i=0; i<narg; ++i) {
+    1424         192 :     setOutputForce(i, kbt_ * dmean_x[i] * f[i]);
+    1425         192 :     w_tmp += kbt_ * dmean_b[i] *f[i];
+    1426             :   }
+    1427             : 
+    1428          48 :   if(do_reweight_) {
+    1429          48 :     setOutputForce(narg, w_tmp);
+    1430          96 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1431             :   }
+    1432          48 : }
+    1433             : 
+    1434          12 : void Metainference::getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1435             :                                      const std::vector<double> &dmean_b)
+    1436             : {
+    1437          12 :   const double scale2 = scale_*scale_;
+    1438          12 :   double inv_s2=0.;
+    1439             : 
+    1440          12 :   if(master) {
+    1441          12 :     inv_s2 = 1./(sigma_[0]*sigma_[0] + scale2*sigma_mean2_[0]);
+    1442          12 :     if(nrep_>1) multi_sim_comm.Sum(inv_s2);
+    1443             :   }
+    1444          12 :   comm.Sum(inv_s2);
+    1445             : 
+    1446             :   double w_tmp = 0.;
+    1447          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1448             :   {
+    1449             :     #pragma omp for reduction( + : w_tmp)
+    1450             :     for(unsigned i=0; i<narg; ++i) {
+    1451             :       const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1452             :       const double mult = dev*scale_*inv_s2;
+    1453             :       setOutputForce(i, -kbt_*dmean_x[i]*mult);
+    1454             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1455             :     }
+    1456             :   }
+    1457             : 
+    1458          12 :   if(do_reweight_) {
+    1459           0 :     setOutputForce(narg, -w_tmp);
+    1460           0 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1461             :   }
+    1462          12 : }
+    1463             : 
+    1464          52 : void Metainference::getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1465             :                                       const std::vector<double> &dmean_b)
+    1466             : {
+    1467          52 :   const double scale2 = scale_*scale_;
+    1468          52 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1469             : 
+    1470          52 :   if(master) {
+    1471        1300 :     for(unsigned i=0; i<sigma_.size(); ++i) inv_s2[i] = 1./(sigma_[i]*sigma_[i] + scale2*sigma_mean2_[i]);
+    1472          26 :     if(nrep_>1) multi_sim_comm.Sum(&inv_s2[0],sigma_.size());
+    1473             :   }
+    1474          52 :   comm.Sum(&inv_s2[0],sigma_.size());
+    1475             : 
+    1476             :   double w_tmp = 0.;
+    1477          52 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1478             :   {
+    1479             :     #pragma omp for reduction( + : w_tmp)
+    1480             :     for(unsigned i=0; i<narg; ++i) {
+    1481             :       const double dev  = scale_*mean[i]-parameters[i]+offset_;
+    1482             :       const double mult = dev*scale_*inv_s2[i];
+    1483             :       setOutputForce(i, -kbt_*dmean_x[i]*mult);
+    1484             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1485             :     }
+    1486             :   }
+    1487             : 
+    1488          52 :   if(do_reweight_) {
+    1489          52 :     setOutputForce(narg, -w_tmp);
+    1490         104 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1491             :   }
+    1492          52 : }
+    1493             : 
+    1494          12 : void Metainference::getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b)
+    1495             : {
+    1496          12 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1497          12 :   std::vector<double> dev(sigma_.size(),0.);
+    1498          12 :   std::vector<double> dev2(sigma_.size(),0.);
+    1499             : 
+    1500          36 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1501          24 :     inv_s2[i]   = 1./sigma_mean2_[i];
+    1502          24 :     if(master) {
+    1503          24 :       dev[i]  = (mean[i]-ftilde_[i]);
+    1504          24 :       dev2[i] = dev[i]*dev[i];
+    1505             :     }
+    1506             :   }
+    1507          12 :   if(master&&nrep_>1) {
+    1508           0 :     multi_sim_comm.Sum(&dev[0],dev.size());
+    1509           0 :     multi_sim_comm.Sum(&dev2[0],dev2.size());
+    1510             :   }
+    1511          12 :   comm.Sum(&dev[0],dev.size());
+    1512          12 :   comm.Sum(&dev2[0],dev2.size());
+    1513             : 
+    1514             :   double dene_b = 0.;
+    1515          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(dene_b)
+    1516             :   {
+    1517             :     #pragma omp for reduction( + : dene_b)
+    1518             :     for(unsigned i=0; i<narg; ++i) {
+    1519             :       const double dene_x  = kbt_*inv_s2[i]*dmean_x[i]*dev[i];
+    1520             :       dene_b += kbt_*inv_s2[i]*dmean_b[i]*dev[i];
+    1521             :       setOutputForce(i, -dene_x);
+    1522             :     }
+    1523             :   }
+    1524             : 
+    1525          12 :   if(do_reweight_) {
+    1526           0 :     setOutputForce(narg, -dene_b);
+    1527           0 :     getPntrToComponent("biasDer")->set(dene_b);
+    1528             :   }
+    1529          12 : }
+    1530             : 
+    1531         178 : void Metainference::get_weights(const unsigned iselect, double &weight, double &norm, double &neff)
+    1532             : {
+    1533         178 :   const double dnrep = static_cast<double>(nrep_);
+    1534             :   // calculate the weights either from BIAS
+    1535         178 :   if(do_reweight_) {
+    1536         148 :     std::vector<double> bias(nrep_,0);
+    1537         148 :     if(master) {
+    1538          74 :       bias[replica_] = getArgument(narg);
+    1539          74 :       if(nrep_>1) multi_sim_comm.Sum(&bias[0], nrep_);
+    1540             :     }
+    1541         148 :     comm.Sum(&bias[0], nrep_);
+    1542             : 
+    1543             :     // accumulate weights
+    1544         148 :     const double decay = 1./static_cast<double> (average_weights_stride_);
+    1545         148 :     if(!firstTimeW[iselect]) {
+    1546         408 :       for(unsigned i=0; i<nrep_; ++i) {
+    1547         272 :         const double delta=bias[i]-average_weights_[iselect][i];
+    1548         272 :         average_weights_[iselect][i]+=decay*delta;
+    1549             :       }
+    1550             :     } else {
+    1551             :       firstTimeW[iselect] = false;
+    1552          36 :       for(unsigned i=0; i<nrep_; ++i) average_weights_[iselect][i] = bias[i];
+    1553             :     }
+    1554             : 
+    1555             :     // set average back into bias and set norm to one
+    1556         148 :     const double maxbias = *(std::max_element(average_weights_[iselect].begin(), average_weights_[iselect].end()));
+    1557         444 :     for(unsigned i=0; i<nrep_; ++i) bias[i] = std::exp((average_weights_[iselect][i]-maxbias)/kbt_);
+    1558             :     // set local weight, norm and weight variance
+    1559         148 :     weight = bias[replica_];
+    1560             :     double w2=0.;
+    1561         444 :     for(unsigned i=0; i<nrep_; ++i) {
+    1562         296 :       w2 += bias[i]*bias[i];
+    1563         296 :       norm += bias[i];
+    1564             :     }
+    1565         148 :     neff = norm*norm/w2;
+    1566         296 :     getPntrToComponent("weight")->set(weight/norm);
+    1567             :   } else {
+    1568             :     // or arithmetic ones
+    1569          30 :     neff = dnrep;
+    1570          30 :     weight = 1.0;
+    1571          30 :     norm = dnrep;
+    1572             :   }
+    1573         178 :   getPntrToComponent("neff")->set(neff);
+    1574         178 : }
+    1575             : 
+    1576         178 : void Metainference::get_sigma_mean(const unsigned iselect, const double weight, const double norm, const double neff, const std::vector<double> &mean)
+    1577             : {
+    1578         178 :   const double dnrep    = static_cast<double>(nrep_);
+    1579         178 :   std::vector<double> sigma_mean2_tmp(sigma_mean2_.size(), 0.);
+    1580             : 
+    1581         178 :   if(do_optsigmamean_>0) {
+    1582             :     // remove first entry of the history std::vector
+    1583           0 :     if(sigma_mean2_last_[iselect][0].size()==optsigmamean_stride_&&optsigmamean_stride_>0)
+    1584           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].erase(sigma_mean2_last_[iselect][i].begin());
+    1585             :     /* this is the current estimate of sigma mean for each argument
+    1586             :        there is one of this per argument in any case  because it is
+    1587             :        the maximum among these to be used in case of GAUSS/OUTLIER */
+    1588           0 :     std::vector<double> sigma_mean2_now(narg,0);
+    1589           0 :     if(master) {
+    1590           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] = weight*(getArgument(i)-mean[i])*(getArgument(i)-mean[i]);
+    1591           0 :       if(nrep_>1) multi_sim_comm.Sum(&sigma_mean2_now[0], narg);
+    1592             :     }
+    1593           0 :     comm.Sum(&sigma_mean2_now[0], narg);
+    1594           0 :     for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] *= 1.0/(neff-1.)/norm;
+    1595             : 
+    1596             :     // add sigma_mean2 to history
+    1597           0 :     if(optsigmamean_stride_>0) {
+    1598           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].push_back(sigma_mean2_now[i]);
+    1599             :     } else {
+    1600           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];
+    1601             :     }
+    1602             : 
+    1603           0 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1604           0 :       for(unsigned i=0; i<narg; ++i) {
+    1605             :         /* set to the maximum in history std::vector */
+    1606           0 :         sigma_mean2_tmp[i] = *max_element(sigma_mean2_last_[iselect][i].begin(), sigma_mean2_last_[iselect][i].end());
+    1607             :         /* the standard error of the mean */
+    1608           0 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1609           0 :         if(noise_type_==GENERIC) {
+    1610           0 :           sigma_min_[i] = std::sqrt(sigma_mean2_tmp[i]);
+    1611           0 :           if(sigma_[i] < sigma_min_[i]) sigma_[i] = sigma_min_[i];
+    1612             :         }
+    1613             :       }
+    1614           0 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1615             :       // find maximum for each data point
+    1616             :       std::vector <double> max_values;
+    1617           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()));
+    1618             :       // find maximum across data points
+    1619           0 :       const double max_now = *max_element(max_values.begin(), max_values.end());
+    1620             :       // set new value
+    1621           0 :       sigma_mean2_tmp[0] = max_now;
+    1622           0 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1623             :     }
+    1624             :     // endif sigma mean optimization
+    1625             :     // start sigma max optimization
+    1626           0 :     if(do_optsigmamean_>1&&!sigmamax_opt_done_) {
+    1627           0 :       for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1628           0 :         if(sigma_max_est_[i]<sigma_mean2_tmp[i]&&optimized_step_>optsigmamean_stride_) sigma_max_est_[i]=sigma_mean2_tmp[i];
+    1629             :         // ready to set once and for all the value of sigma_max
+    1630           0 :         if(optimized_step_==N_optimized_step_) {
+    1631           0 :           sigmamax_opt_done_=true;
+    1632           0 :           for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1633           0 :             sigma_max_[i]=std::sqrt(sigma_max_est_[i]*dnrep);
+    1634           0 :             Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+    1635           0 :             if(sigma_[i]>sigma_max_[i]) sigma_[i]=sigma_max_[i];
+    1636             :           }
+    1637             :         }
+    1638             :       }
+    1639           0 :       optimized_step_++;
+    1640             :     }
+    1641             :     // end sigma max optimization
+    1642             :   } else {
+    1643         178 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1644        2876 :       for(unsigned i=0; i<narg; ++i) {
+    1645        2764 :         sigma_mean2_tmp[i] = sigma_mean2_last_[iselect][i][0];
+    1646        2764 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1647             :       }
+    1648          66 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1649          66 :       sigma_mean2_tmp[0] = sigma_mean2_last_[iselect][0][0];
+    1650          66 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1651             :     }
+    1652             :   }
+    1653             : 
+    1654         178 :   sigma_mean2_ = sigma_mean2_tmp;
+    1655         178 : }
+    1656             : 
+    1657         178 : void Metainference::replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b)
+    1658             : {
+    1659         178 :   if(master) {
+    1660        1660 :     for(unsigned i=0; i<narg; ++i) mean[i] = weight/norm*getArgument(i);
+    1661         104 :     if(nrep_>1) multi_sim_comm.Sum(&mean[0], narg);
+    1662             :   }
+    1663         178 :   comm.Sum(&mean[0], narg);
+    1664             :   // set the derivative of the mean with respect to the bias
+    1665        3200 :   for(unsigned i=0; i<narg; ++i) dmean_b[i] = weight/norm/kbt_*(getArgument(i)-mean[i])/static_cast<double>(average_weights_stride_);
+    1666             : 
+    1667             :   // this is only for generic metainference
+    1668         178 :   if(firstTime) {ftilde_ = mean; firstTime = false;}
+    1669         178 : }
+    1670             : 
+    1671           0 : void Metainference::do_regression_zero(const std::vector<double> &mean)
+    1672             : {
+    1673             : // parameters[i] = scale_ * mean[i]: find scale_ with linear regression
+    1674             :   double num = 0.0;
+    1675             :   double den = 0.0;
+    1676           0 :   for(unsigned i=0; i<parameters.size(); ++i) {
+    1677           0 :     num += mean[i] * parameters[i];
+    1678           0 :     den += mean[i] * mean[i];
+    1679             :   }
+    1680           0 :   if(den>0) {
+    1681           0 :     scale_ = num / den;
+    1682             :   } else {
+    1683           0 :     scale_ = 1.0;
+    1684             :   }
+    1685           0 : }
+    1686             : 
+    1687         178 : void Metainference::calculate()
+    1688             : {
+    1689             :   // get step
+    1690         178 :   const long int step = getStep();
+    1691             : 
+    1692             :   unsigned iselect = 0;
+    1693             :   // set the value of selector for  REM-like stuff
+    1694         178 :   if(selector_.length()>0) iselect = static_cast<unsigned>(plumed.passMap[selector_]);
+    1695             : 
+    1696             :   /* 1) collect weights */
+    1697         178 :   double weight = 0.;
+    1698         178 :   double neff = 0.;
+    1699         178 :   double norm = 0.;
+    1700         178 :   get_weights(iselect, weight, norm, neff);
+    1701             : 
+    1702             :   /* 2) calculate average */
+    1703         178 :   std::vector<double> mean(narg,0);
+    1704             :   // this is the derivative of the mean with respect to the argument
+    1705         178 :   std::vector<double> dmean_x(narg,weight/norm);
+    1706             :   // this is the derivative of the mean with respect to the bias
+    1707         178 :   std::vector<double> dmean_b(narg,0);
+    1708             :   // calculate it
+    1709         178 :   replica_averaging(weight, norm, mean, dmean_b);
+    1710             : 
+    1711             :   /* 3) calculates parameters */
+    1712         178 :   get_sigma_mean(iselect, weight, norm, neff, mean);
+    1713             : 
+    1714             :   // in case of regression with zero intercept, calculate scale
+    1715         178 :   if(doregres_zero_ && step%nregres_zero_==0) do_regression_zero(mean);
+    1716             : 
+    1717             :   /* 4) run monte carlo */
+    1718         178 :   double ene = doMonteCarlo(mean);
+    1719             : 
+    1720             :   // calculate bias and forces
+    1721         178 :   switch(noise_type_) {
+    1722          12 :   case GAUSS:
+    1723          12 :     getEnergyForceGJ(mean, dmean_x, dmean_b);
+    1724             :     break;
+    1725          52 :   case MGAUSS:
+    1726          52 :     getEnergyForceGJE(mean, dmean_x, dmean_b);
+    1727             :     break;
+    1728          54 :   case OUTLIERS:
+    1729          54 :     getEnergyForceSP(mean, dmean_x, dmean_b);
+    1730             :     break;
+    1731          48 :   case MOUTLIERS:
+    1732          48 :     getEnergyForceSPE(mean, dmean_x, dmean_b);
+    1733             :     break;
+    1734          12 :   case GENERIC:
+    1735          12 :     getEnergyForceMIGEN(mean, dmean_x, dmean_b);
+    1736             :     break;
+    1737             :   }
+    1738             : 
+    1739             :   setBias(ene);
+    1740         178 : }
+    1741             : 
+    1742          19 : void Metainference::writeStatus()
+    1743             : {
+    1744          19 :   sfile_.rewind();
+    1745          19 :   sfile_.printField("time",getTimeStep()*getStep());
+    1746             :   //nsel
+    1747          38 :   for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+    1748             :     std::string msg_i,msg_j;
+    1749          19 :     Tools::convert(i,msg_i);
+    1750             :     std::vector <double> max_values;
+    1751             :     //narg
+    1752        2434 :     for(unsigned j=0; j<narg; ++j) {
+    1753        2415 :       Tools::convert(j,msg_j);
+    1754        2415 :       std::string msg = msg_i+"_"+msg_j;
+    1755        2415 :       if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1756        4780 :         sfile_.printField("sigmaMean_"+msg,std::sqrt(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end())));
+    1757             :       } else {
+    1758             :         // find maximum for each data point
+    1759          25 :         max_values.push_back(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end()));
+    1760             :       }
+    1761             :     }
+    1762          19 :     if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1763             :       // find maximum across data points
+    1764           6 :       const double max_now = std::sqrt(*max_element(max_values.begin(), max_values.end()));
+    1765           6 :       Tools::convert(0,msg_j);
+    1766           6 :       std::string msg = msg_i+"_"+msg_j;
+    1767          12 :       sfile_.printField("sigmaMean_"+msg, max_now);
+    1768             :     }
+    1769             :   }
+    1770        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1771             :     std::string msg;
+    1772        2396 :     Tools::convert(i,msg);
+    1773        4792 :     sfile_.printField("sigma_"+msg,sigma_[i]);
+    1774             :   }
+    1775        2415 :   for(unsigned i=0; i<sigma_max_.size(); ++i) {
+    1776             :     std::string msg;
+    1777        2396 :     Tools::convert(i,msg);
+    1778        4792 :     sfile_.printField("sigma_max_"+msg,sigma_max_[i]);
+    1779             :   }
+    1780          19 :   if(noise_type_==GENERIC) {
+    1781           3 :     for(unsigned i=0; i<ftilde_.size(); ++i) {
+    1782             :       std::string msg;
+    1783           2 :       Tools::convert(i,msg);
+    1784           4 :       sfile_.printField("ftilde_"+msg,ftilde_[i]);
+    1785             :     }
+    1786             :   }
+    1787          19 :   sfile_.printField("scale0_",scale_);
+    1788          19 :   sfile_.printField("offset0_",offset_);
+    1789          38 :   for(unsigned i=0; i<average_weights_.size(); i++) {
+    1790             :     std::string msg_i;
+    1791          19 :     Tools::convert(i,msg_i);
+    1792          38 :     sfile_.printField("weight_"+msg_i,average_weights_[i][replica_]);
+    1793             :   }
+    1794          19 :   sfile_.printField();
+    1795          19 :   sfile_.flush();
+    1796          19 : }
+    1797             : 
+    1798         178 : void Metainference::update() {
+    1799             :   // write status file
+    1800         178 :   if(write_stride_>0&& (getStep()%write_stride_==0 || getCPT()) ) writeStatus();
+    1801         178 : }
+    1802             : 
+    1803             : }
+    1804             : }
+    1805             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e7795038fc --- /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:75788885.2 %
Date:2024-06-10 08:19:14Functions: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
_ZN4PLMD4isdb17MetainferenceBase11writeStatusEv82
_ZN4PLMD4isdb17MetainferenceBaseC2ERKNS_13ActionOptionsE82
_ZN4PLMD4isdb17MetainferenceBaseD2Ev82
_ZN4PLMD4isdb17MetainferenceBase16registerKeywordsERNS_8KeywordsE89
_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.15
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.func.html b/coverage/isdb/MetainferenceBase.cpp.func.html new file mode 100644 index 0000000000..6bba0bfee6 --- /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:75788885.2 %
Date:2024-06-10 08:19:14Functions:232882.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase10InitialiseEj31
_ZN4PLMD4isdb17MetainferenceBase10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb2225
_ZN4PLMD4isdb17MetainferenceBase11getEnergyGJERKSt6vectorIdSaIdEES6_dd554
_ZN4PLMD4isdb17MetainferenceBase11getEnergySPERKSt6vectorIdSaIdEES6_dd12
_ZN4PLMD4isdb17MetainferenceBase11get_weightsERdS2_S2_2225
_ZN4PLMD4isdb17MetainferenceBase11writeStatusEv82
_ZN4PLMD4isdb17MetainferenceBase12doMonteCarloERKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase12getEnergyGJEERKSt6vectorIdSaIdEES6_dd368
_ZN4PLMD4isdb17MetainferenceBase12getEnergySPEERKSt6vectorIdSaIdEES6_dd5328
_ZN4PLMD4isdb17MetainferenceBase14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb17MetainferenceBase14get_sigma_meanEdddRKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase15moveScaleOffsetERKSt6vectorIdSaIdEERd1848
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_271
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_6
_ZN4PLMD4isdb17MetainferenceBase16registerKeywordsERNS_8KeywordsE89
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_160
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_1776
_ZN4PLMD4isdb17MetainferenceBase17replica_averagingEddRSt6vectorIdSaIdEES5_2225
_ZN4PLMD4isdb17MetainferenceBase18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb17MetainferenceBase19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb17MetainferenceBase8SelectorEv0
_ZN4PLMD4isdb17MetainferenceBase8getScoreEv2225
_ZN4PLMD4isdb17MetainferenceBase9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb17MetainferenceBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb17MetainferenceBaseC2ERKNS_13ActionOptionsE82
_ZN4PLMD4isdb17MetainferenceBaseD0Ev0
_ZN4PLMD4isdb17MetainferenceBaseD1Ev0
_ZN4PLMD4isdb17MetainferenceBaseD2Ev82
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.gcov.html b/coverage/isdb/MetainferenceBase.cpp.gcov.html new file mode 100644 index 0000000000..3f465f48e5 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.gcov.html @@ -0,0 +1,1640 @@ + + + + + + + + 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:75788885.2 %
Date:2024-06-10 08:19:14Functions: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          89 : void MetainferenceBase::registerKeywords( Keywords& keys ) {
+      35          89 :   Action::registerKeywords(keys);
+      36          89 :   ActionAtomistic::registerKeywords(keys);
+      37          89 :   ActionWithValue::registerKeywords(keys);
+      38          89 :   ActionWithArguments::registerKeywords(keys);
+      39          89 :   componentsAreNotOptional(keys);
+      40          89 :   keys.use("ARG");
+      41         178 :   keys.addFlag("DOSCORE",false,"activate metainference");
+      42         178 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+      43         178 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the ARG as energy");
+      44         178 :   keys.add("optional","AVERAGING", "Stride for calculation of averaged weights and sigma_mean");
+      45         178 :   keys.add("compulsory","NOISETYPE","MGAUSS","functional form of the noise (GAUSS,MGAUSS,OUTLIERS,MOUTLIERS,GENERIC)");
+      46         178 :   keys.add("compulsory","LIKELIHOOD","GAUSS","the likelihood for the GENERIC metainference model, GAUSS or LOGN");
+      47         178 :   keys.add("compulsory","DFTILDE","0.1","fraction of sigma_mean used to evolve ftilde");
+      48         178 :   keys.addFlag("SCALEDATA",false,"Set to TRUE if you want to sample a scaling factor common to all values and replicas");
+      49         178 :   keys.add("compulsory","SCALE0","1.0","initial value of the scaling factor");
+      50         178 :   keys.add("compulsory","SCALE_PRIOR","FLAT","either FLAT or GAUSSIAN");
+      51         178 :   keys.add("optional","SCALE_MIN","minimum value of the scaling factor");
+      52         178 :   keys.add("optional","SCALE_MAX","maximum value of the scaling factor");
+      53         178 :   keys.add("optional","DSCALE","maximum MC move of the scaling factor");
+      54         178 :   keys.addFlag("ADDOFFSET",false,"Set to TRUE if you want to sample an offset common to all values and replicas");
+      55         178 :   keys.add("compulsory","OFFSET0","0.0","initial value of the offset");
+      56         178 :   keys.add("compulsory","OFFSET_PRIOR","FLAT","either FLAT or GAUSSIAN");
+      57         178 :   keys.add("optional","OFFSET_MIN","minimum value of the offset");
+      58         178 :   keys.add("optional","OFFSET_MAX","maximum value of the offset");
+      59         178 :   keys.add("optional","DOFFSET","maximum MC move of the offset");
+      60         178 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+      61         178 :   keys.add("compulsory","SIGMA0","1.0","initial value of the uncertainty parameter");
+      62         178 :   keys.add("compulsory","SIGMA_MIN","0.0","minimum value of the uncertainty parameter");
+      63         178 :   keys.add("compulsory","SIGMA_MAX","10.","maximum value of the uncertainty parameter");
+      64         178 :   keys.add("optional","DSIGMA","maximum MC move of the uncertainty parameter");
+      65         178 :   keys.add("compulsory","OPTSIGMAMEAN","NONE","Set to NONE/SEM to manually set sigma mean, or to estimate it on the fly");
+      66         178 :   keys.add("optional","SIGMA_MEAN0","starting value for the uncertainty in the mean estimate");
+      67         178 :   keys.add("optional","SIGMA_MAX_STEPS", "Number of steps used to optimise SIGMA_MAX, before that the SIGMA_MAX value is used");
+      68         178 :   keys.add("optional","TEMP","the system temperature - this is only needed if code doesn't pass the temperature to plumed");
+      69         178 :   keys.add("optional","MC_STEPS","number of MC steps");
+      70         178 :   keys.add("optional","MC_CHUNKSIZE","MC chunksize");
+      71         178 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart/continuation of Metainference");
+      72         178 :   keys.add("compulsory","WRITE_STRIDE","10000","write the status to a file every N steps, this can be used for restart/continuation");
+      73         178 :   keys.add("optional","SELECTOR","name of selector");
+      74         178 :   keys.add("optional","NSELECT","range of values for selector [0, N-1]");
+      75          89 :   keys.use("RESTART");
+      76         178 :   keys.addOutputComponent("score",        "default",      "the Metainference score");
+      77         178 :   keys.addOutputComponent("sigma",        "default",      "uncertainty parameter");
+      78         178 :   keys.addOutputComponent("sigmaMean",    "default",      "uncertainty in the mean estimate");
+      79         178 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+      80         178 :   keys.addOutputComponent("acceptSigma",  "default",      "MC acceptance for sigma values");
+      81         178 :   keys.addOutputComponent("acceptScale",  "SCALEDATA",    "MC acceptance for scale value");
+      82         178 :   keys.addOutputComponent("acceptFT",     "GENERIC",      "MC acceptance for general metainference f tilde value");
+      83         178 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+      84         178 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+      85         178 :   keys.addOutputComponent("scale",        "SCALEDATA",    "scale parameter");
+      86         178 :   keys.addOutputComponent("offset",       "ADDOFFSET",    "offset parameter");
+      87         178 :   keys.addOutputComponent("ftilde",       "GENERIC",      "ensemble average estimator");
+      88          89 : }
+      89             : 
+      90          82 : MetainferenceBase::MetainferenceBase(const ActionOptions&ao):
+      91             :   Action(ao),
+      92             :   ActionAtomistic(ao),
+      93             :   ActionWithArguments(ao),
+      94             :   ActionWithValue(ao),
+      95          82 :   doscore_(false),
+      96          82 :   write_stride_(0),
+      97          82 :   narg(0),
+      98          82 :   doscale_(false),
+      99          82 :   scale_(1.),
+     100          82 :   scale_mu_(0),
+     101          82 :   scale_min_(1),
+     102          82 :   scale_max_(-1),
+     103          82 :   Dscale_(-1),
+     104          82 :   dooffset_(false),
+     105          82 :   offset_(0.),
+     106          82 :   offset_mu_(0),
+     107          82 :   offset_min_(1),
+     108          82 :   offset_max_(-1),
+     109          82 :   Doffset_(-1),
+     110          82 :   doregres_zero_(false),
+     111          82 :   nregres_zero_(0),
+     112          82 :   Dftilde_(0.1),
+     113          82 :   random(3),
+     114          82 :   MCsteps_(1),
+     115          82 :   MCaccept_(0),
+     116          82 :   MCacceptScale_(0),
+     117          82 :   MCacceptFT_(0),
+     118          82 :   MCtrial_(0),
+     119          82 :   MCchunksize_(0),
+     120          82 :   firstTime(true),
+     121          82 :   do_reweight_(false),
+     122          82 :   do_optsigmamean_(0),
+     123          82 :   nsel_(1),
+     124          82 :   iselect(0),
+     125          82 :   optsigmamean_stride_(0),
+     126          82 :   N_optimized_step_(0),
+     127          82 :   optimized_step_(0),
+     128          82 :   sigmamax_opt_done_(false),
+     129          82 :   decay_w_(1.)
+     130             : {
+     131          82 :   parseFlag("DOSCORE", doscore_);
+     132             : 
+     133          82 :   bool noensemble = false;
+     134          82 :   parseFlag("NOENSEMBLE", noensemble);
+     135             : 
+     136             :   // set up replica stuff
+     137          82 :   master = (comm.Get_rank()==0);
+     138          82 :   if(master) {
+     139          54 :     nrep_    = multi_sim_comm.Get_size();
+     140          54 :     replica_ = multi_sim_comm.Get_rank();
+     141          54 :     if(noensemble) nrep_ = 1;
+     142             :   } else {
+     143          28 :     nrep_    = 0;
+     144          28 :     replica_ = 0;
+     145             :   }
+     146          82 :   comm.Sum(&nrep_,1);
+     147          82 :   comm.Sum(&replica_,1);
+     148             : 
+     149          82 :   parse("SELECTOR", selector_);
+     150         164 :   parse("NSELECT", nsel_);
+     151             :   // do checks
+     152          82 :   if(selector_.length()>0 && nsel_<=1) error("With SELECTOR active, NSELECT must be greater than 1");
+     153          82 :   if(selector_.length()==0 && nsel_>1) error("With NSELECT greater than 1, you must specify SELECTOR");
+     154             : 
+     155             :   // initialise firstTimeW
+     156          82 :   firstTimeW.resize(nsel_, true);
+     157             : 
+     158             :   // reweight implies a different number of arguments (the latest one must always be the bias)
+     159          82 :   parseFlag("REWEIGHT", do_reweight_);
+     160          82 :   if(do_reweight_&&getNumberOfArguments()!=1) error("To REWEIGHT one must provide one single bias as an argument");
+     161          82 :   if(do_reweight_&&nrep_<2) error("REWEIGHT can only be used in parallel with 2 or more replicas");
+     162         163 :   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          82 :   unsigned averaging=0;
+     166          82 :   parse("AVERAGING", averaging);
+     167          82 :   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         164 :   parse("NOISETYPE",stringa_noise);
+     174          82 :   if(stringa_noise=="GAUSS")           noise_type_ = GAUSS;
+     175          75 :   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          82 :   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          82 :   parse("WRITE_STRIDE",write_stride_);
+     192         164 :   parse("STATUS_FILE",status_file_name_);
+     193         164 :   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         164 :   parse("OPTSIGMAMEAN", stringa_optsigma);
+     198          82 :   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          82 :   unsigned aver_max_steps=0;
+     203          82 :   parse("SIGMA_MAX_STEPS", aver_max_steps);
+     204          82 :   if(aver_max_steps==0&&do_optsigmamean_==2) aver_max_steps=averaging*2000;
+     205          82 :   if(aver_max_steps>0&&do_optsigmamean_<2) error("SIGMA_MAX_STEPS can only be used together with OPTSIGMAMEAN=SEM_MAX");
+     206          82 :   if(aver_max_steps>0&&do_optsigmamean_==2) N_optimized_step_=aver_max_steps;
+     207          82 :   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          82 :   parseVector("SIGMA_MEAN0",read_sigma_mean_);
+     211          82 :   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          82 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     215          74 :     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          51 :       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          82 :   parseFlag("SCALEDATA", doscale_);
+     232          82 :   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          82 :   parseFlag("ADDOFFSET", dooffset_);
+     251          82 :   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          82 :   parse("REGRES_ZERO", nregres_zero_);
+     272          82 :   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          82 :   parseVector("SIGMA0",readsigma);
+     282          82 :   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          82 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     285          74 :     sigma_.resize(readsigma.size());
+     286          74 :     sigma_=readsigma;
+     287           8 :   } else sigma_.resize(1, readsigma[0]);
+     288             : 
+     289             :   std::vector<double> readsigma_min;
+     290          82 :   parseVector("SIGMA_MIN",readsigma_min);
+     291          82 :   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          82 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     294          74 :     sigma_min_.resize(readsigma_min.size());
+     295          74 :     sigma_min_=readsigma_min;
+     296           8 :   } else sigma_min_.resize(1, readsigma_min[0]);
+     297             : 
+     298             :   std::vector<double> readsigma_max;
+     299          82 :   parseVector("SIGMA_MAX",readsigma_max);
+     300          82 :   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          82 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     303          74 :     sigma_max_.resize(readsigma_max.size());
+     304          74 :     sigma_max_=readsigma_max;
+     305           8 :   } else sigma_max_.resize(1, readsigma_max[0]);
+     306             : 
+     307          82 :   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          82 :   parseVector("DSIGMA",read_dsigma);
+     311          82 :   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          82 :   if(read_dsigma.size()>0) {
+     314          31 :     Dsigma_.resize(read_dsigma.size());
+     315          31 :     Dsigma_=read_dsigma;
+     316             :   } else {
+     317          51 :     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          82 :   parse("MC_STEPS",MCsteps_);
+     323          82 :   parse("MC_CHUNKSIZE", MCchunksize_);
+     324             :   // get temperature
+     325          82 :   double temp=0.0;
+     326          82 :   parse("TEMP",temp);
+     327          82 :   if(temp>0.0) kbt_=plumed.getAtoms().getKBoltzmann()*temp;
+     328          51 :   else kbt_=plumed.getAtoms().getKbT();
+     329          82 :   if(kbt_==0.0&&doscore_) error("Unless the MD engine passes the temperature to plumed, you must specify it using TEMP");
+     330             : 
+     331             :   // initialize random seed
+     332             :   unsigned iseed;
+     333          82 :   if(master) {
+     334          54 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     335          54 :     iseed = static_cast<unsigned>(ts)+replica_;
+     336             :   } else {
+     337          28 :     iseed = 0;
+     338             :   }
+     339          82 :   comm.Sum(&iseed, 1);
+     340             :   // this is used for ftilde and sigma both the move and the acceptance
+     341             :   // this is different for each replica
+     342          82 :   random[0].setSeed(-iseed);
+     343          82 :   if(doscale_||dooffset_) {
+     344             :     // in this case we want the same seed everywhere
+     345          14 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     346          14 :     iseed = static_cast<unsigned>(ts);
+     347          14 :     if(master&&nrep_>1) multi_sim_comm.Bcast(iseed,0);
+     348          14 :     comm.Bcast(iseed,0);
+     349             :     // this is used for scale and offset sampling and acceptance
+     350          14 :     random[1].setSeed(-iseed);
+     351             :   }
+     352             :   // this is used for random chunk of sigmas, and it is different for each replica
+     353          82 :   if(master) {
+     354          54 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     355          54 :     iseed = static_cast<unsigned>(ts)+replica_;
+     356             :   } else {
+     357          28 :     iseed = 0;
+     358             :   }
+     359          82 :   comm.Sum(&iseed, 1);
+     360          82 :   random[2].setSeed(-iseed);
+     361             : 
+     362             :   // outfile stuff
+     363          82 :   if(write_stride_>0&&doscore_) {
+     364          31 :     sfile_.link(*this);
+     365          31 :     sfile_.open(status_file_name_);
+     366             :   }
+     367             : 
+     368          82 : }
+     369             : 
+     370          82 : MetainferenceBase::~MetainferenceBase()
+     371             : {
+     372          82 :   if(sfile_.isOpen()) sfile_.close();
+     373         410 : }
+     374             : 
+     375          31 : void MetainferenceBase::Initialise(const unsigned input)
+     376             : {
+     377             :   setNarg(input);
+     378          31 :   if(narg!=parameters.size()) {
+     379           0 :     std::string num1; Tools::convert(parameters.size(),num1);
+     380           0 :     std::string num2; Tools::convert(narg,num2);
+     381           0 :     std::string msg = "The number of experimental values " + num1 +" must be the same of the calculated values " + num2;
+     382           0 :     error(msg);
+     383             :   }
+     384             : 
+     385             :   // resize std::vector for sigma_mean history
+     386          31 :   sigma_mean2_last_.resize(nsel_);
+     387          62 :   for(unsigned i=0; i<nsel_; i++) sigma_mean2_last_[i].resize(narg);
+     388          31 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     389          23 :     if(sigma_mean2_.size()==1) {
+     390          23 :       double tmp = sigma_mean2_[0];
+     391          23 :       sigma_mean2_.resize(narg, tmp);
+     392           0 :     } else if(sigma_mean2_.size()>1&&sigma_mean2_.size()!=narg) {
+     393           0 :       error("SIGMA_MEAN0 can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     394             :     }
+     395             :     // set the initial value for the history
+     396        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]);
+     397             :   } else {
+     398             :     // set the initial value for the history
+     399          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]);
+     400             :   }
+     401             : 
+     402             :   // set sigma_bias
+     403          31 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     404          23 :     if(sigma_.size()==1) {
+     405          23 :       double tmp = sigma_[0];
+     406          23 :       sigma_.resize(narg, tmp);
+     407           0 :     } else if(sigma_.size()>1&&sigma_.size()!=narg) {
+     408           0 :       error("SIGMA0 can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     409             :     }
+     410          23 :     if(sigma_min_.size()==1) {
+     411          23 :       double tmp = sigma_min_[0];
+     412          23 :       sigma_min_.resize(narg, tmp);
+     413           0 :     } else if(sigma_min_.size()>1&&sigma_min_.size()!=narg) {
+     414           0 :       error("SIGMA_MIN can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     415             :     }
+     416          23 :     if(sigma_max_.size()==1) {
+     417          23 :       double tmp = sigma_max_[0];
+     418          23 :       sigma_max_.resize(narg, tmp);
+     419           0 :     } else if(sigma_max_.size()>1&&sigma_max_.size()!=narg) {
+     420           0 :       error("SIGMA_MAX can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     421             :     }
+     422          23 :     if(Dsigma_.size()==1) {
+     423          23 :       double tmp = Dsigma_[0];
+     424          23 :       Dsigma_.resize(narg, tmp);
+     425           0 :     } else if(Dsigma_.size()>1&&Dsigma_.size()!=narg) {
+     426           0 :       error("DSIGMA can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     427             :     }
+     428             :   }
+     429             : 
+     430          31 :   sigma_max_est_.resize(sigma_max_.size(), 0.);
+     431             : 
+     432          31 :   IFile restart_sfile;
+     433          31 :   restart_sfile.link(*this);
+     434          31 :   if(getRestart()&&restart_sfile.FileExist(status_file_name_)) {
+     435           1 :     firstTime = false;
+     436           2 :     for(unsigned i=0; i<nsel_; i++) firstTimeW[i] = false;
+     437           1 :     restart_sfile.open(status_file_name_);
+     438           1 :     log.printf("  Restarting from %s\n", status_file_name_.c_str());
+     439             :     double dummy;
+     440           2 :     if(restart_sfile.scanField("time",dummy)) {
+     441             :       // check for syncronisation
+     442           1 :       std::vector<double> dummy_time(nrep_,0);
+     443           1 :       if(master&&nrep_>1) {
+     444           0 :         dummy_time[replica_] = dummy;
+     445           0 :         multi_sim_comm.Sum(dummy_time);
+     446             :       }
+     447           1 :       comm.Sum(dummy_time);
+     448           1 :       for(unsigned i=1; i<nrep_; i++) {
+     449           0 :         std::string msg = "METAINFERENCE restart files " + status_file_name_ + "  are not in sync";
+     450           0 :         if(dummy_time[i]!=dummy_time[0]) plumed_merror(msg);
+     451             :       }
+     452             :       // nsel
+     453           2 :       for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+     454             :         std::string msg_i;
+     455           1 :         Tools::convert(i,msg_i);
+     456             :         // narg
+     457           1 :         if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     458           0 :           for(unsigned j=0; j<narg; ++j) {
+     459             :             std::string msg_j;
+     460           0 :             Tools::convert(j,msg_j);
+     461           0 :             std::string msg = msg_i+"_"+msg_j;
+     462             :             double read_sm;
+     463           0 :             restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     464           0 :             sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     465             :           }
+     466             :         }
+     467           1 :         if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+     468             :           double read_sm;
+     469             :           std::string msg_j;
+     470           1 :           Tools::convert(0,msg_j);
+     471           1 :           std::string msg = msg_i+"_"+msg_j;
+     472           1 :           restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     473           8 :           for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     474             :         }
+     475             :       }
+     476             : 
+     477           2 :       for(unsigned i=0; i<sigma_.size(); ++i) {
+     478             :         std::string msg;
+     479           1 :         Tools::convert(i,msg);
+     480           2 :         restart_sfile.scanField("sigma_"+msg,sigma_[i]);
+     481             :       }
+     482           2 :       for(unsigned i=0; i<sigma_max_.size(); ++i) {
+     483             :         std::string msg;
+     484           1 :         Tools::convert(i,msg);
+     485           1 :         restart_sfile.scanField("sigma_max_"+msg,sigma_max_[i]);
+     486           1 :         sigmamax_opt_done_=true;
+     487             :       }
+     488           1 :       if(noise_type_==GENERIC) {
+     489           0 :         for(unsigned i=0; i<ftilde_.size(); ++i) {
+     490             :           std::string msg;
+     491           0 :           Tools::convert(i,msg);
+     492           0 :           restart_sfile.scanField("ftilde_"+msg,ftilde_[i]);
+     493             :         }
+     494             :       }
+     495           1 :       restart_sfile.scanField("scale0_",scale_);
+     496           1 :       restart_sfile.scanField("offset0_",offset_);
+     497             : 
+     498           2 :       for(unsigned i=0; i<nsel_; i++) {
+     499             :         std::string msg;
+     500           1 :         Tools::convert(i,msg);
+     501             :         double tmp_w;
+     502           1 :         restart_sfile.scanField("weight_"+msg,tmp_w);
+     503           1 :         if(master) {
+     504           1 :           average_weights_[i][replica_] = tmp_w;
+     505           1 :           if(nrep_>1) multi_sim_comm.Sum(&average_weights_[i][0], nrep_);
+     506             :         }
+     507           1 :         comm.Sum(&average_weights_[i][0], nrep_);
+     508             :       }
+     509             : 
+     510             :     }
+     511           1 :     restart_sfile.scanField();
+     512           1 :     restart_sfile.close();
+     513             :   }
+     514             : 
+     515             :   /* If DSIGMA is not yet initialised do it now */
+     516        2509 :   for(unsigned i=0; i<sigma_max_.size(); i++) if(Dsigma_[i]==-1) Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+     517             : 
+     518          31 :   addComponentWithDerivatives("score");
+     519          31 :   componentIsNotPeriodic("score");
+     520          31 :   valueScore=getPntrToComponent("score");
+     521             : 
+     522          31 :   if(do_reweight_) {
+     523          22 :     addComponent("biasDer");
+     524          22 :     componentIsNotPeriodic("biasDer");
+     525          22 :     addComponent("weight");
+     526          44 :     componentIsNotPeriodic("weight");
+     527             :   }
+     528             : 
+     529          31 :   addComponent("neff");
+     530          31 :   componentIsNotPeriodic("neff");
+     531             : 
+     532          31 :   if(doscale_ || doregres_zero_) {
+     533          12 :     addComponent("scale");
+     534          12 :     componentIsNotPeriodic("scale");
+     535          12 :     valueScale=getPntrToComponent("scale");
+     536             :   }
+     537             : 
+     538          31 :   if(dooffset_) {
+     539           2 :     addComponent("offset");
+     540           2 :     componentIsNotPeriodic("offset");
+     541           2 :     valueOffset=getPntrToComponent("offset");
+     542             :   }
+     543             : 
+     544          31 :   if(dooffset_||doscale_) {
+     545          14 :     addComponent("acceptScale");
+     546          14 :     componentIsNotPeriodic("acceptScale");
+     547          14 :     valueAcceptScale=getPntrToComponent("acceptScale");
+     548             :   }
+     549             : 
+     550          31 :   if(noise_type_==GENERIC) {
+     551           1 :     addComponent("acceptFT");
+     552           1 :     componentIsNotPeriodic("acceptFT");
+     553           1 :     valueAcceptFT=getPntrToComponent("acceptFT");
+     554             :   }
+     555             : 
+     556          31 :   addComponent("acceptSigma");
+     557          31 :   componentIsNotPeriodic("acceptSigma");
+     558          31 :   valueAccept=getPntrToComponent("acceptSigma");
+     559             : 
+     560          31 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     561        2493 :     for(unsigned i=0; i<sigma_mean2_.size(); ++i) {
+     562        2470 :       std::string num; Tools::convert(i,num);
+     563        4940 :       addComponent("sigmaMean-"+num); componentIsNotPeriodic("sigmaMean-"+num);
+     564        2470 :       valueSigmaMean.push_back(getPntrToComponent("sigmaMean-"+num));
+     565        2470 :       getPntrToComponent("sigmaMean-"+num)->set(std::sqrt(sigma_mean2_[i]));
+     566        4940 :       addComponent("sigma-"+num); componentIsNotPeriodic("sigma-"+num);
+     567        2470 :       valueSigma.push_back(getPntrToComponent("sigma-"+num));
+     568        2470 :       getPntrToComponent("sigma-"+num)->set(sigma_[i]);
+     569        2470 :       if(noise_type_==GENERIC) {
+     570           4 :         addComponent("ftilde-"+num); componentIsNotPeriodic("ftilde-"+num);
+     571           2 :         valueFtilde.push_back(getPntrToComponent("ftilde-"+num));
+     572             :       }
+     573             :     }
+     574          23 :   } else {
+     575          16 :     addComponent("sigmaMean"); componentIsNotPeriodic("sigmaMean");
+     576           8 :     valueSigmaMean.push_back(getPntrToComponent("sigmaMean"));
+     577           8 :     getPntrToComponent("sigmaMean")->set(std::sqrt(sigma_mean2_[0]));
+     578          16 :     addComponent("sigma"); componentIsNotPeriodic("sigma");
+     579           8 :     valueSigma.push_back(getPntrToComponent("sigma"));
+     580          16 :     getPntrToComponent("sigma")->set(sigma_[0]);
+     581             :   }
+     582             : 
+     583          31 :   switch(noise_type_) {
+     584           1 :   case GENERIC:
+     585           1 :     log.printf("  with general metainference ");
+     586           1 :     if(gen_likelihood_==LIKE_GAUSS) log.printf(" and a gaussian likelihood\n");
+     587           0 :     else if(gen_likelihood_==LIKE_LOGN) log.printf(" and a log-normal likelihood\n");
+     588           1 :     log.printf("  ensemble average parameter sampled with a step %lf of sigma_mean\n", Dftilde_);
+     589             :     break;
+     590           7 :   case GAUSS:
+     591           7 :     log.printf("  with gaussian noise and a single noise parameter for all the data\n");
+     592             :     break;
+     593          14 :   case MGAUSS:
+     594          14 :     log.printf("  with gaussian noise and a noise parameter for each data point\n");
+     595             :     break;
+     596           1 :   case OUTLIERS:
+     597           1 :     log.printf("  with long tailed gaussian noise and a single noise parameter for all the data\n");
+     598             :     break;
+     599           8 :   case MOUTLIERS:
+     600           8 :     log.printf("  with long tailed gaussian noise and a noise parameter for each data point\n");
+     601             :     break;
+     602             :   }
+     603             : 
+     604          31 :   if(doscale_) {
+     605             :     // check that the scale value is the same for all replicas
+     606          12 :     std::vector<double> dummy_scale(nrep_,0);
+     607          12 :     if(master&&nrep_>1) {
+     608           6 :       dummy_scale[replica_] = scale_;
+     609           6 :       multi_sim_comm.Sum(dummy_scale);
+     610             :     }
+     611          12 :     comm.Sum(dummy_scale);
+     612          24 :     for(unsigned i=1; i<nrep_; i++) {
+     613          12 :       std::string msg = "The SCALE value must be the same for all replicas: check your input or restart file";
+     614          12 :       if(dummy_scale[i]!=dummy_scale[0]) plumed_merror(msg);
+     615             :     }
+     616          12 :     log.printf("  sampling a common scaling factor with:\n");
+     617          12 :     log.printf("    initial scale parameter %f\n",scale_);
+     618          12 :     if(scale_prior_==SC_GAUSS) {
+     619           0 :       log.printf("    gaussian prior with mean %f and width %f\n",scale_mu_,Dscale_);
+     620             :     }
+     621          12 :     if(scale_prior_==SC_FLAT) {
+     622          12 :       log.printf("    flat prior between %f - %f\n",scale_min_,scale_max_);
+     623          12 :       log.printf("    maximum MC move of scale parameter %f\n",Dscale_);
+     624             :     }
+     625             :   }
+     626             : 
+     627          31 :   if(dooffset_) {
+     628             :     // check that the offset value is the same for all replicas
+     629           2 :     std::vector<double> dummy_offset(nrep_,0);
+     630           2 :     if(master&&nrep_>1) {
+     631           0 :       dummy_offset[replica_] = offset_;
+     632           0 :       multi_sim_comm.Sum(dummy_offset);
+     633             :     }
+     634           2 :     comm.Sum(dummy_offset);
+     635           2 :     for(unsigned i=1; i<nrep_; i++) {
+     636           0 :       std::string msg = "The OFFSET value must be the same for all replicas: check your input or restart file";
+     637           0 :       if(dummy_offset[i]!=dummy_offset[0]) plumed_merror(msg);
+     638             :     }
+     639           2 :     log.printf("  sampling a common offset with:\n");
+     640           2 :     log.printf("    initial offset parameter %f\n",offset_);
+     641           2 :     if(offset_prior_==SC_GAUSS) {
+     642           0 :       log.printf("    gaussian prior with mean %f and width %f\n",offset_mu_,Doffset_);
+     643             :     }
+     644           2 :     if(offset_prior_==SC_FLAT) {
+     645           2 :       log.printf("    flat prior between %f - %f\n",offset_min_,offset_max_);
+     646           2 :       log.printf("    maximum MC move of offset parameter %f\n",Doffset_);
+     647             :     }
+     648             :   }
+     649             : 
+     650          31 :   if(doregres_zero_)
+     651           0 :     log.printf("  doing regression with zero intercept with stride: %d\n", nregres_zero_);
+     652             : 
+     653          31 :   log.printf("  number of experimental data points %u\n",narg);
+     654          31 :   log.printf("  number of replicas %u\n",nrep_);
+     655          31 :   log.printf("  initial data uncertainties");
+     656        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f", sigma_[i]);
+     657          31 :   log.printf("\n");
+     658          31 :   log.printf("  minimum data uncertainties");
+     659        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_min_[i]);
+     660          31 :   log.printf("\n");
+     661          31 :   log.printf("  maximum data uncertainties");
+     662        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_max_[i]);
+     663          31 :   log.printf("\n");
+     664          31 :   log.printf("  maximum MC move of data uncertainties");
+     665        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",Dsigma_[i]);
+     666          31 :   log.printf("\n");
+     667          31 :   log.printf("  temperature of the system %f\n",kbt_);
+     668          31 :   log.printf("  MC steps %u\n",MCsteps_);
+     669          31 :   log.printf("  initial standard errors of the mean");
+     670        2509 :   for(unsigned i=0; i<sigma_mean2_.size(); ++i) log.printf(" %f", std::sqrt(sigma_mean2_[i]));
+     671          31 :   log.printf("\n");
+     672             : 
+     673             :   //resize the number of metainference derivatives and the number of back-calculated data
+     674          31 :   metader_.resize(narg, 0.);
+     675          31 :   calc_data_.resize(narg, 0.);
+     676             : 
+     677          62 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     678          75 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     679          39 :   if(do_optsigmamean_>0) log<<plumed.cite("Loehr, Jussupow, Camilloni, J. Chem. Phys. 146, 165102 (2017)");
+     680          62 :   log<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     681          31 :   log<<"\n";
+     682          31 : }
+     683             : 
+     684           0 : void MetainferenceBase::Selector()
+     685             : {
+     686           0 :   iselect = 0;
+     687             :   // set the value of selector for  REM-like stuff
+     688           0 :   if(selector_.length()>0) iselect = static_cast<unsigned>(plumed.passMap[selector_]);
+     689           0 : }
+     690             : 
+     691          12 : double MetainferenceBase::getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     692             :                                       const double scale, const double offset)
+     693             : {
+     694          12 :   const double scale2 = scale*scale;
+     695          12 :   const double sm2    = sigma_mean2_[0];
+     696          12 :   const double ss2    = sigma[0]*sigma[0] + scale2*sm2;
+     697          12 :   const double sss    = sigma[0]*sigma[0] + sm2;
+     698             : 
+     699             :   double ene = 0.0;
+     700          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     701             :   {
+     702             :     #pragma omp for reduction( + : ene)
+     703             :     for(unsigned i=0; i<narg; ++i) {
+     704             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     705             :       const double a2 = 0.5*dev*dev + ss2;
+     706             :       if(sm2 > 0.0) {
+     707             :         ene += std::log(2.0*a2/(1.0-std::exp(-a2/sm2)));
+     708             :       }
+     709             :       else {
+     710             :         ene += std::log(2.0*a2);
+     711             :       }
+     712             :     }
+     713             :   }
+     714             :   // add one single Jeffrey's prior and one normalisation per data point
+     715          12 :   ene += 0.5*std::log(sss) + static_cast<double>(narg)*0.5*std::log(0.5*M_PI*M_PI/ss2);
+     716          12 :   if(doscale_ || doregres_zero_) ene += 0.5*std::log(sss);
+     717          12 :   if(dooffset_) ene += 0.5*std::log(sss);
+     718          12 :   return kbt_ * ene;
+     719             : }
+     720             : 
+     721        5328 : double MetainferenceBase::getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     722             :                                        const double scale, const double offset)
+     723             : {
+     724        5328 :   const double scale2 = scale*scale;
+     725             :   double ene = 0.0;
+     726        5328 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     727             :   {
+     728             :     #pragma omp for reduction( + : ene)
+     729             :     for(unsigned i=0; i<narg; ++i) {
+     730             :       const double sm2 = sigma_mean2_[i];
+     731             :       const double ss2 = sigma[i]*sigma[i] + scale2*sm2;
+     732             :       const double sss = sigma[i]*sigma[i] + sm2;
+     733             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     734             :       const double a2  = 0.5*dev*dev + ss2;
+     735             :       if(sm2 > 0.0) {
+     736             :         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)));
+     737             :       }
+     738             :       else {
+     739             :         ene += 0.5*std::log(sss) + 0.5*std::log(0.5*M_PI*M_PI/ss2) + std::log(2.0*a2);
+     740             :       }
+     741             :       if(doscale_ || doregres_zero_)  ene += 0.5*std::log(sss);
+     742             :       if(dooffset_) ene += 0.5*std::log(sss);
+     743             :     }
+     744             :   }
+     745        5328 :   return kbt_ * ene;
+     746             : }
+     747             : 
+     748          48 : double MetainferenceBase::getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     749             :     const double scale, const double offset)
+     750             : {
+     751             :   double ene = 0.0;
+     752          48 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     753             :   {
+     754             :     #pragma omp for reduction( + : ene)
+     755             :     for(unsigned i=0; i<narg; ++i) {
+     756             :       const double inv_sb2  = 1./(sigma[i]*sigma[i]);
+     757             :       const double inv_sm2  = 1./sigma_mean2_[i];
+     758             :       double devb = 0;
+     759             :       if(gen_likelihood_==LIKE_GAUSS)     devb = scale*ftilde[i]-parameters[i]+offset;
+     760             :       else if(gen_likelihood_==LIKE_LOGN) devb = std::log(scale*ftilde[i]/parameters[i]);
+     761             :       double devm = mean[i] - ftilde[i];
+     762             :       // deviation + normalisation + jeffrey
+     763             :       double normb = 0.;
+     764             :       if(gen_likelihood_==LIKE_GAUSS)     normb = -0.5*std::log(0.5/M_PI*inv_sb2);
+     765             :       else if(gen_likelihood_==LIKE_LOGN) normb = -0.5*std::log(0.5/M_PI*inv_sb2/(parameters[i]*parameters[i]));
+     766             :       const double normm         = -0.5*std::log(0.5/M_PI*inv_sm2);
+     767             :       const double jeffreys      = -0.5*std::log(2.*inv_sb2);
+     768             :       ene += 0.5*devb*devb*inv_sb2 + 0.5*devm*devm*inv_sm2 + normb + normm + jeffreys;
+     769             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+     770             :       if(dooffset_) ene += jeffreys;
+     771             :     }
+     772             :   }
+     773          48 :   return kbt_ * ene;
+     774             : }
+     775             : 
+     776         554 : double MetainferenceBase::getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+     777             :                                       const double scale, const double offset)
+     778             : {
+     779         554 :   const double scale2  = scale*scale;
+     780         554 :   const double inv_s2  = 1./(sigma[0]*sigma[0] + scale2*sigma_mean2_[0]);
+     781         554 :   const double inv_sss = 1./(sigma[0]*sigma[0] + sigma_mean2_[0]);
+     782             : 
+     783             :   double ene = 0.0;
+     784         554 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     785             :   {
+     786             :     #pragma omp for reduction( + : ene)
+     787             :     for(unsigned i=0; i<narg; ++i) {
+     788             :       double dev = scale*mean[i]-parameters[i]+offset;
+     789             :       ene += 0.5*dev*dev*inv_s2;
+     790             :     }
+     791             :   }
+     792         554 :   const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+     793         554 :   const double jeffreys = -0.5*std::log(2.*inv_sss);
+     794             :   // add Jeffrey's prior in case one sigma for all data points + one normalisation per datapoint
+     795         554 :   ene += jeffreys + static_cast<double>(narg)*normalisation;
+     796         554 :   if(doscale_ || doregres_zero_)  ene += jeffreys;
+     797         554 :   if(dooffset_) ene += jeffreys;
+     798             : 
+     799         554 :   return kbt_ * ene;
+     800             : }
+     801             : 
+     802         368 : double MetainferenceBase::getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     803             :                                        const double scale, const double offset)
+     804             : {
+     805         368 :   const double scale2 = scale*scale;
+     806             : 
+     807             :   double ene = 0.0;
+     808         368 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     809             :   {
+     810             :     #pragma omp for reduction( + : ene)
+     811             :     for(unsigned i=0; i<narg; ++i) {
+     812             :       const double inv_s2  = 1./(sigma[i]*sigma[i] + scale2*sigma_mean2_[i]);
+     813             :       const double inv_sss = 1./(sigma[i]*sigma[i] + sigma_mean2_[i]);
+     814             :       double dev = scale*mean[i]-parameters[i]+offset;
+     815             :       // deviation + normalisation + jeffrey
+     816             :       const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+     817             :       const double jeffreys      = -0.5*std::log(2.*inv_sss);
+     818             :       ene += 0.5*dev*dev*inv_s2 + normalisation + jeffreys;
+     819             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+     820             :       if(dooffset_) ene += jeffreys;
+     821             :     }
+     822             :   }
+     823         368 :   return kbt_ * ene;
+     824             : }
+     825             : 
+     826          12 : void MetainferenceBase::moveTilde(const std::vector<double> &mean_, double &old_energy)
+     827             : {
+     828          12 :   std::vector<double> new_ftilde(sigma_.size());
+     829          12 :   new_ftilde = ftilde_;
+     830             : 
+     831             :   // change all tildes
+     832          36 :   for(unsigned j=0; j<sigma_.size(); j++) {
+     833          24 :     const double r3 = random[0].Gaussian();
+     834          24 :     const double ds3 = Dftilde_*std::sqrt(sigma_mean2_[j])*r3;
+     835          24 :     new_ftilde[j] = ftilde_[j] + ds3;
+     836             :   }
+     837             :   // calculate new energy
+     838          12 :   double new_energy = getEnergyMIGEN(mean_,new_ftilde,sigma_,scale_,offset_);
+     839             : 
+     840             :   // accept or reject
+     841          12 :   const double delta = ( new_energy - old_energy ) / kbt_;
+     842             :   // if delta is negative always accept move
+     843          12 :   if( delta <= 0.0 ) {
+     844          12 :     old_energy = new_energy;
+     845          12 :     ftilde_ = new_ftilde;
+     846          12 :     MCacceptFT_++;
+     847             :     // otherwise extract random number
+     848             :   } else {
+     849           0 :     const double s = random[0].RandU01();
+     850           0 :     if( s < std::exp(-delta) ) {
+     851           0 :       old_energy = new_energy;
+     852           0 :       ftilde_ = new_ftilde;
+     853           0 :       MCacceptFT_++;
+     854             :     }
+     855             :   }
+     856          12 : }
+     857             : 
+     858        1848 : void MetainferenceBase::moveScaleOffset(const std::vector<double> &mean_, double &old_energy)
+     859             : {
+     860        1848 :   double new_scale = scale_;
+     861             : 
+     862        1848 :   if(doscale_) {
+     863        1824 :     if(scale_prior_==SC_FLAT) {
+     864        1824 :       const double r1 = random[1].Gaussian();
+     865        1824 :       const double ds1 = Dscale_*r1;
+     866        1824 :       new_scale += ds1;
+     867             :       // check boundaries
+     868        1824 :       if(new_scale > scale_max_) {new_scale = 2.0 * scale_max_ - new_scale;}
+     869        1824 :       if(new_scale < scale_min_) {new_scale = 2.0 * scale_min_ - new_scale;}
+     870             :     } else {
+     871           0 :       const double r1 = random[1].Gaussian();
+     872           0 :       const double ds1 = 0.5*(scale_mu_-new_scale)+Dscale_*std::exp(1)/M_PI*r1;
+     873           0 :       new_scale += ds1;
+     874             :     }
+     875             :   }
+     876             : 
+     877        1848 :   double new_offset = offset_;
+     878             : 
+     879        1848 :   if(dooffset_) {
+     880          24 :     if(offset_prior_==SC_FLAT) {
+     881          24 :       const double r1 = random[1].Gaussian();
+     882          24 :       const double ds1 = Doffset_*r1;
+     883          24 :       new_offset += ds1;
+     884             :       // check boundaries
+     885          24 :       if(new_offset > offset_max_) {new_offset = 2.0 * offset_max_ - new_offset;}
+     886          24 :       if(new_offset < offset_min_) {new_offset = 2.0 * offset_min_ - new_offset;}
+     887             :     } else {
+     888           0 :       const double r1 = random[1].Gaussian();
+     889           0 :       const double ds1 = 0.5*(offset_mu_-new_offset)+Doffset_*std::exp(1)/M_PI*r1;
+     890           0 :       new_offset += ds1;
+     891             :     }
+     892             :   }
+     893             : 
+     894             :   // calculate new energy
+     895             :   double new_energy = 0.;
+     896             : 
+     897        1848 :   switch(noise_type_) {
+     898          12 :   case GAUSS:
+     899          12 :     new_energy = getEnergyGJ(mean_,sigma_,new_scale,new_offset);
+     900             :     break;
+     901          48 :   case MGAUSS:
+     902          48 :     new_energy = getEnergyGJE(mean_,sigma_,new_scale,new_offset);
+     903             :     break;
+     904           0 :   case OUTLIERS:
+     905           0 :     new_energy = getEnergySP(mean_,sigma_,new_scale,new_offset);
+     906             :     break;
+     907        1776 :   case MOUTLIERS:
+     908        1776 :     new_energy = getEnergySPE(mean_,sigma_,new_scale,new_offset);
+     909             :     break;
+     910          12 :   case GENERIC:
+     911          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,new_scale,new_offset);
+     912             :     break;
+     913             :   }
+     914             : 
+     915             :   // for the scale/offset we need to consider the total energy
+     916        1848 :   std::vector<double> totenergies(2);
+     917        1848 :   if(master) {
+     918         936 :     totenergies[0] = old_energy;
+     919         936 :     totenergies[1] = new_energy;
+     920         936 :     if(nrep_>1) multi_sim_comm.Sum(totenergies);
+     921             :   } else {
+     922         912 :     totenergies[0] = 0;
+     923         912 :     totenergies[1] = 0;
+     924             :   }
+     925        1848 :   comm.Sum(totenergies);
+     926             : 
+     927             :   // accept or reject
+     928        1848 :   const double delta = ( totenergies[1] - totenergies[0] ) / kbt_;
+     929             :   // if delta is negative always accept move
+     930        1848 :   if( delta <= 0.0 ) {
+     931        1848 :     old_energy = new_energy;
+     932        1848 :     scale_ = new_scale;
+     933        1848 :     offset_ = new_offset;
+     934        1848 :     MCacceptScale_++;
+     935             :     // otherwise extract random number
+     936             :   } else {
+     937           0 :     double s = random[1].RandU01();
+     938           0 :     if( s < std::exp(-delta) ) {
+     939           0 :       old_energy = new_energy;
+     940           0 :       scale_ = new_scale;
+     941           0 :       offset_ = new_offset;
+     942           0 :       MCacceptScale_++;
+     943             :     }
+     944             :   }
+     945        1848 : }
+     946             : 
+     947        2225 : void MetainferenceBase::moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow)
+     948             : {
+     949        2225 :   std::vector<double> new_sigma(sigma_.size());
+     950        2225 :   new_sigma = sigma_;
+     951             : 
+     952             :   // change MCchunksize_ sigmas
+     953        2225 :   if (MCchunksize_ > 0) {
+     954           0 :     if ((MCchunksize_ * i) >= sigma_.size()) {
+     955             :       // This means we are not moving any sigma, so we should break immediately
+     956           0 :       breaknow = true;
+     957             :     }
+     958             : 
+     959             :     // change random sigmas
+     960           0 :     for(unsigned j=0; j<MCchunksize_; j++) {
+     961           0 :       const unsigned shuffle_index = j + MCchunksize_ * i;
+     962           0 :       if (shuffle_index >= sigma_.size()) {
+     963             :         // Going any further will segfault but we should still evaluate the sigmas we changed
+     964             :         break;
+     965             :       }
+     966           0 :       const unsigned index = indices[shuffle_index];
+     967           0 :       const double r2 = random[0].Gaussian();
+     968           0 :       const double ds2 = Dsigma_[index]*r2;
+     969           0 :       new_sigma[index] = sigma_[index] + ds2;
+     970             :       // check boundaries
+     971           0 :       if(new_sigma[index] > sigma_max_[index]) {new_sigma[index] = 2.0 * sigma_max_[index] - new_sigma[index];}
+     972           0 :       if(new_sigma[index] < sigma_min_[index]) {new_sigma[index] = 2.0 * sigma_min_[index] - new_sigma[index];}
+     973             :     }
+     974             :   } else {
+     975             :     // change all sigmas
+     976       13486 :     for(unsigned j=0; j<sigma_.size(); j++) {
+     977       11261 :       const double r2 = random[0].Gaussian();
+     978       11261 :       const double ds2 = Dsigma_[j]*r2;
+     979       11261 :       new_sigma[j] = sigma_[j] + ds2;
+     980             :       // check boundaries
+     981       11261 :       if(new_sigma[j] > sigma_max_[j]) {new_sigma[j] = 2.0 * sigma_max_[j] - new_sigma[j];}
+     982       11261 :       if(new_sigma[j] < sigma_min_[j]) {new_sigma[j] = 2.0 * sigma_min_[j] - new_sigma[j];}
+     983             :     }
+     984             :   }
+     985             : 
+     986        2225 :   if (breaknow) {
+     987             :     // We didnt move any sigmas, so no sense in evaluating anything
+     988             :     return;
+     989             :   }
+     990             : 
+     991             :   // calculate new energy
+     992             :   double new_energy = 0.;
+     993        2225 :   switch(noise_type_) {
+     994         271 :   case GAUSS:
+     995         271 :     new_energy = getEnergyGJ(mean_,new_sigma,scale_,offset_);
+     996             :     break;
+     997         160 :   case MGAUSS:
+     998         160 :     new_energy = getEnergyGJE(mean_,new_sigma,scale_,offset_);
+     999             :     break;
+    1000           6 :   case OUTLIERS:
+    1001           6 :     new_energy = getEnergySP(mean_,new_sigma,scale_,offset_);
+    1002             :     break;
+    1003        1776 :   case MOUTLIERS:
+    1004        1776 :     new_energy = getEnergySPE(mean_,new_sigma,scale_,offset_);
+    1005             :     break;
+    1006          12 :   case GENERIC:
+    1007          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,new_sigma,scale_,offset_);
+    1008             :     break;
+    1009             :   }
+    1010             : 
+    1011             :   // accept or reject
+    1012        2225 :   const double delta = ( new_energy - old_energy ) / kbt_;
+    1013             :   // if delta is negative always accept move
+    1014        2225 :   if( delta <= 0.0 ) {
+    1015        2225 :     old_energy = new_energy;
+    1016        2225 :     sigma_ = new_sigma;
+    1017        2225 :     MCaccept_++;
+    1018             :     // otherwise extract random number
+    1019             :   } else {
+    1020           0 :     const double s = random[0].RandU01();
+    1021           0 :     if( s < std::exp(-delta) ) {
+    1022           0 :       old_energy = new_energy;
+    1023           0 :       sigma_ = new_sigma;
+    1024           0 :       MCaccept_++;
+    1025             :     }
+    1026             :   }
+    1027             : }
+    1028             : 
+    1029        2225 : double MetainferenceBase::doMonteCarlo(const std::vector<double> &mean_)
+    1030             : {
+    1031             :   // calculate old energy with the updated coordinates
+    1032        2225 :   double old_energy=0.;
+    1033             : 
+    1034        2225 :   switch(noise_type_) {
+    1035         271 :   case GAUSS:
+    1036         271 :     old_energy = getEnergyGJ(mean_,sigma_,scale_,offset_);
+    1037         271 :     break;
+    1038         160 :   case MGAUSS:
+    1039         160 :     old_energy = getEnergyGJE(mean_,sigma_,scale_,offset_);
+    1040         160 :     break;
+    1041           6 :   case OUTLIERS:
+    1042           6 :     old_energy = getEnergySP(mean_,sigma_,scale_,offset_);
+    1043           6 :     break;
+    1044        1776 :   case MOUTLIERS:
+    1045        1776 :     old_energy = getEnergySPE(mean_,sigma_,scale_,offset_);
+    1046        1776 :     break;
+    1047          12 :   case GENERIC:
+    1048          12 :     old_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,scale_,offset_);
+    1049          12 :     break;
+    1050             :   }
+    1051             : 
+    1052             :   // do not run MC if this is a replica-exchange trial
+    1053        2225 :   if(!getExchangeStep()) {
+    1054             : 
+    1055             :     // Create std::vector of random sigma indices
+    1056             :     std::vector<unsigned> indices;
+    1057        2225 :     if (MCchunksize_ > 0) {
+    1058           0 :       for (unsigned j=0; j<sigma_.size(); j++) {
+    1059           0 :         indices.push_back(j);
+    1060             :       }
+    1061           0 :       random[2].Shuffle(indices);
+    1062             :     }
+    1063        2225 :     bool breaknow = false;
+    1064             : 
+    1065             :     // cycle on MC steps
+    1066        4450 :     for(unsigned i=0; i<MCsteps_; ++i) {
+    1067        2225 :       MCtrial_++;
+    1068             :       // propose move for ftilde
+    1069        2225 :       if(noise_type_==GENERIC) moveTilde(mean_, old_energy);
+    1070             :       // propose move for scale and/or offset
+    1071        2225 :       if(doscale_||dooffset_) moveScaleOffset(mean_, old_energy);
+    1072             :       // propose move for sigma
+    1073        2225 :       moveSigmas(mean_, old_energy, i, indices, breaknow);
+    1074             :       // exit from the loop if this is the case
+    1075        2225 :       if(breaknow) break;
+    1076             :     }
+    1077             : 
+    1078             :     /* save the result of the sampling */
+    1079             :     /* ftilde */
+    1080        2225 :     if(noise_type_==GENERIC) {
+    1081          12 :       double accept = static_cast<double>(MCacceptFT_) / static_cast<double>(MCtrial_);
+    1082          12 :       valueAcceptFT->set(accept);
+    1083          36 :       for(unsigned i=0; i<sigma_.size(); i++) valueFtilde[i]->set(ftilde_[i]);
+    1084             :     }
+    1085             :     /* scale and offset */
+    1086        2225 :     if(doscale_ || doregres_zero_) valueScale->set(scale_);
+    1087        2225 :     if(dooffset_) valueOffset->set(offset_);
+    1088        2225 :     if(doscale_||dooffset_) {
+    1089        1848 :       double accept = static_cast<double>(MCacceptScale_) / static_cast<double>(MCtrial_);
+    1090        1848 :       valueAcceptScale->set(accept);
+    1091             :     }
+    1092             :     /* sigmas */
+    1093       13486 :     for(unsigned i=0; i<sigma_.size(); i++) valueSigma[i]->set(sigma_[i]);
+    1094        2225 :     double accept = static_cast<double>(MCaccept_) / static_cast<double>(MCtrial_);
+    1095        2225 :     valueAccept->set(accept);
+    1096             :   }
+    1097             : 
+    1098             :   // here we sum the score over the replicas to get the full metainference score that we save as a bias
+    1099        2225 :   if(master) {
+    1100        1227 :     if(nrep_>1) multi_sim_comm.Sum(old_energy);
+    1101             :   } else {
+    1102         998 :     old_energy=0;
+    1103             :   }
+    1104        2225 :   comm.Sum(old_energy);
+    1105             : 
+    1106             :   // this is the energy with current coordinates and parameters
+    1107        2225 :   return old_energy;
+    1108             : }
+    1109             : 
+    1110             : /*
+    1111             :    In the following energy-force functions we don't add the normalisation and the jeffreys priors
+    1112             :    because they are not needed for the forces, the correct MetaInference energy is the one calculated
+    1113             :    in the Monte-Carlo
+    1114             : */
+    1115             : 
+    1116           6 : void MetainferenceBase::getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1117             :     const std::vector<double> &dmean_b)
+    1118             : {
+    1119           6 :   const double scale2 = scale_*scale_;
+    1120           6 :   const double sm2    = sigma_mean2_[0];
+    1121           6 :   const double ss2    = sigma_[0]*sigma_[0] + scale2*sm2;
+    1122           6 :   std::vector<double> f(narg,0);
+    1123             : 
+    1124           6 :   if(master) {
+    1125           6 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1126             :     {
+    1127             :       #pragma omp for
+    1128             :       for(unsigned i=0; i<narg; ++i) {
+    1129             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1130             :         const double a2 = 0.5*dev*dev + ss2;
+    1131             :         if(sm2 > 0.0) {
+    1132             :           const double t = std::exp(-a2/sm2);
+    1133             :           const double dt = 1./t;
+    1134             :           const double dit = 1./(1.-dt);
+    1135             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1136             :         }
+    1137             :         else {
+    1138             :           f[i] = -scale_*dev*(1./a2);
+    1139             :         }
+    1140             :       }
+    1141             :     }
+    1142             :     // collect contribution to forces and energy from other replicas
+    1143           6 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1144             :   }
+    1145             :   // intra-replica summation
+    1146           6 :   comm.Sum(&f[0],narg);
+    1147             : 
+    1148             :   double w_tmp = 0.;
+    1149          48 :   for(unsigned i=0; i<narg; ++i) {
+    1150          42 :     setMetaDer(i, -kbt_*f[i]*dmean_x[i]);
+    1151          42 :     w_tmp += kbt_*f[i]*dmean_b[i];
+    1152             :   }
+    1153             : 
+    1154           6 :   if(do_reweight_) {
+    1155           0 :     setArgDerivatives(valueScore, -w_tmp);
+    1156           0 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1157             :   }
+    1158           6 : }
+    1159             : 
+    1160        1776 : void MetainferenceBase::getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1161             :     const std::vector<double> &dmean_b)
+    1162             : {
+    1163        1776 :   const double scale2 = scale_*scale_;
+    1164        1776 :   std::vector<double> f(narg,0);
+    1165             : 
+    1166        1776 :   if(master) {
+    1167         888 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1168             :     {
+    1169             :       #pragma omp for
+    1170             :       for(unsigned i=0; i<narg; ++i) {
+    1171             :         const double sm2 = sigma_mean2_[i];
+    1172             :         const double ss2 = sigma_[i]*sigma_[i] + scale2*sm2;
+    1173             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1174             :         const double a2  = 0.5*dev*dev + ss2;
+    1175             :         if(sm2 > 0.0) {
+    1176             :           const double t   = std::exp(-a2/sm2);
+    1177             :           const double dt  = 1./t;
+    1178             :           const double dit = 1./(1.-dt);
+    1179             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1180             :         }
+    1181             :         else {
+    1182             :           f[i] = -scale_*dev*(1./a2);
+    1183             :         }
+    1184             :       }
+    1185             :     }
+    1186             :     // collect contribution to forces and energy from other replicas
+    1187         888 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1188             :   }
+    1189        1776 :   comm.Sum(&f[0],narg);
+    1190             : 
+    1191             :   double w_tmp = 0.;
+    1192        8880 :   for(unsigned i=0; i<narg; ++i) {
+    1193        7104 :     setMetaDer(i, -kbt_ * dmean_x[i] * f[i]);
+    1194        7104 :     w_tmp += kbt_ * dmean_b[i] *f[i];
+    1195             :   }
+    1196             : 
+    1197        1776 :   if(do_reweight_) {
+    1198        1776 :     setArgDerivatives(valueScore, -w_tmp);
+    1199        3552 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1200             :   }
+    1201        1776 : }
+    1202             : 
+    1203         271 : void MetainferenceBase::getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1204             :     const std::vector<double> &dmean_b)
+    1205             : {
+    1206         271 :   const double scale2 = scale_*scale_;
+    1207         271 :   double inv_s2=0.;
+    1208             : 
+    1209         271 :   if(master) {
+    1210         229 :     inv_s2 = 1./(sigma_[0]*sigma_[0] + scale2*sigma_mean2_[0]);
+    1211         229 :     if(nrep_>1) multi_sim_comm.Sum(inv_s2);
+    1212             :   }
+    1213         271 :   comm.Sum(inv_s2);
+    1214             : 
+    1215         271 :   double w_tmp = 0.;
+    1216         271 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1217             :   {
+    1218             :     #pragma omp for reduction( + : w_tmp)
+    1219             :     for(unsigned i=0; i<narg; ++i) {
+    1220             :       const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1221             :       const double mult = dev*scale_*inv_s2;
+    1222             :       setMetaDer(i, kbt_*dmean_x[i]*mult);
+    1223             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1224             :     }
+    1225             :   }
+    1226             : 
+    1227         271 :   if(do_reweight_) {
+    1228          84 :     setArgDerivatives(valueScore, w_tmp);
+    1229         168 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1230             :   }
+    1231         271 : }
+    1232             : 
+    1233         160 : void MetainferenceBase::getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1234             :     const std::vector<double> &dmean_b)
+    1235             : {
+    1236         160 :   const double scale2 = scale_*scale_;
+    1237         160 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1238             : 
+    1239         160 :   if(master) {
+    1240        2044 :     for(unsigned i=0; i<sigma_.size(); ++i) inv_s2[i] = 1./(sigma_[i]*sigma_[i] + scale2*sigma_mean2_[i]);
+    1241          92 :     if(nrep_>1) multi_sim_comm.Sum(&inv_s2[0],sigma_.size());
+    1242             :   }
+    1243         160 :   comm.Sum(&inv_s2[0],sigma_.size());
+    1244             : 
+    1245         160 :   double w_tmp = 0.;
+    1246         160 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1247             :   {
+    1248             :     #pragma omp for reduction( + : w_tmp)
+    1249             :     for(unsigned i=0; i<narg; ++i) {
+    1250             :       const double dev  = scale_*mean[i]-parameters[i]+offset_;
+    1251             :       const double mult = dev*scale_*inv_s2[i];
+    1252             :       setMetaDer(i, kbt_*dmean_x[i]*mult);
+    1253             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1254             :     }
+    1255             :   }
+    1256             : 
+    1257         160 :   if(do_reweight_) {
+    1258          76 :     setArgDerivatives(valueScore, w_tmp);
+    1259         152 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1260             :   }
+    1261         160 : }
+    1262             : 
+    1263          12 : void MetainferenceBase::getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b)
+    1264             : {
+    1265          12 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1266          12 :   std::vector<double> dev(sigma_.size(),0.);
+    1267          12 :   std::vector<double> dev2(sigma_.size(),0.);
+    1268             : 
+    1269          36 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1270          24 :     inv_s2[i]   = 1./sigma_mean2_[i];
+    1271          24 :     if(master) {
+    1272          24 :       dev[i]  = (mean[i]-ftilde_[i]);
+    1273          24 :       dev2[i] = dev[i]*dev[i];
+    1274             :     }
+    1275             :   }
+    1276          12 :   if(master&&nrep_>1) {
+    1277           0 :     multi_sim_comm.Sum(&dev[0],dev.size());
+    1278           0 :     multi_sim_comm.Sum(&dev2[0],dev2.size());
+    1279             :   }
+    1280          12 :   comm.Sum(&dev[0],dev.size());
+    1281          12 :   comm.Sum(&dev2[0],dev2.size());
+    1282             : 
+    1283          12 :   double dene_b = 0.;
+    1284          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(dene_b)
+    1285             :   {
+    1286             :     #pragma omp for reduction( + : dene_b)
+    1287             :     for(unsigned i=0; i<narg; ++i) {
+    1288             :       const double dene_x  = kbt_*inv_s2[i]*dmean_x[i]*dev[i];
+    1289             :       dene_b += kbt_*inv_s2[i]*dmean_b[i]*dev[i];
+    1290             :       setMetaDer(i, dene_x);
+    1291             :     }
+    1292             :   }
+    1293             : 
+    1294          12 :   if(do_reweight_) {
+    1295           0 :     setArgDerivatives(valueScore, dene_b);
+    1296           0 :     getPntrToComponent("biasDer")->set(dene_b);
+    1297             :   }
+    1298          12 : }
+    1299             : 
+    1300        2225 : void MetainferenceBase::get_weights(double &weight, double &norm, double &neff)
+    1301             : {
+    1302        2225 :   const double dnrep = static_cast<double>(nrep_);
+    1303             :   // calculate the weights either from BIAS
+    1304        2225 :   if(do_reweight_) {
+    1305        1936 :     std::vector<double> bias(nrep_,0);
+    1306        1936 :     if(master) {
+    1307         980 :       bias[replica_] = getArgument(0);
+    1308         980 :       if(nrep_>1) multi_sim_comm.Sum(&bias[0], nrep_);
+    1309             :     }
+    1310        1936 :     comm.Sum(&bias[0], nrep_);
+    1311             : 
+    1312             :     // accumulate weights
+    1313        1936 :     if(!firstTimeW[iselect]) {
+    1314        5742 :       for(unsigned i=0; i<nrep_; ++i) {
+    1315        3828 :         const double delta=bias[i]-average_weights_[iselect][i];
+    1316        3828 :         average_weights_[iselect][i]+=decay_w_*delta;
+    1317             :       }
+    1318             :     } else {
+    1319             :       firstTimeW[iselect] = false;
+    1320          66 :       for(unsigned i=0; i<nrep_; ++i) average_weights_[iselect][i] = bias[i];
+    1321             :     }
+    1322             : 
+    1323             :     // set average back into bias and set norm to one
+    1324        1936 :     const double maxbias = *(std::max_element(average_weights_[iselect].begin(), average_weights_[iselect].end()));
+    1325        5808 :     for(unsigned i=0; i<nrep_; ++i) bias[i] = std::exp((average_weights_[iselect][i]-maxbias)/kbt_);
+    1326             :     // set local weight, norm and weight variance
+    1327        1936 :     weight = bias[replica_];
+    1328             :     double w2=0.;
+    1329        5808 :     for(unsigned i=0; i<nrep_; ++i) {
+    1330        3872 :       w2 += bias[i]*bias[i];
+    1331        3872 :       norm += bias[i];
+    1332             :     }
+    1333        1936 :     neff = norm*norm/w2;
+    1334        3872 :     getPntrToComponent("weight")->set(weight/norm);
+    1335             :   } else {
+    1336             :     // or arithmetic ones
+    1337         289 :     neff = dnrep;
+    1338         289 :     weight = 1.0;
+    1339         289 :     norm = dnrep;
+    1340             :   }
+    1341        2225 :   getPntrToComponent("neff")->set(neff);
+    1342        2225 : }
+    1343             : 
+    1344        2225 : void MetainferenceBase::get_sigma_mean(const double weight, const double norm, const double neff, const std::vector<double> &mean)
+    1345             : {
+    1346        2225 :   const double dnrep    = static_cast<double>(nrep_);
+    1347        2225 :   std::vector<double> sigma_mean2_tmp(sigma_mean2_.size());
+    1348             : 
+    1349        2225 :   if(do_optsigmamean_>0) {
+    1350             :     // remove first entry of the history std::vector
+    1351          84 :     if(sigma_mean2_last_[iselect][0].size()==optsigmamean_stride_&&optsigmamean_stride_>0)
+    1352           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].erase(sigma_mean2_last_[iselect][i].begin());
+    1353             :     /* this is the current estimate of sigma mean for each argument
+    1354             :        there is one of this per argument in any case  because it is
+    1355             :        the maximum among these to be used in case of GAUSS/OUTLIER */
+    1356          84 :     std::vector<double> sigma_mean2_now(narg,0);
+    1357          84 :     if(master) {
+    1358         672 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] = weight*(calc_data_[i]-mean[i])*(calc_data_[i]-mean[i]);
+    1359          42 :       if(nrep_>1) multi_sim_comm.Sum(&sigma_mean2_now[0], narg);
+    1360             :     }
+    1361          84 :     comm.Sum(&sigma_mean2_now[0], narg);
+    1362        1344 :     for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] *= 1.0/(neff-1.)/norm;
+    1363             : 
+    1364             :     // add sigma_mean2 to history
+    1365          84 :     if(optsigmamean_stride_>0) {
+    1366           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].push_back(sigma_mean2_now[i]);
+    1367             :     } else {
+    1368        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];
+    1369             :     }
+    1370             : 
+    1371          84 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1372        1344 :       for(unsigned i=0; i<narg; ++i) {
+    1373             :         /* set to the maximum in history std::vector */
+    1374        1260 :         sigma_mean2_tmp[i] = *max_element(sigma_mean2_last_[iselect][i].begin(), sigma_mean2_last_[iselect][i].end());
+    1375             :         /* the standard error of the mean */
+    1376        1260 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1377        1260 :         if(noise_type_==GENERIC) {
+    1378           0 :           sigma_min_[i] = std::sqrt(sigma_mean2_tmp[i]);
+    1379           0 :           if(sigma_[i] < sigma_min_[i]) sigma_[i] = sigma_min_[i];
+    1380             :         }
+    1381             :       }
+    1382           0 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1383             :       // find maximum for each data point
+    1384             :       std::vector <double> max_values;
+    1385           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()));
+    1386             :       // find maximum across data points
+    1387           0 :       const double max_now = *max_element(max_values.begin(), max_values.end());
+    1388             :       // set new value
+    1389           0 :       sigma_mean2_tmp[0] = max_now;
+    1390           0 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1391             :     }
+    1392             :     // endif sigma mean optimization
+    1393             :     // start sigma max optimization
+    1394          84 :     if(do_optsigmamean_>1&&!sigmamax_opt_done_) {
+    1395           0 :       for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1396           0 :         if(sigma_max_est_[i]<sigma_mean2_tmp[i]&&optimized_step_>optsigmamean_stride_) sigma_max_est_[i]=sigma_mean2_tmp[i];
+    1397             :         // ready to set once and for all the value of sigma_max
+    1398           0 :         if(optimized_step_==N_optimized_step_) {
+    1399           0 :           sigmamax_opt_done_=true;
+    1400           0 :           for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1401           0 :             sigma_max_[i]=std::sqrt(sigma_max_est_[i]*dnrep);
+    1402           0 :             Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+    1403           0 :             if(sigma_[i]>sigma_max_[i]) sigma_[i]=sigma_max_[i];
+    1404             :           }
+    1405             :         }
+    1406             :       }
+    1407           0 :       optimized_step_++;
+    1408             :     }
+    1409             :     // end sigma max optimization
+    1410             :   } else {
+    1411        2141 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1412       11588 :       for(unsigned i=0; i<narg; ++i) {
+    1413        9724 :         sigma_mean2_tmp[i] = sigma_mean2_last_[iselect][i][0];
+    1414        9724 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1415             :       }
+    1416         277 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1417         277 :       sigma_mean2_tmp[0] = sigma_mean2_last_[iselect][0][0];
+    1418         277 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1419             :     }
+    1420             :   }
+    1421             : 
+    1422        2225 :   sigma_mean2_ = sigma_mean2_tmp;
+    1423        2225 : }
+    1424             : 
+    1425        2225 : void MetainferenceBase::replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b)
+    1426             : {
+    1427        2225 :   if(master) {
+    1428        7472 :     for(unsigned i=0; i<narg; ++i) mean[i] = weight/norm*calc_data_[i];
+    1429        1227 :     if(nrep_>1) multi_sim_comm.Sum(&mean[0], narg);
+    1430             :   }
+    1431        2225 :   comm.Sum(&mean[0], narg);
+    1432             :   // set the derivative of the mean with respect to the bias
+    1433       14052 :   for(unsigned i=0; i<narg; ++i) dmean_b[i] = weight/norm/kbt_*(calc_data_[i]-mean[i])*decay_w_;
+    1434             : 
+    1435             :   // this is only for generic metainference
+    1436        2225 :   if(firstTime) {ftilde_ = mean; firstTime = false;}
+    1437        2225 : }
+    1438             : 
+    1439           0 : void MetainferenceBase::do_regression_zero(const std::vector<double> &mean)
+    1440             : {
+    1441             : // parameters[i] = scale_ * mean[i]: find scale_ with linear regression
+    1442             :   double num = 0.0;
+    1443             :   double den = 0.0;
+    1444           0 :   for(unsigned i=0; i<parameters.size(); ++i) {
+    1445           0 :     num += mean[i] * parameters[i];
+    1446           0 :     den += mean[i] * mean[i];
+    1447             :   }
+    1448           0 :   if(den>0) {
+    1449           0 :     scale_ = num / den;
+    1450             :   } else {
+    1451           0 :     scale_ = 1.0;
+    1452             :   }
+    1453           0 : }
+    1454             : 
+    1455        2225 : double MetainferenceBase::getScore()
+    1456             : {
+    1457             :   /* Metainference */
+    1458             :   /* 1) collect weights */
+    1459        2225 :   double weight = 0.;
+    1460        2225 :   double neff = 0.;
+    1461        2225 :   double norm = 0.;
+    1462        2225 :   get_weights(weight, norm, neff);
+    1463             : 
+    1464             :   /* 2) calculate average */
+    1465        2225 :   std::vector<double> mean(getNarg(),0);
+    1466             :   // this is the derivative of the mean with respect to the argument
+    1467        2225 :   std::vector<double> dmean_x(getNarg(),weight/norm);
+    1468             :   // this is the derivative of the mean with respect to the bias
+    1469        2225 :   std::vector<double> dmean_b(getNarg(),0);
+    1470             :   // calculate it
+    1471        2225 :   replica_averaging(weight, norm, mean, dmean_b);
+    1472             : 
+    1473             :   /* 3) calculates parameters */
+    1474        2225 :   get_sigma_mean(weight, norm, neff, mean);
+    1475             : 
+    1476             :   // in case of regression with zero intercept, calculate scale
+    1477        2225 :   if(doregres_zero_ && getStep()%nregres_zero_==0) do_regression_zero(mean);
+    1478             : 
+    1479             :   /* 4) run monte carlo */
+    1480        2225 :   double ene = doMonteCarlo(mean);
+    1481             : 
+    1482             :   // calculate bias and forces
+    1483        2225 :   switch(noise_type_) {
+    1484         271 :   case GAUSS:
+    1485         271 :     getEnergyForceGJ(mean, dmean_x, dmean_b);
+    1486             :     break;
+    1487         160 :   case MGAUSS:
+    1488         160 :     getEnergyForceGJE(mean, dmean_x, dmean_b);
+    1489             :     break;
+    1490           6 :   case OUTLIERS:
+    1491           6 :     getEnergyForceSP(mean, dmean_x, dmean_b);
+    1492             :     break;
+    1493        1776 :   case MOUTLIERS:
+    1494        1776 :     getEnergyForceSPE(mean, dmean_x, dmean_b);
+    1495             :     break;
+    1496          12 :   case GENERIC:
+    1497          12 :     getEnergyForceMIGEN(mean, dmean_x, dmean_b);
+    1498             :     break;
+    1499             :   }
+    1500             : 
+    1501        2225 :   return ene;
+    1502             : }
+    1503             : 
+    1504          82 : void MetainferenceBase::writeStatus()
+    1505             : {
+    1506          82 :   if(!doscore_) return;
+    1507          31 :   sfile_.rewind();
+    1508          31 :   sfile_.printField("time",getTimeStep()*getStep());
+    1509             :   //nsel
+    1510          62 :   for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+    1511             :     std::string msg_i,msg_j;
+    1512          31 :     Tools::convert(i,msg_i);
+    1513             :     std::vector <double> max_values;
+    1514             :     //narg
+    1515        2528 :     for(unsigned j=0; j<narg; ++j) {
+    1516        2497 :       Tools::convert(j,msg_j);
+    1517        2497 :       std::string msg = msg_i+"_"+msg_j;
+    1518        2497 :       if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1519        4940 :         sfile_.printField("sigmaMean_"+msg,std::sqrt(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end())));
+    1520             :       } else {
+    1521             :         // find maximum for each data point
+    1522          27 :         max_values.push_back(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end()));
+    1523             :       }
+    1524             :     }
+    1525          31 :     if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1526             :       // find maximum across data points
+    1527           8 :       const double max_now = std::sqrt(*max_element(max_values.begin(), max_values.end()));
+    1528           8 :       Tools::convert(0,msg_j);
+    1529           8 :       std::string msg = msg_i+"_"+msg_j;
+    1530          16 :       sfile_.printField("sigmaMean_"+msg, max_now);
+    1531             :     }
+    1532             :   }
+    1533        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1534             :     std::string msg;
+    1535        2478 :     Tools::convert(i,msg);
+    1536        4956 :     sfile_.printField("sigma_"+msg,sigma_[i]);
+    1537             :   }
+    1538        2509 :   for(unsigned i=0; i<sigma_max_.size(); ++i) {
+    1539             :     std::string msg;
+    1540        2478 :     Tools::convert(i,msg);
+    1541        4956 :     sfile_.printField("sigma_max_"+msg,sigma_max_[i]);
+    1542             :   }
+    1543          31 :   if(noise_type_==GENERIC) {
+    1544           3 :     for(unsigned i=0; i<ftilde_.size(); ++i) {
+    1545             :       std::string msg;
+    1546           2 :       Tools::convert(i,msg);
+    1547           4 :       sfile_.printField("ftilde_"+msg,ftilde_[i]);
+    1548             :     }
+    1549             :   }
+    1550          31 :   sfile_.printField("scale0_",scale_);
+    1551          31 :   sfile_.printField("offset0_",offset_);
+    1552          62 :   for(unsigned i=0; i<average_weights_.size(); i++) {
+    1553             :     std::string msg_i;
+    1554          31 :     Tools::convert(i,msg_i);
+    1555          62 :     sfile_.printField("weight_"+msg_i,average_weights_[i][replica_]);
+    1556             :   }
+    1557          31 :   sfile_.printField();
+    1558          31 :   sfile_.flush();
+    1559             : }
+    1560             : 
+    1561             : }
+    1562             : }
+    1563             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..f08b980312 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:707297.2 %
Date:2024-06-10 08:19:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv82
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv687
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv687
_ZN4PLMD4isdb17MetainferenceBase5applyEv687
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE11722
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE1927088
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv3480111
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv4099241008
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.func.html b/coverage/isdb/MetainferenceBase.h.func.html new file mode 100644 index 0000000000..85147bacc7 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:707297.2 %
Date:2024-06-10 08:19:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv687
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv82
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv687
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE11722
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv3480111
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE1927088
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv4099241008
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase5applyEv687
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.gcov.html b/coverage/isdb/MetainferenceBase.h.gcov.html new file mode 100644 index 0000000000..730e70b9f3 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.gcov.html @@ -0,0 +1,462 @@ + + + + + + + + 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:707297.2 %
Date:2024-06-10 08:19:14Functions:1010100.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 "core/PlumedMain.h"
+      29             : #include "tools/Random.h"
+      30             : #include "tools/OpenMP.h"
+      31             : 
+      32             : #define PLUMED_METAINF_INIT(ao) Action(ao),MetainferenceBase(ao)
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace isdb {
+      36             : 
+      37             : /**
+      38             : \ingroup INHERIT
+      39             : This is the abstract base class to use for implementing new ISDB Metainference actions, within it there is
+      40             : information as to how to go about implementing a new Metainference action.
+      41             : */
+      42             : 
+      43             : class MetainferenceBase :
+      44             :   public ActionAtomistic,
+      45             :   public ActionWithArguments,
+      46             :   public ActionWithValue
+      47             : {
+      48             : private:
+      49             :   std::vector<double> forces;
+      50             :   std::vector<double> forcesToApply;
+      51             : 
+      52             :   // activate metainference
+      53             :   bool doscore_;
+      54             :   unsigned write_stride_;
+      55             :   // number of experimental data
+      56             :   unsigned narg;
+      57             :   // experimental data
+      58             :   std::vector<double> parameters;
+      59             :   // metainference derivatives
+      60             :   std::vector<double> metader_;
+      61             :   // vector of back-calculated experimental data
+      62             :   std::vector<double> calc_data_;
+      63             : 
+      64             :   // noise type
+      65             :   unsigned noise_type_;
+      66             :   enum { GAUSS, MGAUSS, OUTLIERS, MOUTLIERS, GENERIC };
+      67             :   unsigned gen_likelihood_;
+      68             :   enum { LIKE_GAUSS, LIKE_LOGN };
+      69             :   bool   doscale_;
+      70             :   unsigned scale_prior_;
+      71             :   enum { SC_GAUSS, SC_FLAT };
+      72             :   double scale_;
+      73             :   double scale_mu_;
+      74             :   double scale_min_;
+      75             :   double scale_max_;
+      76             :   double Dscale_;
+      77             :   // scale is data scaling factor
+      78             :   // noise type
+      79             :   unsigned offset_prior_;
+      80             :   bool   dooffset_;
+      81             :   double offset_;
+      82             :   double offset_mu_;
+      83             :   double offset_min_;
+      84             :   double offset_max_;
+      85             :   double Doffset_;
+      86             :   // scale and offset regression
+      87             :   bool doregres_zero_;
+      88             :   int  nregres_zero_;
+      89             :   // sigma is data uncertainty
+      90             :   std::vector<double> sigma_;
+      91             :   std::vector<double> sigma_min_;
+      92             :   std::vector<double> sigma_max_;
+      93             :   std::vector<double> Dsigma_;
+      94             :   // sigma_mean is uncertainty in the mean estimate
+      95             :   std::vector<double> sigma_mean2_;
+      96             :   // this is the estimator of the mean value per replica for generic metainference
+      97             :   std::vector<double> ftilde_;
+      98             :   double Dftilde_;
+      99             : 
+     100             :   // temperature in kbt
+     101             :   double   kbt_;
+     102             : 
+     103             :   // Monte Carlo stuff
+     104             :   std::vector<Random> random;
+     105             :   unsigned MCsteps_;
+     106             :   long unsigned MCaccept_;
+     107             :   long unsigned MCacceptScale_;
+     108             :   long unsigned MCacceptFT_;
+     109             :   long unsigned MCtrial_;
+     110             :   unsigned MCchunksize_;
+     111             : 
+     112             :   // output
+     113             :   Value*   valueScore;
+     114             :   Value*   valueScale;
+     115             :   Value*   valueOffset;
+     116             :   Value*   valueAccept;
+     117             :   Value*   valueAcceptScale;
+     118             :   Value*   valueAcceptFT;
+     119             :   std::vector<Value*> valueSigma;
+     120             :   std::vector<Value*> valueSigmaMean;
+     121             :   std::vector<Value*> valueFtilde;
+     122             : 
+     123             :   // restart
+     124             :   std::string status_file_name_;
+     125             :   OFile    sfile_;
+     126             : 
+     127             :   // others
+     128             :   bool     firstTime;
+     129             :   std::vector<bool> firstTimeW;
+     130             :   bool     master;
+     131             :   bool     do_reweight_;
+     132             :   unsigned do_optsigmamean_;
+     133             :   unsigned nrep_;
+     134             :   unsigned replica_;
+     135             : 
+     136             :   // selector
+     137             :   unsigned nsel_;
+     138             :   std::string selector_;
+     139             :   unsigned iselect;
+     140             : 
+     141             :   // optimize sigma mean
+     142             :   std::vector< std::vector < std::vector <double> > > sigma_mean2_last_;
+     143             :   unsigned optsigmamean_stride_;
+     144             :   // optimize sigma max
+     145             :   unsigned N_optimized_step_;
+     146             :   unsigned optimized_step_;
+     147             :   bool sigmamax_opt_done_;
+     148             :   std::vector<double> sigma_max_est_;
+     149             : 
+     150             :   // average weights
+     151             :   double decay_w_;
+     152             :   std::vector< std::vector <double> >  average_weights_;
+     153             : 
+     154             :   double getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     155             :                         const double scale, const double offset);
+     156             :   double getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     157             :                      const double scale, const double offset);
+     158             :   double getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     159             :                       const double scale, const double offset);
+     160             :   double getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+     161             :                      const double scale, const double offset);
+     162             :   double getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     163             :                       const double scale, const double offset);
+     164             :   void setMetaDer(const unsigned index, const double der);
+     165             :   void getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     166             :   void getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     167             :   void getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     168             :   void getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     169             :   void getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     170             :   double getCalcData(const unsigned index);
+     171             :   void get_weights(double &weight, double &norm, double &neff);
+     172             :   void replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b);
+     173             :   void get_sigma_mean(const double weight, const double norm, const double neff, const std::vector<double> &mean);
+     174             :   void do_regression_zero(const std::vector<double> &mean);
+     175             :   void moveTilde(const std::vector<double> &mean_, double &old_energy);
+     176             :   void moveScaleOffset(const std::vector<double> &mean_, double &old_energy);
+     177             :   void moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow);
+     178             :   double doMonteCarlo(const std::vector<double> &mean);
+     179             : 
+     180             : public:
+     181             :   static void registerKeywords( Keywords& keys );
+     182             :   explicit MetainferenceBase(const ActionOptions&);
+     183             :   ~MetainferenceBase();
+     184             :   void Initialise(const unsigned input);
+     185             :   void Selector();
+     186             :   unsigned getNarg();
+     187             :   void setNarg(const unsigned input);
+     188             :   void setParameters(const std::vector<double>& input);
+     189             :   void setParameter(const double input);
+     190             :   void setCalcData(const unsigned index, const double datum);
+     191             :   void setCalcData(const std::vector<double>& data);
+     192             :   bool getDoScore();
+     193             :   unsigned getWstride();
+     194             :   double getScore();
+     195             :   void setScore(const double score);
+     196             :   void setDerivatives();
+     197             :   double getMetaDer(const unsigned index);
+     198             :   void writeStatus();
+     199             :   void turnOnDerivatives() override;
+     200             :   unsigned getNumberOfDerivatives() override;
+     201             :   void lockRequests() override;
+     202             :   void unlockRequests() override;
+     203             :   void calculateNumericalDerivatives( ActionWithValue* a ) override;
+     204             :   void apply() override;
+     205             :   void setArgDerivatives(Value *v, const double &d);
+     206             :   void setAtomsDerivatives(Value*v, const unsigned i, const Vector&d);
+     207             :   void setBoxDerivatives(Value*v, const Tensor&d);
+     208             : };
+     209             : 
+     210             : inline
+     211             : void MetainferenceBase::setNarg(const unsigned input)
+     212             : {
+     213          31 :   narg = input;
+     214             : }
+     215             : 
+     216             : inline
+     217             : bool MetainferenceBase::getDoScore()
+     218             : {
+     219       21926 :   return doscore_;
+     220             : }
+     221             : 
+     222             : inline
+     223             : unsigned MetainferenceBase::getWstride()
+     224             : {
+     225        1374 :   return write_stride_;
+     226             : }
+     227             : 
+     228             : inline
+     229             : unsigned MetainferenceBase::getNarg()
+     230             : {
+     231        2225 :   return narg;
+     232             : }
+     233             : 
+     234             : inline
+     235             : void MetainferenceBase::setMetaDer(const unsigned index, const double der)
+     236             : {
+     237        7146 :   metader_[index] = der;
+     238             : }
+     239             : 
+     240             : inline
+     241             : double MetainferenceBase::getMetaDer(const unsigned index)
+     242             : {
+     243      909788 :   return metader_[index];
+     244             : }
+     245             : 
+     246             : inline
+     247             : double MetainferenceBase::getCalcData(const unsigned index)
+     248             : {
+     249             :   return calc_data_[index];
+     250             : }
+     251             : 
+     252             : inline
+     253             : void MetainferenceBase::setCalcData(const unsigned index, const double datum)
+     254             : {
+     255        3868 :   calc_data_[index] = datum;
+     256        3868 : }
+     257             : 
+     258             : inline
+     259             : void MetainferenceBase::setCalcData(const std::vector<double>& data)
+     260             : {
+     261             :   for(unsigned i=0; i<data.size(); i++) calc_data_[i] = data[i];
+     262             : }
+     263             : 
+     264             : inline
+     265          27 : void MetainferenceBase::setParameters(const std::vector<double>& input) {
+     266         168 :   for(unsigned i=0; i<input.size(); i++) parameters.push_back(input[i]);
+     267          27 : }
+     268             : 
+     269             : inline
+     270             : void MetainferenceBase::setParameter(const double input) {
+     271        2356 :   parameters.push_back(input);
+     272        2356 : }
+     273             : 
+     274             : inline
+     275             : void MetainferenceBase::setScore(const double score) {
+     276        2225 :   valueScore->set(score);
+     277        2225 : }
+     278             : 
+     279             : inline
+     280          82 : void MetainferenceBase::setDerivatives() {
+     281             :   // Get appropriate number of derivatives
+     282             :   // Derivatives are first for arguments and then for atoms
+     283             :   unsigned nder;
+     284          82 :   if( getNumberOfAtoms()>0 ) {
+     285          82 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     286             :   } else {
+     287           0 :     nder = getNumberOfArguments();
+     288             :   }
+     289             : 
+     290             :   // Resize all derivative arrays
+     291          82 :   forces.resize( nder ); forcesToApply.resize( nder );
+     292       21076 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(nder);
+     293          82 : }
+     294             : 
+     295             : inline
+     296     3480111 : void MetainferenceBase::turnOnDerivatives() {
+     297     3480111 :   ActionWithValue::turnOnDerivatives();
+     298     3480111 : }
+     299             : 
+     300             : inline
+     301  4099241008 : unsigned MetainferenceBase::getNumberOfDerivatives() {
+     302  4099241008 :   if( getNumberOfAtoms()>0 ) {
+     303  4099241008 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     304             :   }
+     305           0 :   return getNumberOfArguments();
+     306             : }
+     307             : 
+     308             : inline
+     309         687 : void MetainferenceBase::lockRequests() {
+     310             :   ActionAtomistic::lockRequests();
+     311             :   ActionWithArguments::lockRequests();
+     312         687 : }
+     313             : 
+     314             : inline
+     315         687 : void MetainferenceBase::unlockRequests() {
+     316             :   ActionAtomistic::unlockRequests();
+     317             :   ActionWithArguments::unlockRequests();
+     318         687 : }
+     319             : 
+     320             : inline
+     321          75 : void MetainferenceBase::calculateNumericalDerivatives( ActionWithValue* a=NULL ) {
+     322          75 :   if( getNumberOfArguments()>0 ) {
+     323          48 :     ActionWithArguments::calculateNumericalDerivatives( a );
+     324             :   }
+     325          75 :   if( getNumberOfAtoms()>0 ) {
+     326          75 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
+     327        1293 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     328        2322 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) if(getPntrToComponent(j)->hasDerivatives()) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
+     329             :     }
+     330          75 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
+     331        1293 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     332        2322 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) if(getPntrToComponent(j)->hasDerivatives()) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
+     333             :     }
+     334             :   }
+     335          75 : }
+     336             : 
+     337             : inline
+     338         687 : void MetainferenceBase::apply() {
+     339         687 :   bool wasforced=false; forcesToApply.assign(forcesToApply.size(),0.0);
+     340       32598 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     341       31911 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
+     342             :       wasforced=true;
+     343    41664408 :       for(unsigned i=0; i<forces.size(); ++i) forcesToApply[i]+=forces[i];
+     344             :     }
+     345             :   }
+     346         687 :   if( wasforced ) {
+     347         350 :     addForcesOnArguments( forcesToApply );
+     348         350 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, getNumberOfArguments() );
+     349             :   }
+     350         687 : }
+     351             : 
+     352             : inline
+     353             : void MetainferenceBase::setArgDerivatives(Value *v, const double &d) {
+     354         160 :   v->addDerivative(0,d);
+     355             : }
+     356             : 
+     357             : inline
+     358     1927088 : void MetainferenceBase::setAtomsDerivatives(Value*v, const unsigned i, const Vector&d) {
+     359     1927088 :   const unsigned noa=getNumberOfArguments();
+     360     1927088 :   v->addDerivative(noa+3*i+0,d[0]);
+     361     1927088 :   v->addDerivative(noa+3*i+1,d[1]);
+     362     1927088 :   v->addDerivative(noa+3*i+2,d[2]);
+     363     1927088 : }
+     364             : 
+     365             : inline
+     366       11722 : void MetainferenceBase::setBoxDerivatives(Value* v,const Tensor&d) {
+     367       11722 :   const unsigned noa=getNumberOfArguments();
+     368             :   const unsigned nat=getNumberOfAtoms();
+     369       11722 :   v->addDerivative(noa+3*nat+0,d(0,0));
+     370       11722 :   v->addDerivative(noa+3*nat+1,d(0,1));
+     371       11722 :   v->addDerivative(noa+3*nat+2,d(0,2));
+     372       11722 :   v->addDerivative(noa+3*nat+3,d(1,0));
+     373       11722 :   v->addDerivative(noa+3*nat+4,d(1,1));
+     374       11722 :   v->addDerivative(noa+3*nat+5,d(1,2));
+     375       11722 :   v->addDerivative(noa+3*nat+6,d(2,0));
+     376       11722 :   v->addDerivative(noa+3*nat+7,d(2,1));
+     377       11722 :   v->addDerivative(noa+3*nat+8,d(2,2));
+     378       11722 : }
+     379             : 
+     380             : 
+     381             : }
+     382             : }
+     383             : 
+     384             : #endif
+     385             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..20f406468c --- /dev/null +++ b/coverage/isdb/NOE.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3NOEC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe826createERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOEC1ERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOE16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4isdb3NOE6updateEv132
_ZN4PLMD4isdb3NOE9calculateEv456
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe82C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe82D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/NOE.cpp.func.html b/coverage/isdb/NOE.cpp.func.html new file mode 100644 index 0000000000..0638af115d --- /dev/null +++ b/coverage/isdb/NOE.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe826createERKNS_13ActionOptionsE11
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe82C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe82D2Ev3473
_ZN4PLMD4isdb3NOE16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4isdb3NOE6updateEv132
_ZN4PLMD4isdb3NOE9calculateEv456
_ZN4PLMD4isdb3NOEC1ERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOEC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/NOE.cpp.gcov.html b/coverage/isdb/NOE.cpp.gcov.html new file mode 100644 index 0000000000..2dc09254ec --- /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-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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       10441 : PLUMED_REGISTER_ACTION(NOE,"NOE")
+      83             : 
+      84          12 : void NOE::registerKeywords( Keywords& keys ) {
+      85          12 :   componentsAreNotOptional(keys);
+      86          12 :   MetainferenceBase::registerKeywords(keys);
+      87          24 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      88          24 :   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          24 :   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          24 :   keys.reset_style("GROUPA","atoms");
+      95          24 :   keys.reset_style("GROUPB","atoms");
+      96          24 :   keys.add("numbered","NOEDIST","Add an experimental value for each NOE.");
+      97          24 :   keys.addOutputComponent("noe","default","the # NOE");
+      98          24 :   keys.addOutputComponent("exp","NOEDIST","the # NOE experimental distance");
+      99          12 : }
+     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          33 :   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          14 :       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          10 :         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           8 :       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           8 :       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             :     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.15
+
+ + + 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 0000000000..739ebf7be7 --- /dev/null +++ b/coverage/isdb/PRE.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3PREC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe896createERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PREC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PRE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4isdb3PRE6updateEv20
_ZN4PLMD4isdb3PRE9calculateEv350
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe89C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe89D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/PRE.cpp.func.html b/coverage/isdb/PRE.cpp.func.html new file mode 100644 index 0000000000..242fd8021a --- /dev/null +++ b/coverage/isdb/PRE.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe896createERKNS_13ActionOptionsE4
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe89C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe89D2Ev3473
_ZN4PLMD4isdb3PRE16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4isdb3PRE6updateEv20
_ZN4PLMD4isdb3PRE9calculateEv350
_ZN4PLMD4isdb3PREC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PREC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/PRE.cpp.gcov.html b/coverage/isdb/PRE.cpp.gcov.html new file mode 100644 index 0000000000..af13193c51 --- /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-06-10 08:19:14Functions: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 "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       10427 : PLUMED_REGISTER_ACTION(PRE,"PRE")
+      90             : 
+      91           5 : void PRE::registerKeywords( Keywords& keys ) {
+      92           5 :   componentsAreNotOptional(keys);
+      93           5 :   MetainferenceBase::registerKeywords(keys);
+      94          10 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      95          10 :   keys.addFlag("NORATIO",false,"Set to TRUE if you want to compute PRE without Intensity Ratio");
+      96          10 :   keys.add("compulsory","INEPT","is the INEPT time (in ms).");
+      97          10 :   keys.add("compulsory","TAUC","is the correlation time (in ns) for this electron-nuclear interaction.");
+      98          10 :   keys.add("compulsory","OMEGA","is the Larmor frequency of the nuclear spin (in MHz).");
+      99          10 :   keys.add("atoms","SPINLABEL","The atom to be used as the paramagnetic center.");
+     100          10 :   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          10 :   keys.reset_style("GROUPA","atoms");
+     104          10 :   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          10 :   keys.add("numbered","PREINT","Add an experimental value for each PRE.");
+     107          10 :   keys.addOutputComponent("pre","default","the # PRE");
+     108          10 :   keys.addOutputComponent("exp","PREINT","the # PRE experimental intensity");
+     109           5 : }
+     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          12 :   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           6 :       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           6 :       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           6 :       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             :     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.15
+
+ + + 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 0000000000..881bbd69a0 --- /dev/null +++ b/coverage/isdb/RDC.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:17118294.0 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe2216createERKNS_13ActionOptionsE0
_ZN4PLMD4isdb3RDCC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb3RDC6do_svdEv5
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe2206createERKNS_13ActionOptionsE29
_ZN4PLMD4isdb3RDCC1ERKNS_13ActionOptionsE29
_ZN4PLMD4isdb3RDC16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD4isdb3RDC6updateEv327
_ZN4PLMD4isdb3RDC9calculateEv2172
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe220C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe220D2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe221C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe221D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/RDC.cpp.func.html b/coverage/isdb/RDC.cpp.func.html new file mode 100644 index 0000000000..03a5ff1829 --- /dev/null +++ b/coverage/isdb/RDC.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:17118294.0 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe2206createERKNS_13ActionOptionsE29
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe220C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe220D2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe2216createERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe221C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe221D2Ev3473
_ZN4PLMD4isdb3RDC16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD4isdb3RDC6do_svdEv5
_ZN4PLMD4isdb3RDC6updateEv327
_ZN4PLMD4isdb3RDC9calculateEv2172
_ZN4PLMD4isdb3RDCC1ERKNS_13ActionOptionsE29
_ZN4PLMD4isdb3RDCC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/RDC.cpp.gcov.html b/coverage/isdb/RDC.cpp.gcov.html new file mode 100644 index 0000000000..ef4a1b738c --- /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:17118294.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10477 : PLUMED_REGISTER_ACTION(RDC,"RDC")
+     221       10419 : PLUMED_REGISTER_ACTION(RDC,"PCS")
+     222             : 
+     223          31 : void RDC::registerKeywords( Keywords& keys ) {
+     224          31 :   componentsAreNotOptional(keys);
+     225          31 :   MetainferenceBase::registerKeywords(keys);
+     226          62 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     227          62 :   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          62 :   keys.reset_style("ATOMS","atoms");
+     231          62 :   keys.add("compulsory","GYROM","1.","Add the product of the gyromagnetic constants for the bond. ");
+     232          62 :   keys.add("compulsory","SCALE","1.","Add the scaling factor to take into account concentration and other effects. ");
+     233          62 :   keys.addFlag("SVD",false,"Set to TRUE if you want to back calculate using Single Value Decomposition (need GSL at compilation time).");
+     234          62 :   keys.add("numbered","COUPLING","Add an experimental value for each coupling (needed by SVD and useful for \\ref STATS).");
+     235          62 :   keys.addOutputComponent("rdc","default","the calculated # RDC");
+     236          62 :   keys.addOutputComponent("exp","SVD/COUPLING","the experimental # RDC");
+     237          62 :   keys.addOutputComponent("Sxx","SVD","Tensor component");
+     238          62 :   keys.addOutputComponent("Syy","SVD","Tensor component");
+     239          62 :   keys.addOutputComponent("Szz","SVD","Tensor component");
+     240          62 :   keys.addOutputComponent("Sxy","SVD","Tensor component");
+     241          62 :   keys.addOutputComponent("Sxz","SVD","Tensor component");
+     242          62 :   keys.addOutputComponent("Syz","SVD","Tensor component");
+     243          31 : }
+     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         116 :      <<plumed.cite("Camilloni C, Vendruscolo M, Biochemistry 54, 7470 (2015)");
+     318          87 :   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          64 :       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          53 :       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          53 :       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           2 :     addComponent("Sxx"); componentIsNotPeriodic("Sxx");
+     353           2 :     addComponent("Syy"); componentIsNotPeriodic("Syy");
+     354           2 :     addComponent("Szz"); componentIsNotPeriodic("Szz");
+     355           2 :     addComponent("Sxy"); componentIsNotPeriodic("Sxy");
+     356           2 :     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             :     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.15
+
+ + + 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 0000000000..c712d1e0dc --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + 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:2219011.6 %
Date:2024-06-10 08:19:14Functions:31520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe1626createERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7Rescale10print_biasEl0
_ZN4PLMD4isdb7Rescale11proposeMoveEjjj0
_ZN4PLMD4isdb7Rescale12doMonteCarloEjdSt6vectorIdSaIdEES4_0
_ZN4PLMD4isdb7Rescale8doAcceptEdd0
_ZN4PLMD4isdb7Rescale9calculateEv0
_ZN4PLMD4isdb7Rescale9read_biasEv0
_ZN4PLMD4isdb7RescaleC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleD0Ev0
_ZN4PLMD4isdb7RescaleD1Ev0
_ZN4PLMD4isdb7RescaleD2Ev0
_ZN4PLMD4isdb7Rescale16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe162C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe162D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.func.html b/coverage/isdb/Rescale.cpp.func.html new file mode 100644 index 0000000000..5267b33aac --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + 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:2219011.6 %
Date:2024-06-10 08:19:14Functions:31520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe1626createERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe162C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe162D2Ev3473
_ZN4PLMD4isdb7Rescale10print_biasEl0
_ZN4PLMD4isdb7Rescale11proposeMoveEjjj0
_ZN4PLMD4isdb7Rescale12doMonteCarloEjdSt6vectorIdSaIdEES4_0
_ZN4PLMD4isdb7Rescale16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD4isdb7Rescale8doAcceptEdd0
_ZN4PLMD4isdb7Rescale9calculateEv0
_ZN4PLMD4isdb7Rescale9read_biasEv0
_ZN4PLMD4isdb7RescaleC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleD0Ev0
_ZN4PLMD4isdb7RescaleD1Ev0
_ZN4PLMD4isdb7RescaleD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.gcov.html b/coverage/isdb/Rescale.cpp.gcov.html new file mode 100644 index 0000000000..dc1812ecc4 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.gcov.html @@ -0,0 +1,593 @@ + + + + + + + + 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:2219011.6 %
Date:2024-06-10 08:19:14Functions:31520.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 "bias/Bias.h"
+      26             : #include "bias/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/Atoms.h"
+      29             : #include "core/Value.h"
+      30             : #include "tools/File.h"
+      31             : #include "tools/Random.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 int MCfirst_;
+     139             :   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, std::vector<double> args, 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 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       10419 : PLUMED_REGISTER_ACTION(Rescale,"RESCALE")
+     163             : 
+     164           1 : void Rescale::registerKeywords(Keywords& keys) {
+     165           1 :   Bias::registerKeywords(keys);
+     166           1 :   keys.use("ARG");
+     167           2 :   keys.add("compulsory","TEMP","temperature");
+     168           2 :   keys.add("compulsory","SELECTOR", "name of the SELECTOR used for rescaling");
+     169           2 :   keys.add("compulsory","MAX_RESCALE","maximum values for rescaling");
+     170           2 :   keys.add("compulsory","NBIN","number of bins for gamma grid");
+     171           2 :   keys.add("compulsory","W0", "initial bias height");
+     172           2 :   keys.add("compulsory","BIASFACTOR", "bias factor");
+     173           2 :   keys.add("compulsory","BSTRIDE", "stride for writing bias");
+     174           2 :   keys.add("compulsory","BFILE", "file name for bias");
+     175           2 :   keys.add("optional","NOT_SHARED",   "list of arguments (from 1 to N) not summed across replicas");
+     176           2 :   keys.add("optional","NOT_RESCALED", "these last N arguments will not be scaled");
+     177           2 :   keys.add("optional","MC_STEPS","number of MC steps");
+     178           2 :   keys.add("optional","MC_STRIDE","MC stride");
+     179           2 :   keys.add("optional","PACE", "Pace for adding bias, in MC stride unit");
+     180           1 :   componentsAreNotOptional(keys);
+     181           2 :   keys.addOutputComponent("igamma",  "default","gamma parameter");
+     182           2 :   keys.addOutputComponent("accgamma","default","MC acceptance for gamma");
+     183           2 :   keys.addOutputComponent("wtbias",  "default","well-tempered bias");
+     184           1 : }
+     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 :   double temp=0.0;
+     268           0 :   parse("TEMP",temp);
+     269           0 :   if(temp>0.0) kbt_=plumed.getAtoms().getKBoltzmann()*temp;
+     270           0 :   else kbt_=plumed.getAtoms().getKbT();
+     271             : 
+     272           0 :   checkRead();
+     273             : 
+     274           0 :   log.printf("  temperature of the system in energy unit %f\n",kbt_);
+     275           0 :   log.printf("  name of the SELECTOR use for this action %s\n",selector_.c_str());
+     276           0 :   log.printf("  number of bins in grid %u\n",nbin);
+     277           0 :   log.printf("  number of arguments that will not be scaled %u\n",nores_);
+     278           0 :   if(nrep_>1) log<<"  number of arguments that will not be summed across replicas "<<not_shared.size()<<"\n";
+     279           0 :   log.printf("  biasfactor %f\n",biasf_);
+     280           0 :   log.printf("  initial hills height %f\n",w0_);
+     281           0 :   log.printf("  stride to write bias to file %u\n",Biasstride_);
+     282           0 :   log.printf("  write bias to file : %s\n",Biasfilename_.c_str());
+     283           0 :   log.printf("  number of replicas %u\n",nrep_);
+     284           0 :   log.printf("  number of MC steps %d\n",MCsteps_);
+     285           0 :   log.printf("  do MC every %d steps\n", MCstride_);
+     286           0 :   log.printf("\n");
+     287             : 
+     288           0 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     289             : 
+     290             : 
+     291             :   // add components
+     292           0 :   addComponent("igamma");   componentIsNotPeriodic("igamma");
+     293           0 :   addComponent("accgamma"); componentIsNotPeriodic("accgamma");
+     294           0 :   addComponent("wtbias");   componentIsNotPeriodic("wtbias");
+     295             : 
+     296             :   // initialize random seed
+     297           0 :   srand (time(NULL));
+     298             : 
+     299             :   // read bias if restarting
+     300           0 :   if(getRestart()) read_bias();
+     301           0 : }
+     302             : 
+     303           0 : Rescale::~Rescale()
+     304             : {
+     305           0 :   Biasfile_.close();
+     306           0 : }
+     307             : 
+     308           0 : void Rescale::read_bias()
+     309             : {
+     310             : // open file
+     311           0 :   auto ifile=Tools::make_unique<IFile>();
+     312           0 :   ifile->link(*this);
+     313           0 :   if(ifile->FileExist(Biasfilename_)) {
+     314           0 :     ifile->open(Biasfilename_);
+     315             :     // read all the lines, store last value of bias
+     316             :     double MDtime;
+     317           0 :     while(ifile->scanField("MD_time",MDtime)) {
+     318           0 :       for(unsigned i=0; i<bias_.size(); ++i) {
+     319             :         // convert i to string
+     320           0 :         std::stringstream ss;
+     321             :         ss << i;
+     322             :         // label
+     323           0 :         std::string label = "b" + ss.str();
+     324             :         // read entry
+     325           0 :         ifile->scanField(label, bias_[i]);
+     326           0 :       }
+     327             :       // new line
+     328           0 :       ifile->scanField();
+     329             :     }
+     330           0 :     ifile->close();
+     331             :   } else {
+     332           0 :     error("Cannot find bias file "+Biasfilename_+"\n");
+     333             :   }
+     334           0 : }
+     335             : 
+     336           0 : unsigned Rescale::proposeMove(unsigned x, unsigned xmin, unsigned xmax)
+     337             : {
+     338           0 :   int xmin_i = static_cast<int>(xmin);
+     339           0 :   int xmax_i = static_cast<int>(xmax);
+     340             :   int dx;
+     341           0 :   int r = rand() % 2;
+     342           0 :   if( r % 2 == 0 ) dx = +1;
+     343             :   else             dx = -1;
+     344             : // new index, integer
+     345           0 :   int x_new = static_cast<int>(x) + dx;
+     346             : // check boundaries
+     347           0 :   if(x_new >= xmax_i) x_new = xmax_i-1;
+     348             :   if(x_new <  xmin_i) x_new = xmin_i;
+     349           0 :   return static_cast<unsigned>(x_new);
+     350             : }
+     351             : 
+     352           0 : bool Rescale::doAccept(double oldE, double newE)
+     353             : {
+     354             :   bool accept = false;
+     355             :   // calculate delta energy
+     356           0 :   double delta = ( newE - oldE ) / kbt_;
+     357             :   // if delta is negative always accept move
+     358           0 :   if( delta < 0.0 ) {
+     359             :     accept = true;
+     360             :   } else {
+     361             :     // otherwise extract random number
+     362           0 :     double s = static_cast<double>(rand()) / RAND_MAX;
+     363           0 :     if( s < std::exp(-delta) ) { accept = true; }
+     364             :   }
+     365           0 :   return accept;
+     366             : }
+     367             : 
+     368           0 : void Rescale::doMonteCarlo(unsigned igamma, double oldE,
+     369             :                            std::vector<double> args, std::vector<double> bargs)
+     370             : {
+     371             :   double oldB, newB;
+     372             : 
+     373             : // cycle on MC steps
+     374           0 :   for(unsigned i=0; i<MCsteps_; ++i) {
+     375             :     // propose move in igamma
+     376           0 :     unsigned new_igamma = proposeMove(igamma, 0, gamma_.size());
+     377             :     // calculate new energy
+     378             :     double newE = 0.0;
+     379           0 :     for(unsigned j=0; j<args.size(); ++j) {
+     380             :       // calculate energy term
+     381           0 :       double fact = 1.0/pow(gamma_[new_igamma], expo_[j]) - 1.0;
+     382           0 :       newE += args[j] * fact;
+     383             :     }
+     384             :     // calculate contributions from non-rescaled terms
+     385           0 :     if(bargs.size()>0) {
+     386           0 :       oldB = bias_[igamma]+bargs[igamma];
+     387           0 :       newB = bias_[new_igamma]+bargs[new_igamma];
+     388             :     } else {
+     389           0 :       oldB = bias_[igamma];
+     390           0 :       newB = bias_[new_igamma];
+     391             :     }
+     392             :     // accept or reject
+     393           0 :     bool accept = doAccept(oldE+oldB, newE+newB);
+     394           0 :     if(accept) {
+     395           0 :       igamma = new_igamma;
+     396             :       oldE = newE;
+     397           0 :       MCaccgamma_++;
+     398             :     }
+     399             :   }
+     400             : // send values of gamma to all replicas
+     401           0 :   if(comm.Get_rank()==0) {
+     402           0 :     if(multi_sim_comm.Get_rank()!=0) igamma = 0;
+     403           0 :     multi_sim_comm.Sum(&igamma, 1);
+     404             :   } else {
+     405           0 :     igamma = 0;
+     406             :   }
+     407             : // local communication
+     408           0 :   comm.Sum(&igamma, 1);
+     409             : 
+     410             : // set the value of gamma into passMap
+     411           0 :   plumed.passMap[selector_]=static_cast<double>(igamma);
+     412           0 : }
+     413             : 
+     414           0 : void Rescale::print_bias(long int step)
+     415             : {
+     416             : // if first time open the file
+     417           0 :   if(first_bias_) {
+     418           0 :     first_bias_ = false;
+     419           0 :     Biasfile_.link(*this);
+     420           0 :     Biasfile_.open(Biasfilename_);
+     421             :     Biasfile_.setHeavyFlush();
+     422           0 :     Biasfile_.fmtField("%30.5f");
+     423             :   }
+     424             : 
+     425             : // write fields
+     426           0 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     427           0 :   Biasfile_.printField("MD_time", MDtime);
+     428           0 :   for(unsigned i=0; i<bias_.size(); ++i) {
+     429             :     // convert i to string
+     430           0 :     std::stringstream ss;
+     431             :     ss << i;
+     432             :     // label
+     433           0 :     std::string label = "b" + ss.str();
+     434             :     // print entry
+     435           0 :     Biasfile_.printField(label, bias_[i]);
+     436           0 :   }
+     437           0 :   Biasfile_.printField();
+     438           0 : }
+     439             : 
+     440           0 : void Rescale::calculate()
+     441             : {
+     442             :   // get the current value of the selector
+     443           0 :   unsigned igamma = static_cast<unsigned>(plumed.passMap[selector_]);
+     444             : 
+     445             :   // collect data from other replicas
+     446           0 :   std::vector<double> all_args(getNumberOfArguments(), 0.0);
+     447             :   // first calculate arguments
+     448           0 :   for(unsigned i=0; i<all_args.size(); ++i) {
+     449           0 :     double arg = getArgument(i);
+     450             :     // sum shared arguments across replicas
+     451           0 :     if(shared_[i]==1) {
+     452           0 :       if(comm.Get_rank()==0) multi_sim_comm.Sum(arg);
+     453           0 :       else                   arg = 0.0;
+     454           0 :       if(comm.Get_size()>1)  comm.Sum(arg);
+     455             :     }
+     456             :     // put into all_args
+     457           0 :     all_args[i] = arg;
+     458             :   }
+     459             : 
+     460             :   // now separate terms that should be rescaled
+     461             :   std::vector<double> args;
+     462           0 :   if(getNumberOfArguments()-nores_>0) args.resize(getNumberOfArguments()-nores_);
+     463           0 :   for(unsigned i=0; i<args.size(); ++i)  args[i]  = all_args[i];
+     464             :   // and terms that should not
+     465             :   std::vector<double> bargs;
+     466           0 :   if(nores_>0) bargs.resize(nores_);
+     467           0 :   for(unsigned i=0; i<bargs.size(); ++i) bargs[i] = all_args[i+args.size()];
+     468             : 
+     469             :   // calculate energy and forces, only on rescaled terms
+     470             :   double ene = 0.0;
+     471           0 :   for(unsigned i=0; i<args.size(); ++i) {
+     472             :     // calculate energy term
+     473           0 :     double fact = 1.0/pow(gamma_[igamma], expo_[i]) - 1.0;
+     474           0 :     ene += args[i] * fact;
+     475             :     // add force
+     476           0 :     setOutputForce(i, -fact);
+     477             :   }
+     478             : 
+     479             :   // set to zero on the others
+     480           0 :   for(unsigned i=0; i<bargs.size(); ++i) setOutputForce(i+args.size(), 0.0);
+     481             : 
+     482             :   // set value of the bias
+     483             :   setBias(ene);
+     484             :   // set value of the wt-bias
+     485           0 :   getPntrToComponent("wtbias")->set(bias_[igamma]);
+     486             :   // set values of gamma
+     487           0 :   getPntrToComponent("igamma")->set(igamma);
+     488             :   // get time step
+     489           0 :   long int step = getStep();
+     490           0 :   if(MCfirst_==-1) MCfirst_=step;
+     491             :   // calculate gamma acceptance
+     492           0 :   double MCtrials = std::floor(static_cast<double>(step-MCfirst_) / static_cast<double>(MCstride_))+1.0;
+     493           0 :   double accgamma = static_cast<double>(MCaccgamma_) / static_cast<double>(MCsteps_) / MCtrials;
+     494           0 :   getPntrToComponent("accgamma")->set(accgamma);
+     495             : 
+     496             :   // do MC at the right time step
+     497           0 :   if(step%MCstride_==0&&!getExchangeStep()) doMonteCarlo(igamma, ene, args, bargs);
+     498             : 
+     499             :   // add well-tempered like bias
+     500           0 :   if(step%Biaspace_==0) {
+     501             :     // get updated igamma
+     502           0 :     unsigned igamma = static_cast<unsigned>(plumed.passMap[selector_]);
+     503             :     // add "Gaussian"
+     504           0 :     double kbDT = kbt_ * ( biasf_ - 1.0 );
+     505           0 :     bias_[igamma] += w0_ * std::exp(-bias_[igamma] / kbDT);
+     506             :   }
+     507             : 
+     508             :   // print bias
+     509           0 :   if(step%Biasstride_==0) print_bias(step);
+     510             : 
+     511           0 : }
+     512             : 
+     513             : 
+     514             : }
+     515             : }
+     516             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..0dd20879ea --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:1366151890.0 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4SAXS13calculate_gpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZN4PLMD4isdb4SAXSC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb4SAXS12calculateASFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd2
_ZN4PLMD4isdb4SAXS17getMartiniSFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe1426createERKNS_13ActionOptionsE14
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE174
_ZN4PLMD4isdb4SAXS6updateEv174
_ZN4PLMD4isdb4SAXS9calculateEv174
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe142C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe142D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.func.html b/coverage/isdb/SAXS.cpp.func.html new file mode 100644 index 0000000000..8f4826ab34 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:1366151890.0 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe1426createERKNS_13ActionOptionsE14
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe142C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe142D2Ev3473
_ZN4PLMD4isdb4SAXS12calculateASFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd2
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE174
_ZN4PLMD4isdb4SAXS13calculate_gpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD4isdb4SAXS17getMartiniSFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb4SAXS6updateEv174
_ZN4PLMD4isdb4SAXS9calculateEv174
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb4SAXSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.gcov.html b/coverage/isdb/SAXS.cpp.gcov.html new file mode 100644 index 0000000000..e852b28a31 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.gcov.html @@ -0,0 +1,2164 @@ + + + + + + + + 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:1366151890.0 %
Date:2024-06-10 08:19:14Functions:101283.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 beads structure factor for Nucleic Acids by Cristina Paissoni
+      27             : */
+      28             : 
+      29             : #include "MetainferenceBase.h"
+      30             : #include "core/ActionRegister.h"
+      31             : #include "core/ActionSet.h"
+      32             : #include "core/GenericMolInfo.h"
+      33             : #include "tools/Communicator.h"
+      34             : #include "tools/Pbc.h"
+      35             : 
+      36             : #include <map>
+      37             : 
+      38             : #ifdef __PLUMED_HAS_ARRAYFIRE
+      39             : #include <arrayfire.h>
+      40             : #include <af/util.h>
+      41             : #endif
+      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 SAXS
+      51             : /*
+      52             : Calculates SAXS scattered intensity using either the Debye equation.
+      53             : 
+      54             : Intensities are calculated for a set of scattering length set using QVALUE keywords that are numbered starting from 0.
+      55             : Structure factors can be either assigned using a polynomial expansion to any order using the PARAMETERS keywords;
+      56             : automatically assigned to atoms using the ATOMISTIC flag reading a PDB file, a correction for the water density is
+      57             : automatically added, with water density that by default is 0.334 but that can be set otherwise using WATERDENS;
+      58             : automatically assigned to Martini pseudo atoms using the MARTINI flag.
+      59             : The calculated intensities can be scaled using the SCALEINT keywords. This is applied by rescaling the structure factors.
+      60             : Experimental reference intensities can be added using the EXPINT keywords.
+      61             : By default SAXS is calculated using Debye on CPU, by adding the GPU flag it is possible to solve the equation on a GPU
+      62             : if the ARRAYFIRE libraries are installed and correctly linked.
+      63             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+      64             : 
+      65             : \par Examples
+      66             : in the following example the saxs intensities for a martini model are calculated. structure factors
+      67             : are obtained from the pdb file indicated in the MOLINFO.
+      68             : 
+      69             : \plumedfile
+      70             : MOLINFO STRUCTURE=template.pdb
+      71             : 
+      72             : SAXS ...
+      73             : LABEL=saxs
+      74             : ATOMS=1-355
+      75             : SCALEINT=3920000
+      76             : MARTINI
+      77             : QVALUE1=0.02 EXPINT1=1.0902
+      78             : QVALUE2=0.05 EXPINT2=0.790632
+      79             : QVALUE3=0.08 EXPINT3=0.453808
+      80             : QVALUE4=0.11 EXPINT4=0.254737
+      81             : QVALUE5=0.14 EXPINT5=0.154928
+      82             : QVALUE6=0.17 EXPINT6=0.0921503
+      83             : QVALUE7=0.2 EXPINT7=0.052633
+      84             : QVALUE8=0.23 EXPINT8=0.0276557
+      85             : QVALUE9=0.26 EXPINT9=0.0122775
+      86             : QVALUE10=0.29 EXPINT10=0.00880634
+      87             : QVALUE11=0.32 EXPINT11=0.0137301
+      88             : QVALUE12=0.35 EXPINT12=0.0180036
+      89             : QVALUE13=0.38 EXPINT13=0.0193374
+      90             : QVALUE14=0.41 EXPINT14=0.0210131
+      91             : QVALUE15=0.44 EXPINT15=0.0220506
+      92             : ... SAXS
+      93             : 
+      94             : PRINT ARG=(saxs\.q-.*),(saxs\.exp-.*) FILE=colvar STRIDE=1
+      95             : 
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : class SAXS :
+     102             :   public MetainferenceBase
+     103             : {
+     104             : private:
+     105             :   enum { H, C, N, O, P, S, NTT };
+     106             :   enum { ALA_BB, ARG_BB, ARG_SC1, ARG_SC2, ASN_BB, ASN_SC1, ASP_BB, ASP_SC1, CYS_BB, CYS_SC1,
+     107             :          GLN_BB, GLN_SC1, GLU_BB, GLU_SC1, GLY_BB, HIS_BB, HIS_SC1, HIS_SC2, HIS_SC3, ILE_BB,
+     108             :          ILE_SC1, LEU_BB, LEU_SC1, LYS_BB, LYS_SC1, LYS_SC2, MET_BB, MET_SC1, PHE_BB, PHE_SC1,
+     109             :          PHE_SC2, PHE_SC3, PRO_BB, PRO_SC1, SER_BB, SER_SC1, THR_BB, THR_SC1, TRP_BB, TRP_SC1,
+     110             :          TRP_SC2, TRP_SC3, TRP_SC4, TYR_BB, TYR_SC1, TYR_SC2, TYR_SC3, VAL_BB, VAL_SC1, A_BB1,
+     111             :          A_BB2, A_BB3, A_SC1, A_SC2, A_SC3, A_SC4, A_3TE, A_5TE, A_TE3, A_TE5, C_BB1, C_BB2,
+     112             :          C_BB3, C_SC1, C_SC2, C_SC3, C_3TE, C_5TE, C_TE3, C_TE5, G_BB1, G_BB2, G_BB3, G_SC1,
+     113             :          G_SC2, G_SC3, G_SC4, G_3TE, G_5TE, G_TE3, G_TE5, U_BB1, U_BB2, U_BB3, U_SC1, U_SC2,
+     114             :          U_SC3, U_3TE, U_5TE, U_TE3, U_TE5, DA_BB1, DA_BB2, DA_BB3, DA_SC1, DA_SC2, DA_SC3,
+     115             :          DA_SC4, DA_3TE, DA_5TE, DA_TE3, DA_TE5, DC_BB1, DC_BB2, DC_BB3, DC_SC1, DC_SC2, DC_SC3,
+     116             :          DC_3TE, DC_5TE, DC_TE3, DC_TE5, DG_BB1, DG_BB2, DG_BB3, DG_SC1, DG_SC2, DG_SC3, DG_SC4,
+     117             :          DG_3TE, DG_5TE, DG_TE3, DG_TE5, DT_BB1, DT_BB2, DT_BB3, DT_SC1, DT_SC2, DT_SC3, DT_3TE,
+     118             :          DT_5TE, DT_TE3, DT_TE5, NMARTINI
+     119             :        };
+     120             :   bool                       pbc;
+     121             :   bool                       serial;
+     122             :   bool                       gpu;
+     123             :   int                        deviceid;
+     124             :   std::vector<unsigned>           atoi;
+     125             :   std::vector<double>             q_list;
+     126             :   std::vector<double>             FF_rank;
+     127             :   std::vector<std::vector<double> >    FF_value;
+     128             :   std::vector<std::vector<float> >     FFf_value;
+     129             : 
+     130             :   void calculate_gpu(std::vector<Vector> &deriv);
+     131             :   void calculate_cpu(std::vector<Vector> &deriv);
+     132             :   void getMartiniSFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter);
+     133             :   double calculateASF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho);
+     134             : 
+     135             : public:
+     136             :   static void registerKeywords( Keywords& keys );
+     137             :   explicit SAXS(const ActionOptions&);
+     138             :   void calculate() override;
+     139             :   void update() override;
+     140             : };
+     141             : 
+     142       10447 : PLUMED_REGISTER_ACTION(SAXS,"SAXS")
+     143             : 
+     144          15 : void SAXS::registerKeywords(Keywords& keys) {
+     145          15 :   componentsAreNotOptional(keys);
+     146          15 :   MetainferenceBase::registerKeywords(keys);
+     147          30 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     148          30 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     149          30 :   keys.add("compulsory","DEVICEID","0","Identifier of the GPU to be used");
+     150          30 :   keys.addFlag("GPU",false,"calculate SAXS using ARRAYFIRE on an accelerator device");
+     151          30 :   keys.addFlag("ATOMISTIC",false,"calculate SAXS for an atomistic model");
+     152          30 :   keys.addFlag("MARTINI",false,"calculate SAXS for a Martini model");
+     153          30 :   keys.add("atoms","ATOMS","The atoms to be included in the calculation, e.g. the whole protein.");
+     154          30 :   keys.add("numbered","QVALUE","Selected scattering lengths in Angstrom are given as QVALUE1, QVALUE2, ... .");
+     155          30 :   keys.add("numbered","PARAMETERS","Used parameter Keywords like PARAMETERS1, PARAMETERS2. These are used to calculate the structure factor for the \\f$i\\f$th atom/bead.");
+     156          30 :   keys.add("compulsory","WATERDENS","0.334","Density of the water to be used for the correction of atomistic structure factors.");
+     157          30 :   keys.add("numbered","EXPINT","Add an experimental value for each q value.");
+     158          30 :   keys.add("compulsory","SCALEINT","1.0","SCALING value of the calculated data. Useful to simplify the comparison.");
+     159          30 :   keys.addOutputComponent("q","default","the # SAXS of q");
+     160          30 :   keys.addOutputComponent("exp","EXPINT","the # experimental intensity");
+     161          15 : }
+     162             : 
+     163          14 : SAXS::SAXS(const ActionOptions&ao):
+     164             :   PLUMED_METAINF_INIT(ao),
+     165          14 :   pbc(true),
+     166          14 :   serial(false),
+     167          14 :   gpu(false),
+     168          14 :   deviceid(0)
+     169             : {
+     170             :   std::vector<AtomNumber> atoms;
+     171          28 :   parseAtomList("ATOMS",atoms);
+     172          14 :   const unsigned size = atoms.size();
+     173             : 
+     174          14 :   parseFlag("SERIAL",serial);
+     175             : 
+     176          14 :   bool nopbc=!pbc;
+     177          14 :   parseFlag("NOPBC",nopbc);
+     178          14 :   pbc=!nopbc;
+     179          14 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     180           2 :   else         log.printf("  without periodic boundary conditions\n");
+     181             : 
+     182          14 :   parseFlag("GPU",gpu);
+     183             : #ifndef  __PLUMED_HAS_ARRAYFIRE
+     184          14 :   if(gpu) error("To use the GPU mode PLUMED must be compiled with ARRAYFIRE");
+     185             : #endif
+     186             : 
+     187          28 :   parse("DEVICEID",deviceid);
+     188             : #ifdef  __PLUMED_HAS_ARRAYFIRE
+     189             :   if(gpu) {
+     190             :     af::setDevice(deviceid);
+     191             :     af::info();
+     192             :   }
+     193             : #endif
+     194             : 
+     195             :   unsigned ntarget=0;
+     196             :   for(unsigned i=0;; ++i) {
+     197             :     double t_list;
+     198         328 :     if( !parseNumbered( "QVALUE", i+1, t_list) ) break;
+     199         150 :     if(t_list<=0.) error("QVALUE cannot be less or equal to zero!\n");
+     200         150 :     q_list.push_back(t_list);
+     201         150 :     ntarget++;
+     202         150 :   }
+     203             :   const unsigned numq = ntarget;
+     204             : 
+     205         164 :   for(unsigned i=0; i<numq; i++) {
+     206         150 :     if(q_list[i]==0.) error("it is not possible to set q=0\n");
+     207         150 :     if(i>0&&q_list[i]<q_list[i-1]) error("QVALUE must be in ascending order");
+     208         150 :     log.printf("  my q: %lf \n",q_list[i]);
+     209             :   }
+     210             : 
+     211          14 :   bool atomistic=false;
+     212          14 :   parseFlag("ATOMISTIC",atomistic);
+     213          14 :   bool martini=false;
+     214          14 :   parseFlag("MARTINI",martini);
+     215             : 
+     216          14 :   if(martini&&atomistic) error("You cannot use MARTINI and ATOMISTIC at the same time");
+     217             : 
+     218          14 :   double rho = 0.334;
+     219          28 :   parse("WATERDENS", rho);
+     220             : 
+     221             :   double Iq0=0;
+     222             :   std::vector<std::vector<long double> > FF_tmp;
+     223          14 :   atoi.resize(size);
+     224          14 :   if(!atomistic&&!martini) {
+     225             :     //read in parameter std::vector
+     226             :     std::vector<std::vector<long double> > parameter;
+     227           4 :     parameter.resize(size);
+     228             :     ntarget=0;
+     229          36 :     for(unsigned i=0; i<size; ++i) {
+     230          64 :       if( !parseNumberedVector( "PARAMETERS", i+1, parameter[i]) ) break;
+     231          32 :       ntarget++;
+     232             :     }
+     233           4 :     if( ntarget!=size ) error("found wrong number of parameter std::vectors");
+     234           4 :     FF_tmp.resize(numq,std::vector<long double>(size));
+     235          36 :     for(unsigned i=0; i<size; ++i) {
+     236          32 :       atoi[i]=i;
+     237         128 :       for(unsigned k=0; k<numq; ++k) {
+     238         480 :         for(unsigned j=0; j<parameter[i].size(); ++j) {
+     239         384 :           FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     240             :         }
+     241             :       }
+     242             :     }
+     243          36 :     for(unsigned i=0; i<size; ++i) Iq0+=parameter[i][0];
+     244          14 :   } else if(martini) {
+     245             :     //read in parameter std::vector
+     246          16 :     FF_tmp.resize(numq,std::vector<long double>(NMARTINI));
+     247             :     std::vector<std::vector<long double> > parameter;
+     248           8 :     parameter.resize(NMARTINI);
+     249           8 :     getMartiniSFparam(atoms, parameter);
+     250        1072 :     for(unsigned i=0; i<NMARTINI; ++i) {
+     251       17024 :       for(unsigned k=0; k<numq; ++k) {
+     252      127680 :         for(unsigned j=0; j<parameter[i].size(); ++j) {
+     253      111720 :           FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     254             :         }
+     255             :       }
+     256             :     }
+     257        8400 :     for(unsigned i=0; i<size; ++i) Iq0+=parameter[atoi[i]][0];
+     258          10 :   } else if(atomistic) {
+     259           2 :     FF_tmp.resize(numq,std::vector<long double>(NTT));
+     260           2 :     Iq0=calculateASF(atoms, FF_tmp, rho);
+     261             :   }
+     262          14 :   double scale_int = Iq0*Iq0;
+     263             : 
+     264             :   std::vector<double> expint;
+     265          14 :   expint.resize( numq );
+     266             :   ntarget=0;
+     267         146 :   for(unsigned i=0; i<numq; ++i) {
+     268         268 :     if( !parseNumbered( "EXPINT", i+1, expint[i] ) ) break;
+     269         132 :     ntarget++;
+     270             :   }
+     271             :   bool exp=false;
+     272          14 :   if(ntarget!=numq && ntarget!=0) error("found wrong number of EXPINT values");
+     273          14 :   if(ntarget==numq) exp=true;
+     274          14 :   if(getDoScore()&&!exp) error("with DOSCORE you need to set the EXPINT values");
+     275             : 
+     276          14 :   double tmp_scale_int=1.;
+     277          14 :   parse("SCALEINT",tmp_scale_int);
+     278             : 
+     279          14 :   if(tmp_scale_int!=1) scale_int /= tmp_scale_int;
+     280             :   else {
+     281          14 :     if(exp) scale_int /= expint[0];
+     282             :   }
+     283             : 
+     284          14 :   if(!gpu) {
+     285          14 :     FF_rank.resize(numq);
+     286             :     unsigned n_atom_types=size;
+     287          14 :     if(atomistic) n_atom_types=NTT;
+     288          12 :     else if(martini) n_atom_types=NMARTINI;
+     289          14 :     FF_value.resize(n_atom_types,std::vector<double>(numq));
+     290         164 :     for(unsigned k=0; k<numq; ++k) {
+     291       16314 :       for(unsigned i=0; i<n_atom_types; i++) FF_value[i][k] = static_cast<double>(FF_tmp[k][i])/std::sqrt(scale_int);
+     292      187524 :       for(unsigned i=0; i<size; i++) FF_rank[k] += FF_value[atoi[i]][k]*FF_value[atoi[i]][k];
+     293             :     }
+     294             :   } else {
+     295           0 :     FFf_value.resize(numq,std::vector<float>(size));
+     296           0 :     for(unsigned k=0; k<numq; ++k) {
+     297           0 :       for(unsigned i=0; i<size; i++) {
+     298           0 :         FFf_value[k][i] = static_cast<float>(FF_tmp[k][atoi[i]])/std::sqrt(scale_int);
+     299             :       }
+     300             :     }
+     301             :   }
+     302             : 
+     303          14 :   if(!getDoScore()) {
+     304          84 :     for(unsigned i=0; i<numq; i++) {
+     305          78 :       std::string num; Tools::convert(i,num);
+     306          78 :       addComponentWithDerivatives("q-"+num);
+     307         156 :       componentIsNotPeriodic("q-"+num);
+     308             :     }
+     309           6 :     if(exp) {
+     310          64 :       for(unsigned i=0; i<numq; i++) {
+     311          60 :         std::string num; Tools::convert(i,num);
+     312          60 :         addComponent("exp-"+num);
+     313          60 :         componentIsNotPeriodic("exp-"+num);
+     314          60 :         Value* comp=getPntrToComponent("exp-"+num);
+     315          60 :         comp->set(expint[i]);
+     316             :       }
+     317             :     }
+     318             :   } else {
+     319          80 :     for(unsigned i=0; i<numq; i++) {
+     320          72 :       std::string num; Tools::convert(i,num);
+     321          72 :       addComponent("q-"+num);
+     322         144 :       componentIsNotPeriodic("q-"+num);
+     323             :     }
+     324          80 :     for(unsigned i=0; i<numq; i++) {
+     325          72 :       std::string num; Tools::convert(i,num);
+     326          72 :       addComponent("exp-"+num);
+     327          72 :       componentIsNotPeriodic("exp-"+num);
+     328          72 :       Value* comp=getPntrToComponent("exp-"+num);
+     329          72 :       comp->set(expint[i]);
+     330             :     }
+     331             :   }
+     332             : 
+     333             :   // convert units to nm^-1
+     334         164 :   for(unsigned i=0; i<numq; ++i) {
+     335         150 :     q_list[i]=q_list[i]*10.0;    //factor 10 to convert from A^-1 to nm^-1
+     336             :   }
+     337          14 :   log<<"  Bibliography ";
+     338          14 :   if(martini) {
+     339          16 :     log<<plumed.cite("Niebling, Björling, Westenhoff, J Appl Crystallogr 47, 1190–1198 (2014).");
+     340          24 :     log<<plumed.cite("Paissoni, Jussupow, Camilloni, J Appl Crystallogr 52, 394-402 (2019).");
+     341             :   }
+     342          14 :   if(atomistic) {
+     343           4 :     log<<plumed.cite("Fraser, MacRae, Suzuki, J. Appl. Crystallogr., 11, 693–694 (1978).");
+     344           6 :     log<<plumed.cite("Brown, Fox, Maslen, O'Keefe, Willis, International Tables for Crystallography C, 554–595 (International Union of Crystallography, 2006).");
+     345             :   }
+     346          28 :   log<< plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     347          14 :   log<<"\n";
+     348             : 
+     349          14 :   requestAtoms(atoms, false);
+     350          14 :   if(getDoScore()) {
+     351           8 :     setParameters(expint);
+     352           8 :     Initialise(numq);
+     353             :   }
+     354          14 :   setDerivatives();
+     355          14 :   checkRead();
+     356          28 : }
+     357             : 
+     358           0 : void SAXS::calculate_gpu(std::vector<Vector> &deriv)
+     359             : {
+     360             : #ifdef __PLUMED_HAS_ARRAYFIRE
+     361             :   const unsigned size = getNumberOfAtoms();
+     362             :   const unsigned numq = q_list.size();
+     363             : 
+     364             :   std::vector<float> sum;
+     365             :   sum.resize(numq);
+     366             : 
+     367             :   std::vector<float> dd;
+     368             :   dd.resize(size*3*numq);
+     369             : 
+     370             :   // on gpu only the master rank run the calculation
+     371             :   if(comm.Get_rank()==0) {
+     372             :     std::vector<float> posi;
+     373             :     posi.resize(3*size);
+     374             :     #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     375             :     for (unsigned i=0; i<size; i++) {
+     376             :       const Vector tmp = getPosition(i);
+     377             :       posi[3*i]   = static_cast<float>(tmp[0]);
+     378             :       posi[3*i+1] = static_cast<float>(tmp[1]);
+     379             :       posi[3*i+2] = static_cast<float>(tmp[2]);
+     380             :     }
+     381             : 
+     382             :     // create array a and b containing atomic coordinates
+     383             :     af::setDevice(deviceid);
+     384             :     // 3,size,1,1
+     385             :     af::array pos_a = af::array(3, size, &posi.front());
+     386             :     // size,3,1,1
+     387             :     pos_a = af::moddims(pos_a.T(), size, 3, 1);
+     388             :     // size,3,1,1
+     389             :     af::array pos_b = pos_a(af::span, af::span);
+     390             :     // size,1,3,1
+     391             :     pos_a = af::moddims(pos_a, size, 1, 3);
+     392             :     // 1,size,3,1
+     393             :     pos_b = af::moddims(pos_b, 1, size, 3);
+     394             : 
+     395             :     // size,size,3,1
+     396             :     af::array pos_a_t = af::tile(pos_a, 1, size, 1);
+     397             :     // size,size,3,1: for some reason we need this
+     398             :     pos_a_t = af::moddims(pos_a_t, size, size, 3);
+     399             :     // size,size,3,1
+     400             :     af::array pos_b_t = af::tile(pos_b, size, 1, 1);
+     401             :     // size,size,3,1: for some reason we need this
+     402             :     pos_b_t = af::moddims(pos_b_t, size, size, 3);
+     403             :     // size,size,3,1
+     404             :     af::array xyz_dist = pos_a_t - pos_b_t;
+     405             :     // size,size,1,1
+     406             :     af::array square = af::sum(xyz_dist*xyz_dist,2);
+     407             :     // size,size,1,1
+     408             :     af::array dist_sqrt = af::sqrt(square);
+     409             :     // replace the zero of square with one to avoid nan in the derivatives (the number does not matter because this are multiplied by zero)
+     410             :     af::replace(square,!(af::iszero(square)),1.);
+     411             :     // size,size,3,1
+     412             :     xyz_dist = xyz_dist / af::tile(square, 1, 1, 3);
+     413             :     // numq,1,1,1
+     414             :     af::array sum_device   = af::constant(0, numq, f32);
+     415             :     // numq,size,3,1
+     416             :     af::array deriv_device = af::constant(0, numq, size, 3, f32);
+     417             : 
+     418             :     for (unsigned k=0; k<numq; k++) {
+     419             :       // calculate FF matrix
+     420             :       // size,1,1,1
+     421             :       af::array AFF_value(size, &FFf_value[k].front());
+     422             :       // size,size,1,1
+     423             :       af::array FFdist_mod = af::tile(AFF_value(af::span), 1, size)*af::transpose(af::tile(AFF_value(af::span), 1, size));
+     424             : 
+     425             :       // get q
+     426             :       const float qvalue = static_cast<float>(q_list[k]);
+     427             :       // size,size,1,1
+     428             :       af::array dist_q = qvalue*dist_sqrt;
+     429             :       // size,size,1
+     430             :       af::array dist_sin = af::sin(dist_q)/dist_q;
+     431             :       af::replace(dist_sin,!(af::isNaN(dist_sin)),1.);
+     432             :       // 1,1,1,1
+     433             :       sum_device(k) = af::sum(af::flat(dist_sin)*af::flat(FFdist_mod));
+     434             : 
+     435             :       // size,size,1,1
+     436             :       af::array tmp = FFdist_mod*(dist_sin - af::cos(dist_q));
+     437             :       // size,size,3,1
+     438             :       af::array dd_all = af::tile(tmp, 1, 1, 3)*xyz_dist;
+     439             :       // it should become 1,size,3
+     440             :       deriv_device(k, af::span, af::span) = af::sum(dd_all,0);
+     441             :     }
+     442             : 
+     443             :     // read out results
+     444             :     sum_device.host(&sum.front());
+     445             : 
+     446             :     deriv_device = af::reorder(deriv_device, 2, 1, 0);
+     447             :     deriv_device = af::flat(deriv_device);
+     448             :     deriv_device.host(&dd.front());
+     449             :   }
+     450             : 
+     451             :   comm.Bcast(dd, 0);
+     452             :   comm.Bcast(sum, 0);
+     453             : 
+     454             :   for(unsigned k=0; k<numq; k++) {
+     455             :     std::string num; Tools::convert(k,num);
+     456             :     Value* val=getPntrToComponent("q-"+num);
+     457             :     val->set(sum[k]);
+     458             :     if(getDoScore()) setCalcData(k, sum[k]);
+     459             :     for(unsigned i=0; i<size; i++) {
+     460             :       const unsigned di = k*size*3+i*3;
+     461             :       deriv[k*size+i] = Vector(2.*dd[di+0],2.*dd[di+1],2.*dd[di+2]);
+     462             :     }
+     463             :   }
+     464             : #endif
+     465           0 : }
+     466             : 
+     467         174 : void SAXS::calculate_cpu(std::vector<Vector> &deriv)
+     468             : {
+     469             :   const unsigned size = getNumberOfAtoms();
+     470         174 :   const unsigned numq = q_list.size();
+     471             : 
+     472         174 :   unsigned stride = comm.Get_size();
+     473         174 :   unsigned rank   = comm.Get_rank();
+     474         174 :   if(serial) {
+     475             :     stride = 1;
+     476             :     rank   = 0;
+     477             :   }
+     478             : 
+     479         174 :   std::vector<double> sum(numq,0);
+     480         174 :   unsigned nt=OpenMP::getNumThreads();
+     481         174 :   #pragma omp parallel num_threads(nt)
+     482             :   {
+     483             :     std::vector<Vector> omp_deriv(deriv.size());
+     484             :     std::vector<double> omp_sum(numq,0);
+     485             :     #pragma omp for nowait
+     486             :     for (unsigned i=rank; i<size-1; i+=stride) {
+     487             :       Vector posi = getPosition(i);
+     488             :       for (unsigned j=i+1; j<size ; j++) {
+     489             :         Vector c_distances = delta(posi,getPosition(j));
+     490             :         double m_distances = c_distances.modulo();
+     491             :         c_distances = c_distances/m_distances/m_distances;
+     492             :         for (unsigned k=0; k<numq; k++) {
+     493             :           unsigned kdx=k*size;
+     494             :           double qdist = q_list[k]*m_distances;
+     495             :           double FFF = 2.*FF_value[atoi[i]][k]*FF_value[atoi[j]][k];
+     496             :           double tsq = std::sin(qdist)/qdist;
+     497             :           double tcq = std::cos(qdist);
+     498             :           double tmp = FFF*(tcq-tsq);
+     499             :           Vector dd  = c_distances*tmp;
+     500             :           if(nt>1) {
+     501             :             omp_deriv[kdx+i] -=dd;
+     502             :             omp_deriv[kdx+j] +=dd;
+     503             :             omp_sum[k] += FFF*tsq;
+     504             :           } else {
+     505             :             deriv[kdx+i] -= dd;
+     506             :             deriv[kdx+j] += dd;
+     507             :             sum[k]       += FFF*tsq;
+     508             :           }
+     509             :         }
+     510             :       }
+     511             :     }
+     512             :     #pragma omp critical
+     513             :     if(nt>1) {
+     514             :       for(unsigned i=0; i<deriv.size(); i++) deriv[i]+=omp_deriv[i];
+     515             :       for(unsigned k=0; k<numq; k++) sum[k]+=omp_sum[k];
+     516             :     }
+     517             :   }
+     518             : 
+     519         174 :   if(!serial) {
+     520         172 :     comm.Sum(&deriv[0][0], 3*deriv.size());
+     521         172 :     comm.Sum(&sum[0], numq);
+     522             :   }
+     523             : 
+     524        1764 :   for (unsigned k=0; k<numq; k++) {
+     525        1590 :     sum[k]+=FF_rank[k];
+     526        1590 :     std::string num; Tools::convert(k,num);
+     527        1590 :     Value* val=getPntrToComponent("q-"+num);
+     528        1590 :     val->set(sum[k]);
+     529        1590 :     if(getDoScore()) setCalcData(k, sum[k]);
+     530             :   }
+     531         174 : }
+     532             : 
+     533         174 : void SAXS::calculate()
+     534             : {
+     535         174 :   if(pbc) makeWhole();
+     536             : 
+     537         174 :   const size_t size = getNumberOfAtoms();
+     538             :   const size_t numq = q_list.size();
+     539             : 
+     540         174 :   std::vector<Vector> deriv(numq*size);
+     541         174 :   if(gpu) calculate_gpu(deriv);
+     542         174 :   else calculate_cpu(deriv);
+     543             : 
+     544         174 :   if(getDoScore()) {
+     545             :     /* Metainference */
+     546         168 :     double score = getScore();
+     547             :     setScore(score);
+     548             :   }
+     549             : 
+     550        1764 :   for (unsigned k=0; k<numq; k++) {
+     551        1590 :     const unsigned kdx=k*size;
+     552        1590 :     Tensor deriv_box;
+     553             :     Value* val;
+     554        1590 :     if(!getDoScore()) {
+     555          78 :       std::string num; Tools::convert(k,num);
+     556          78 :       val=getPntrToComponent("q-"+num);
+     557      166056 :       for(unsigned i=0; i<size; i++) {
+     558      165978 :         setAtomsDerivatives(val, i, deriv[kdx+i]);
+     559      165978 :         deriv_box += Tensor(getPosition(i),deriv[kdx+i]);
+     560             :       }
+     561             :     } else {
+     562        1512 :       val=getPntrToComponent("score");
+     563      450828 :       for(unsigned i=0; i<size; i++) {
+     564      449316 :         setAtomsDerivatives(val, i, deriv[kdx+i]*getMetaDer(k));
+     565      449316 :         deriv_box += Tensor(getPosition(i),deriv[kdx+i]*getMetaDer(k));
+     566             :       }
+     567             :     }
+     568        1590 :     setBoxDerivatives(val, -deriv_box);
+     569             :   }
+     570         174 : }
+     571             : 
+     572         174 : void SAXS::update() {
+     573             :   // write status file
+     574         174 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     575         174 : }
+     576             : 
+     577           8 : void SAXS::getMartiniSFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter)
+     578             : {
+     579           8 :   parameter[ALA_BB].push_back(9.045);
+     580           8 :   parameter[ALA_BB].push_back(-0.098114);
+     581           8 :   parameter[ALA_BB].push_back(7.54281);
+     582           8 :   parameter[ALA_BB].push_back(-1.97438);
+     583           8 :   parameter[ALA_BB].push_back(-8.32689);
+     584           8 :   parameter[ALA_BB].push_back(6.09318);
+     585           8 :   parameter[ALA_BB].push_back(-1.18913);
+     586             : 
+     587           8 :   parameter[ARG_BB].push_back(10.729);
+     588           8 :   parameter[ARG_BB].push_back(-0.0392574);
+     589           8 :   parameter[ARG_BB].push_back(1.15382);
+     590           8 :   parameter[ARG_BB].push_back(-0.155999);
+     591           8 :   parameter[ARG_BB].push_back(-2.43619);
+     592           8 :   parameter[ARG_BB].push_back(1.72922);
+     593           8 :   parameter[ARG_BB].push_back(-0.33799);
+     594             : 
+     595           8 :   parameter[ARG_SC1].push_back(-2.796);
+     596           8 :   parameter[ARG_SC1].push_back(0.472403);
+     597           8 :   parameter[ARG_SC1].push_back(8.07424);
+     598           8 :   parameter[ARG_SC1].push_back(4.37299);
+     599           8 :   parameter[ARG_SC1].push_back(-10.7398);
+     600           8 :   parameter[ARG_SC1].push_back(4.95677);
+     601           8 :   parameter[ARG_SC1].push_back(-0.725797);
+     602             : 
+     603           8 :   parameter[ARG_SC2].push_back(15.396);
+     604           8 :   parameter[ARG_SC2].push_back(0.0636736);
+     605           8 :   parameter[ARG_SC2].push_back(-1.258);
+     606           8 :   parameter[ARG_SC2].push_back(1.93135);
+     607           8 :   parameter[ARG_SC2].push_back(-4.45031);
+     608           8 :   parameter[ARG_SC2].push_back(2.49356);
+     609           8 :   parameter[ARG_SC2].push_back(-0.410721);
+     610             : 
+     611           8 :   parameter[ASN_BB].push_back(10.738);
+     612           8 :   parameter[ASN_BB].push_back(-0.0402162);
+     613           8 :   parameter[ASN_BB].push_back(1.03007);
+     614           8 :   parameter[ASN_BB].push_back(-0.254174);
+     615           8 :   parameter[ASN_BB].push_back(-2.12015);
+     616           8 :   parameter[ASN_BB].push_back(1.55535);
+     617           8 :   parameter[ASN_BB].push_back(-0.30963);
+     618             : 
+     619           8 :   parameter[ASN_SC1].push_back(9.249);
+     620           8 :   parameter[ASN_SC1].push_back(-0.0148678);
+     621           8 :   parameter[ASN_SC1].push_back(5.52169);
+     622           8 :   parameter[ASN_SC1].push_back(0.00853212);
+     623           8 :   parameter[ASN_SC1].push_back(-6.71992);
+     624           8 :   parameter[ASN_SC1].push_back(3.93622);
+     625           8 :   parameter[ASN_SC1].push_back(-0.64973);
+     626             : 
+     627           8 :   parameter[ASP_BB].push_back(10.695);
+     628           8 :   parameter[ASP_BB].push_back(-0.0410247);
+     629           8 :   parameter[ASP_BB].push_back(1.03656);
+     630           8 :   parameter[ASP_BB].push_back(-0.298558);
+     631           8 :   parameter[ASP_BB].push_back(-2.06064);
+     632           8 :   parameter[ASP_BB].push_back(1.53495);
+     633           8 :   parameter[ASP_BB].push_back(-0.308365);
+     634             : 
+     635           8 :   parameter[ASP_SC1].push_back(9.476);
+     636           8 :   parameter[ASP_SC1].push_back(-0.0254664);
+     637           8 :   parameter[ASP_SC1].push_back(5.57899);
+     638           8 :   parameter[ASP_SC1].push_back(-0.395027);
+     639           8 :   parameter[ASP_SC1].push_back(-5.9407);
+     640           8 :   parameter[ASP_SC1].push_back(3.48836);
+     641           8 :   parameter[ASP_SC1].push_back(-0.569402);
+     642             : 
+     643           8 :   parameter[CYS_BB].push_back(10.698);
+     644           8 :   parameter[CYS_BB].push_back(-0.0233493);
+     645           8 :   parameter[CYS_BB].push_back(1.18257);
+     646           8 :   parameter[CYS_BB].push_back(0.0684464);
+     647           8 :   parameter[CYS_BB].push_back(-2.792);
+     648           8 :   parameter[CYS_BB].push_back(1.88995);
+     649           8 :   parameter[CYS_BB].push_back(-0.360229);
+     650             : 
+     651           8 :   parameter[CYS_SC1].push_back(8.199);
+     652           8 :   parameter[CYS_SC1].push_back(-0.0261569);
+     653           8 :   parameter[CYS_SC1].push_back(6.79677);
+     654           8 :   parameter[CYS_SC1].push_back(-0.343845);
+     655           8 :   parameter[CYS_SC1].push_back(-5.03578);
+     656           8 :   parameter[CYS_SC1].push_back(2.7076);
+     657           8 :   parameter[CYS_SC1].push_back(-0.420714);
+     658             : 
+     659           8 :   parameter[GLN_BB].push_back(10.728);
+     660           8 :   parameter[GLN_BB].push_back(-0.0391984);
+     661           8 :   parameter[GLN_BB].push_back(1.09264);
+     662           8 :   parameter[GLN_BB].push_back(-0.261555);
+     663           8 :   parameter[GLN_BB].push_back(-2.21245);
+     664           8 :   parameter[GLN_BB].push_back(1.62071);
+     665           8 :   parameter[GLN_BB].push_back(-0.322325);
+     666             : 
+     667           8 :   parameter[GLN_SC1].push_back(8.317);
+     668           8 :   parameter[GLN_SC1].push_back(-0.229045);
+     669           8 :   parameter[GLN_SC1].push_back(12.6338);
+     670           8 :   parameter[GLN_SC1].push_back(-7.6719);
+     671           8 :   parameter[GLN_SC1].push_back(-5.8376);
+     672           8 :   parameter[GLN_SC1].push_back(5.53784);
+     673           8 :   parameter[GLN_SC1].push_back(-1.12604);
+     674             : 
+     675           8 :   parameter[GLU_BB].push_back(10.694);
+     676           8 :   parameter[GLU_BB].push_back(-0.0521961);
+     677           8 :   parameter[GLU_BB].push_back(1.11153);
+     678           8 :   parameter[GLU_BB].push_back(-0.491995);
+     679           8 :   parameter[GLU_BB].push_back(-1.86236);
+     680           8 :   parameter[GLU_BB].push_back(1.45332);
+     681           8 :   parameter[GLU_BB].push_back(-0.29708);
+     682             : 
+     683           8 :   parameter[GLU_SC1].push_back(8.544);
+     684           8 :   parameter[GLU_SC1].push_back(-0.249555);
+     685           8 :   parameter[GLU_SC1].push_back(12.8031);
+     686           8 :   parameter[GLU_SC1].push_back(-8.42696);
+     687           8 :   parameter[GLU_SC1].push_back(-4.66486);
+     688           8 :   parameter[GLU_SC1].push_back(4.90004);
+     689           8 :   parameter[GLU_SC1].push_back(-1.01204);
+     690             : 
+     691           8 :   parameter[GLY_BB].push_back(9.977);
+     692           8 :   parameter[GLY_BB].push_back(-0.0285799);
+     693           8 :   parameter[GLY_BB].push_back(1.84236);
+     694           8 :   parameter[GLY_BB].push_back(-0.0315192);
+     695           8 :   parameter[GLY_BB].push_back(-2.88326);
+     696           8 :   parameter[GLY_BB].push_back(1.87323);
+     697           8 :   parameter[GLY_BB].push_back(-0.345773);
+     698             : 
+     699           8 :   parameter[HIS_BB].push_back(10.721);
+     700           8 :   parameter[HIS_BB].push_back(-0.0379337);
+     701           8 :   parameter[HIS_BB].push_back(1.06028);
+     702           8 :   parameter[HIS_BB].push_back(-0.236143);
+     703           8 :   parameter[HIS_BB].push_back(-2.17819);
+     704           8 :   parameter[HIS_BB].push_back(1.58357);
+     705           8 :   parameter[HIS_BB].push_back(-0.31345);
+     706             : 
+     707           8 :   parameter[HIS_SC1].push_back(-0.424);
+     708           8 :   parameter[HIS_SC1].push_back(0.665176);
+     709           8 :   parameter[HIS_SC1].push_back(3.4369);
+     710           8 :   parameter[HIS_SC1].push_back(2.93795);
+     711           8 :   parameter[HIS_SC1].push_back(-5.18288);
+     712           8 :   parameter[HIS_SC1].push_back(2.12381);
+     713           8 :   parameter[HIS_SC1].push_back(-0.284224);
+     714             : 
+     715           8 :   parameter[HIS_SC2].push_back(5.363);
+     716           8 :   parameter[HIS_SC2].push_back(-0.0176945);
+     717           8 :   parameter[HIS_SC2].push_back(2.9506);
+     718           8 :   parameter[HIS_SC2].push_back(-0.387018);
+     719           8 :   parameter[HIS_SC2].push_back(-1.83951);
+     720           8 :   parameter[HIS_SC2].push_back(0.9703);
+     721           8 :   parameter[HIS_SC2].push_back(-0.1458);
+     722             : 
+     723           8 :   parameter[HIS_SC3].push_back(5.784);
+     724           8 :   parameter[HIS_SC3].push_back(-0.0293129);
+     725           8 :   parameter[HIS_SC3].push_back(2.74167);
+     726           8 :   parameter[HIS_SC3].push_back(-0.520875);
+     727           8 :   parameter[HIS_SC3].push_back(-1.62949);
+     728           8 :   parameter[HIS_SC3].push_back(0.902379);
+     729           8 :   parameter[HIS_SC3].push_back(-0.139957);
+     730             : 
+     731           8 :   parameter[ILE_BB].push_back(10.699);
+     732           8 :   parameter[ILE_BB].push_back(-0.0188962);
+     733           8 :   parameter[ILE_BB].push_back(1.217);
+     734           8 :   parameter[ILE_BB].push_back(0.242481);
+     735           8 :   parameter[ILE_BB].push_back(-3.13898);
+     736           8 :   parameter[ILE_BB].push_back(2.07916);
+     737           8 :   parameter[ILE_BB].push_back(-0.392574);
+     738             : 
+     739           8 :   parameter[ILE_SC1].push_back(-4.448);
+     740           8 :   parameter[ILE_SC1].push_back(1.20996);
+     741           8 :   parameter[ILE_SC1].push_back(11.5141);
+     742           8 :   parameter[ILE_SC1].push_back(6.98895);
+     743           8 :   parameter[ILE_SC1].push_back(-19.1948);
+     744           8 :   parameter[ILE_SC1].push_back(9.89207);
+     745           8 :   parameter[ILE_SC1].push_back(-1.60877);
+     746             : 
+     747           8 :   parameter[LEU_BB].push_back(10.692);
+     748           8 :   parameter[LEU_BB].push_back(-0.0414917);
+     749           8 :   parameter[LEU_BB].push_back(1.1077);
+     750           8 :   parameter[LEU_BB].push_back(-0.288062);
+     751           8 :   parameter[LEU_BB].push_back(-2.17187);
+     752           8 :   parameter[LEU_BB].push_back(1.59879);
+     753           8 :   parameter[LEU_BB].push_back(-0.318545);
+     754             : 
+     755           8 :   parameter[LEU_SC1].push_back(-4.448);
+     756           8 :   parameter[LEU_SC1].push_back(2.1063);
+     757           8 :   parameter[LEU_SC1].push_back(6.72381);
+     758           8 :   parameter[LEU_SC1].push_back(14.6954);
+     759           8 :   parameter[LEU_SC1].push_back(-23.7197);
+     760           8 :   parameter[LEU_SC1].push_back(10.7247);
+     761           8 :   parameter[LEU_SC1].push_back(-1.59146);
+     762             : 
+     763           8 :   parameter[LYS_BB].push_back(10.706);
+     764           8 :   parameter[LYS_BB].push_back(-0.0468629);
+     765           8 :   parameter[LYS_BB].push_back(1.09477);
+     766           8 :   parameter[LYS_BB].push_back(-0.432751);
+     767           8 :   parameter[LYS_BB].push_back(-1.94335);
+     768           8 :   parameter[LYS_BB].push_back(1.49109);
+     769           8 :   parameter[LYS_BB].push_back(-0.302589);
+     770             : 
+     771           8 :   parameter[LYS_SC1].push_back(-2.796);
+     772           8 :   parameter[LYS_SC1].push_back(0.508044);
+     773           8 :   parameter[LYS_SC1].push_back(7.91436);
+     774           8 :   parameter[LYS_SC1].push_back(4.54097);
+     775           8 :   parameter[LYS_SC1].push_back(-10.8051);
+     776           8 :   parameter[LYS_SC1].push_back(4.96204);
+     777           8 :   parameter[LYS_SC1].push_back(-0.724414);
+     778             : 
+     779           8 :   parameter[LYS_SC2].push_back(3.070);
+     780           8 :   parameter[LYS_SC2].push_back(-0.0101448);
+     781           8 :   parameter[LYS_SC2].push_back(4.67994);
+     782           8 :   parameter[LYS_SC2].push_back(-0.792529);
+     783           8 :   parameter[LYS_SC2].push_back(-2.09142);
+     784           8 :   parameter[LYS_SC2].push_back(1.02933);
+     785           8 :   parameter[LYS_SC2].push_back(-0.137787);
+     786             : 
+     787           8 :   parameter[MET_BB].push_back(10.671);
+     788           8 :   parameter[MET_BB].push_back(-0.0433724);
+     789           8 :   parameter[MET_BB].push_back(1.13784);
+     790           8 :   parameter[MET_BB].push_back(-0.40768);
+     791           8 :   parameter[MET_BB].push_back(-2.00555);
+     792           8 :   parameter[MET_BB].push_back(1.51673);
+     793           8 :   parameter[MET_BB].push_back(-0.305547);
+     794             : 
+     795           8 :   parameter[MET_SC1].push_back(5.85);
+     796           8 :   parameter[MET_SC1].push_back(-0.0485798);
+     797           8 :   parameter[MET_SC1].push_back(17.0391);
+     798           8 :   parameter[MET_SC1].push_back(-3.65327);
+     799           8 :   parameter[MET_SC1].push_back(-13.174);
+     800           8 :   parameter[MET_SC1].push_back(8.68286);
+     801           8 :   parameter[MET_SC1].push_back(-1.56095);
+     802             : 
+     803           8 :   parameter[PHE_BB].push_back(10.741);
+     804           8 :   parameter[PHE_BB].push_back(-0.0317275);
+     805           8 :   parameter[PHE_BB].push_back(1.15599);
+     806           8 :   parameter[PHE_BB].push_back(0.0276187);
+     807           8 :   parameter[PHE_BB].push_back(-2.74757);
+     808           8 :   parameter[PHE_BB].push_back(1.88783);
+     809           8 :   parameter[PHE_BB].push_back(-0.363525);
+     810             : 
+     811           8 :   parameter[PHE_SC1].push_back(-0.636);
+     812           8 :   parameter[PHE_SC1].push_back(0.527882);
+     813           8 :   parameter[PHE_SC1].push_back(6.77612);
+     814           8 :   parameter[PHE_SC1].push_back(3.18508);
+     815           8 :   parameter[PHE_SC1].push_back(-8.92826);
+     816           8 :   parameter[PHE_SC1].push_back(4.29752);
+     817           8 :   parameter[PHE_SC1].push_back(-0.65187);
+     818             : 
+     819           8 :   parameter[PHE_SC2].push_back(-0.424);
+     820           8 :   parameter[PHE_SC2].push_back(0.389174);
+     821           8 :   parameter[PHE_SC2].push_back(4.11761);
+     822           8 :   parameter[PHE_SC2].push_back(2.29527);
+     823           8 :   parameter[PHE_SC2].push_back(-4.7652);
+     824           8 :   parameter[PHE_SC2].push_back(1.97023);
+     825           8 :   parameter[PHE_SC2].push_back(-0.262318);
+     826             : 
+     827           8 :   parameter[PHE_SC3].push_back(-0.424);
+     828           8 :   parameter[PHE_SC3].push_back(0.38927);
+     829           8 :   parameter[PHE_SC3].push_back(4.11708);
+     830           8 :   parameter[PHE_SC3].push_back(2.29623);
+     831           8 :   parameter[PHE_SC3].push_back(-4.76592);
+     832           8 :   parameter[PHE_SC3].push_back(1.97055);
+     833           8 :   parameter[PHE_SC3].push_back(-0.262381);
+     834             : 
+     835           8 :   parameter[PRO_BB].push_back(11.434);
+     836           8 :   parameter[PRO_BB].push_back(-0.033323);
+     837           8 :   parameter[PRO_BB].push_back(0.472014);
+     838           8 :   parameter[PRO_BB].push_back(-0.290854);
+     839           8 :   parameter[PRO_BB].push_back(-1.81409);
+     840           8 :   parameter[PRO_BB].push_back(1.39751);
+     841           8 :   parameter[PRO_BB].push_back(-0.280407);
+     842             : 
+     843           8 :   parameter[PRO_SC1].push_back(-2.796);
+     844           8 :   parameter[PRO_SC1].push_back(0.95668);
+     845           8 :   parameter[PRO_SC1].push_back(6.84197);
+     846           8 :   parameter[PRO_SC1].push_back(6.43774);
+     847           8 :   parameter[PRO_SC1].push_back(-12.5068);
+     848           8 :   parameter[PRO_SC1].push_back(5.64597);
+     849           8 :   parameter[PRO_SC1].push_back(-0.825206);
+     850             : 
+     851           8 :   parameter[SER_BB].push_back(10.699);
+     852           8 :   parameter[SER_BB].push_back(-0.0325828);
+     853           8 :   parameter[SER_BB].push_back(1.20329);
+     854           8 :   parameter[SER_BB].push_back(-0.0674351);
+     855           8 :   parameter[SER_BB].push_back(-2.60749);
+     856           8 :   parameter[SER_BB].push_back(1.80318);
+     857           8 :   parameter[SER_BB].push_back(-0.346803);
+     858             : 
+     859           8 :   parameter[SER_SC1].push_back(3.298);
+     860           8 :   parameter[SER_SC1].push_back(-0.0366801);
+     861           8 :   parameter[SER_SC1].push_back(5.11077);
+     862           8 :   parameter[SER_SC1].push_back(-1.46774);
+     863           8 :   parameter[SER_SC1].push_back(-1.48421);
+     864           8 :   parameter[SER_SC1].push_back(0.800326);
+     865           8 :   parameter[SER_SC1].push_back(-0.108314);
+     866             : 
+     867           8 :   parameter[THR_BB].push_back(10.697);
+     868           8 :   parameter[THR_BB].push_back(-0.0242955);
+     869           8 :   parameter[THR_BB].push_back(1.24671);
+     870           8 :   parameter[THR_BB].push_back(0.146423);
+     871           8 :   parameter[THR_BB].push_back(-2.97429);
+     872           8 :   parameter[THR_BB].push_back(1.97513);
+     873           8 :   parameter[THR_BB].push_back(-0.371479);
+     874             : 
+     875           8 :   parameter[THR_SC1].push_back(2.366);
+     876           8 :   parameter[THR_SC1].push_back(0.0297604);
+     877           8 :   parameter[THR_SC1].push_back(11.9216);
+     878           8 :   parameter[THR_SC1].push_back(-9.32503);
+     879           8 :   parameter[THR_SC1].push_back(1.9396);
+     880           8 :   parameter[THR_SC1].push_back(0.0804861);
+     881           8 :   parameter[THR_SC1].push_back(-0.0302721);
+     882             : 
+     883           8 :   parameter[TRP_BB].push_back(10.689);
+     884           8 :   parameter[TRP_BB].push_back(-0.0265879);
+     885           8 :   parameter[TRP_BB].push_back(1.17819);
+     886           8 :   parameter[TRP_BB].push_back(0.0386457);
+     887           8 :   parameter[TRP_BB].push_back(-2.75634);
+     888           8 :   parameter[TRP_BB].push_back(1.88065);
+     889           8 :   parameter[TRP_BB].push_back(-0.360217);
+     890             : 
+     891           8 :   parameter[TRP_SC1].push_back(0.084);
+     892           8 :   parameter[TRP_SC1].push_back(0.752407);
+     893           8 :   parameter[TRP_SC1].push_back(5.3802);
+     894           8 :   parameter[TRP_SC1].push_back(4.09281);
+     895           8 :   parameter[TRP_SC1].push_back(-9.28029);
+     896           8 :   parameter[TRP_SC1].push_back(4.45923);
+     897           8 :   parameter[TRP_SC1].push_back(-0.689008);
+     898             : 
+     899           8 :   parameter[TRP_SC2].push_back(5.739);
+     900           8 :   parameter[TRP_SC2].push_back(0.0298492);
+     901           8 :   parameter[TRP_SC2].push_back(4.60446);
+     902           8 :   parameter[TRP_SC2].push_back(1.34463);
+     903           8 :   parameter[TRP_SC2].push_back(-5.69968);
+     904           8 :   parameter[TRP_SC2].push_back(2.84924);
+     905           8 :   parameter[TRP_SC2].push_back(-0.433781);
+     906             : 
+     907           8 :   parameter[TRP_SC3].push_back(-0.424);
+     908           8 :   parameter[TRP_SC3].push_back(0.388576);
+     909           8 :   parameter[TRP_SC3].push_back(4.11859);
+     910           8 :   parameter[TRP_SC3].push_back(2.29485);
+     911           8 :   parameter[TRP_SC3].push_back(-4.76255);
+     912           8 :   parameter[TRP_SC3].push_back(1.96849);
+     913           8 :   parameter[TRP_SC3].push_back(-0.262015);
+     914             : 
+     915           8 :   parameter[TRP_SC4].push_back(-0.424);
+     916           8 :   parameter[TRP_SC4].push_back(0.387685);
+     917           8 :   parameter[TRP_SC4].push_back(4.12153);
+     918           8 :   parameter[TRP_SC4].push_back(2.29144);
+     919           8 :   parameter[TRP_SC4].push_back(-4.7589);
+     920           8 :   parameter[TRP_SC4].push_back(1.96686);
+     921           8 :   parameter[TRP_SC4].push_back(-0.261786);
+     922             : 
+     923           8 :   parameter[TYR_BB].push_back(10.689);
+     924           8 :   parameter[TYR_BB].push_back(-0.0193526);
+     925           8 :   parameter[TYR_BB].push_back(1.18241);
+     926           8 :   parameter[TYR_BB].push_back(0.207318);
+     927           8 :   parameter[TYR_BB].push_back(-3.0041);
+     928           8 :   parameter[TYR_BB].push_back(1.99335);
+     929           8 :   parameter[TYR_BB].push_back(-0.376482);
+     930             : 
+     931           8 :   parameter[TYR_SC1].push_back(-0.636);
+     932           8 :   parameter[TYR_SC1].push_back(0.528902);
+     933           8 :   parameter[TYR_SC1].push_back(6.78168);
+     934           8 :   parameter[TYR_SC1].push_back(3.17769);
+     935           8 :   parameter[TYR_SC1].push_back(-8.93667);
+     936           8 :   parameter[TYR_SC1].push_back(4.30692);
+     937           8 :   parameter[TYR_SC1].push_back(-0.653993);
+     938             : 
+     939           8 :   parameter[TYR_SC2].push_back(-0.424);
+     940           8 :   parameter[TYR_SC2].push_back(0.388811);
+     941           8 :   parameter[TYR_SC2].push_back(4.11851);
+     942           8 :   parameter[TYR_SC2].push_back(2.29545);
+     943           8 :   parameter[TYR_SC2].push_back(-4.7668);
+     944           8 :   parameter[TYR_SC2].push_back(1.97131);
+     945           8 :   parameter[TYR_SC2].push_back(-0.262534);
+     946             : 
+     947           8 :   parameter[TYR_SC3].push_back(4.526);
+     948           8 :   parameter[TYR_SC3].push_back(-0.00381305);
+     949           8 :   parameter[TYR_SC3].push_back(5.8567);
+     950           8 :   parameter[TYR_SC3].push_back(-0.214086);
+     951           8 :   parameter[TYR_SC3].push_back(-4.63649);
+     952           8 :   parameter[TYR_SC3].push_back(2.52869);
+     953           8 :   parameter[TYR_SC3].push_back(-0.39894);
+     954             : 
+     955           8 :   parameter[VAL_BB].push_back(10.691);
+     956           8 :   parameter[VAL_BB].push_back(-0.0162929);
+     957           8 :   parameter[VAL_BB].push_back(1.24446);
+     958           8 :   parameter[VAL_BB].push_back(0.307914);
+     959           8 :   parameter[VAL_BB].push_back(-3.27446);
+     960           8 :   parameter[VAL_BB].push_back(2.14788);
+     961           8 :   parameter[VAL_BB].push_back(-0.403259);
+     962             : 
+     963           8 :   parameter[VAL_SC1].push_back(-3.516);
+     964           8 :   parameter[VAL_SC1].push_back(1.62307);
+     965           8 :   parameter[VAL_SC1].push_back(5.43064);
+     966           8 :   parameter[VAL_SC1].push_back(9.28809);
+     967           8 :   parameter[VAL_SC1].push_back(-14.9927);
+     968           8 :   parameter[VAL_SC1].push_back(6.6133);
+     969           8 :   parameter[VAL_SC1].push_back(-0.964977);
+     970             : 
+     971           8 :   parameter[A_BB1].push_back(32.88500000);
+     972           8 :   parameter[A_BB1].push_back(0.08339900);
+     973           8 :   parameter[A_BB1].push_back(-7.36054400);
+     974           8 :   parameter[A_BB1].push_back(2.19220300);
+     975           8 :   parameter[A_BB1].push_back(-3.56523400);
+     976           8 :   parameter[A_BB1].push_back(2.33326900);
+     977           8 :   parameter[A_BB1].push_back(-0.39785500);
+     978             : 
+     979           8 :   parameter[A_BB2].push_back(3.80600000);
+     980           8 :   parameter[A_BB2].push_back(-0.10727600);
+     981           8 :   parameter[A_BB2].push_back(9.58854100);
+     982           8 :   parameter[A_BB2].push_back(-6.23740500);
+     983           8 :   parameter[A_BB2].push_back(-0.48267300);
+     984           8 :   parameter[A_BB2].push_back(1.14119500);
+     985           8 :   parameter[A_BB2].push_back(-0.21385600);
+     986             : 
+     987           8 :   parameter[A_BB3].push_back(3.59400000);
+     988           8 :   parameter[A_BB3].push_back(0.04537300);
+     989           8 :   parameter[A_BB3].push_back(9.59178900);
+     990           8 :   parameter[A_BB3].push_back(-1.29202200);
+     991           8 :   parameter[A_BB3].push_back(-7.10851000);
+     992           8 :   parameter[A_BB3].push_back(4.05571200);
+     993           8 :   parameter[A_BB3].push_back(-0.63372500);
+     994             : 
+     995           8 :   parameter[A_SC1].push_back(6.67100000);
+     996           8 :   parameter[A_SC1].push_back(-0.00855300);
+     997           8 :   parameter[A_SC1].push_back(1.63222400);
+     998           8 :   parameter[A_SC1].push_back(-0.06466200);
+     999           8 :   parameter[A_SC1].push_back(-1.48694200);
+    1000           8 :   parameter[A_SC1].push_back(0.78544600);
+    1001           8 :   parameter[A_SC1].push_back(-0.12083500);
+    1002             : 
+    1003           8 :   parameter[A_SC2].push_back(5.95100000);
+    1004           8 :   parameter[A_SC2].push_back(-0.02606600);
+    1005           8 :   parameter[A_SC2].push_back(2.54399900);
+    1006           8 :   parameter[A_SC2].push_back(-0.48436900);
+    1007           8 :   parameter[A_SC2].push_back(-1.55357400);
+    1008           8 :   parameter[A_SC2].push_back(0.86466900);
+    1009           8 :   parameter[A_SC2].push_back(-0.13509000);
+    1010             : 
+    1011           8 :   parameter[A_SC3].push_back(11.39400000);
+    1012           8 :   parameter[A_SC3].push_back(0.00871300);
+    1013           8 :   parameter[A_SC3].push_back(-0.23891300);
+    1014           8 :   parameter[A_SC3].push_back(0.48919400);
+    1015           8 :   parameter[A_SC3].push_back(-1.75289400);
+    1016           8 :   parameter[A_SC3].push_back(0.99267500);
+    1017           8 :   parameter[A_SC3].push_back(-0.16291300);
+    1018             : 
+    1019           8 :   parameter[A_SC4].push_back(6.45900000);
+    1020           8 :   parameter[A_SC4].push_back(0.01990600);
+    1021           8 :   parameter[A_SC4].push_back(4.17970400);
+    1022           8 :   parameter[A_SC4].push_back(0.97629900);
+    1023           8 :   parameter[A_SC4].push_back(-5.03297800);
+    1024           8 :   parameter[A_SC4].push_back(2.55576700);
+    1025           8 :   parameter[A_SC4].push_back(-0.39150500);
+    1026             : 
+    1027           8 :   parameter[A_3TE].push_back(4.23000000);
+    1028           8 :   parameter[A_3TE].push_back(0.00064800);
+    1029           8 :   parameter[A_3TE].push_back(0.92124600);
+    1030           8 :   parameter[A_3TE].push_back(0.08064300);
+    1031           8 :   parameter[A_3TE].push_back(-0.39054400);
+    1032           8 :   parameter[A_3TE].push_back(0.12429100);
+    1033           8 :   parameter[A_3TE].push_back(-0.01122700);
+    1034             : 
+    1035           8 :   parameter[A_5TE].push_back(4.23000000);
+    1036           8 :   parameter[A_5TE].push_back(0.00039300);
+    1037           8 :   parameter[A_5TE].push_back(0.92305100);
+    1038           8 :   parameter[A_5TE].push_back(0.07747500);
+    1039           8 :   parameter[A_5TE].push_back(-0.38792100);
+    1040           8 :   parameter[A_5TE].push_back(0.12323800);
+    1041           8 :   parameter[A_5TE].push_back(-0.01106600);
+    1042             : 
+    1043           8 :   parameter[A_TE3].push_back(7.82400000);
+    1044           8 :   parameter[A_TE3].push_back(-0.04881000);
+    1045           8 :   parameter[A_TE3].push_back(8.21557900);
+    1046          16 :   parameter[A_TE3].push_back(-0.89491400);
+    1047           8 :   parameter[A_TE3].push_back(-9.54293700);
+    1048           8 :   parameter[A_TE3].push_back(6.33122200);
+    1049           8 :   parameter[A_TE3].push_back(-1.16672900);
+    1050             : 
+    1051           8 :   parameter[A_TE5].push_back(8.03600000);
+    1052           8 :   parameter[A_TE5].push_back(0.01641200);
+    1053           8 :   parameter[A_TE5].push_back(5.14902200);
+    1054           8 :   parameter[A_TE5].push_back(0.83419700);
+    1055           8 :   parameter[A_TE5].push_back(-7.59068300);
+    1056           8 :   parameter[A_TE5].push_back(4.52063200);
+    1057           8 :   parameter[A_TE5].push_back(-0.78260800);
+    1058             : 
+    1059           8 :   parameter[C_BB1].push_back(32.88500000);
+    1060           8 :   parameter[C_BB1].push_back(0.08311100);
+    1061           8 :   parameter[C_BB1].push_back(-7.35432100);
+    1062           8 :   parameter[C_BB1].push_back(2.18610000);
+    1063           8 :   parameter[C_BB1].push_back(-3.55788300);
+    1064           8 :   parameter[C_BB1].push_back(2.32918700);
+    1065           8 :   parameter[C_BB1].push_back(-0.39720000);
+    1066             : 
+    1067           8 :   parameter[C_BB2].push_back(3.80600000);
+    1068           8 :   parameter[C_BB2].push_back(-0.10808100);
+    1069           8 :   parameter[C_BB2].push_back(9.61612600);
+    1070           8 :   parameter[C_BB2].push_back(-6.28595400);
+    1071           8 :   parameter[C_BB2].push_back(-0.45187000);
+    1072           8 :   parameter[C_BB2].push_back(1.13326000);
+    1073           8 :   parameter[C_BB2].push_back(-0.21320300);
+    1074             : 
+    1075           8 :   parameter[C_BB3].push_back(3.59400000);
+    1076           8 :   parameter[C_BB3].push_back(0.04484200);
+    1077           8 :   parameter[C_BB3].push_back(9.61919800);
+    1078           8 :   parameter[C_BB3].push_back(-1.33582800);
+    1079           8 :   parameter[C_BB3].push_back(-7.07200400);
+    1080           8 :   parameter[C_BB3].push_back(4.03952900);
+    1081           8 :   parameter[C_BB3].push_back(-0.63098200);
+    1082             : 
+    1083           8 :   parameter[C_SC1].push_back(5.95100000);
+    1084           8 :   parameter[C_SC1].push_back(-0.02911300);
+    1085           8 :   parameter[C_SC1].push_back(2.59700400);
+    1086           8 :   parameter[C_SC1].push_back(-0.55507700);
+    1087           8 :   parameter[C_SC1].push_back(-1.56344600);
+    1088           8 :   parameter[C_SC1].push_back(0.88956200);
+    1089           8 :   parameter[C_SC1].push_back(-0.14061300);
+    1090             : 
+    1091           8 :   parameter[C_SC2].push_back(11.62100000);
+    1092           8 :   parameter[C_SC2].push_back(0.01366100);
+    1093           8 :   parameter[C_SC2].push_back(-0.25959200);
+    1094           8 :   parameter[C_SC2].push_back(0.48918300);
+    1095           8 :   parameter[C_SC2].push_back(-1.52550500);
+    1096           8 :   parameter[C_SC2].push_back(0.83644100);
+    1097           8 :   parameter[C_SC2].push_back(-0.13407300);
+    1098             : 
+    1099           8 :   parameter[C_SC3].push_back(5.01900000);
+    1100           8 :   parameter[C_SC3].push_back(-0.03276100);
+    1101           8 :   parameter[C_SC3].push_back(5.53776900);
+    1102           8 :   parameter[C_SC3].push_back(-0.95105000);
+    1103           8 :   parameter[C_SC3].push_back(-3.71130800);
+    1104           8 :   parameter[C_SC3].push_back(2.16146000);
+    1105           8 :   parameter[C_SC3].push_back(-0.34918600);
+    1106             : 
+    1107           8 :   parameter[C_3TE].push_back(4.23000000);
+    1108           8 :   parameter[C_3TE].push_back(0.00057300);
+    1109           8 :   parameter[C_3TE].push_back(0.92174800);
+    1110           8 :   parameter[C_3TE].push_back(0.07964500);
+    1111           8 :   parameter[C_3TE].push_back(-0.38965700);
+    1112           8 :   parameter[C_3TE].push_back(0.12392500);
+    1113           8 :   parameter[C_3TE].push_back(-0.01117000);
+    1114             : 
+    1115           8 :   parameter[C_5TE].push_back(4.23000000);
+    1116           8 :   parameter[C_5TE].push_back(0.00071000);
+    1117           8 :   parameter[C_5TE].push_back(0.92082800);
+    1118           8 :   parameter[C_5TE].push_back(0.08150600);
+    1119           8 :   parameter[C_5TE].push_back(-0.39127000);
+    1120           8 :   parameter[C_5TE].push_back(0.12455900);
+    1121           8 :   parameter[C_5TE].push_back(-0.01126300);
+    1122             : 
+    1123           8 :   parameter[C_TE3].push_back(7.82400000);
+    1124           8 :   parameter[C_TE3].push_back(-0.05848300);
+    1125           8 :   parameter[C_TE3].push_back(8.29319900);
+    1126           8 :   parameter[C_TE3].push_back(-1.12563800);
+    1127           8 :   parameter[C_TE3].push_back(-9.42197600);
+    1128           8 :   parameter[C_TE3].push_back(6.35441700);
+    1129           8 :   parameter[C_TE3].push_back(-1.18356900);
+    1130             : 
+    1131           8 :   parameter[C_TE5].push_back(8.03600000);
+    1132           8 :   parameter[C_TE5].push_back(0.00493500);
+    1133           8 :   parameter[C_TE5].push_back(4.92622000);
+    1134           8 :   parameter[C_TE5].push_back(0.64810700);
+    1135           8 :   parameter[C_TE5].push_back(-7.05100000);
+    1136           8 :   parameter[C_TE5].push_back(4.26064400);
+    1137           8 :   parameter[C_TE5].push_back(-0.74819100);
+    1138             : 
+    1139           8 :   parameter[G_BB1].push_back(32.88500000);
+    1140           8 :   parameter[G_BB1].push_back(0.08325400);
+    1141           8 :   parameter[G_BB1].push_back(-7.35736000);
+    1142           8 :   parameter[G_BB1].push_back(2.18914800);
+    1143           8 :   parameter[G_BB1].push_back(-3.56154800);
+    1144           8 :   parameter[G_BB1].push_back(2.33120600);
+    1145           8 :   parameter[G_BB1].push_back(-0.39752300);
+    1146             : 
+    1147           8 :   parameter[G_BB2].push_back(3.80600000);
+    1148           8 :   parameter[G_BB2].push_back(-0.10788300);
+    1149           8 :   parameter[G_BB2].push_back(9.60930800);
+    1150           8 :   parameter[G_BB2].push_back(-6.27402500);
+    1151           8 :   parameter[G_BB2].push_back(-0.46192700);
+    1152           8 :   parameter[G_BB2].push_back(1.13737000);
+    1153           8 :   parameter[G_BB2].push_back(-0.21383100);
+    1154             : 
+    1155           8 :   parameter[G_BB3].push_back(3.59400000);
+    1156           8 :   parameter[G_BB3].push_back(0.04514500);
+    1157           8 :   parameter[G_BB3].push_back(9.61234700);
+    1158           8 :   parameter[G_BB3].push_back(-1.31542100);
+    1159           8 :   parameter[G_BB3].push_back(-7.09150500);
+    1160           8 :   parameter[G_BB3].push_back(4.04706200);
+    1161           8 :   parameter[G_BB3].push_back(-0.63201000);
+    1162             : 
+    1163           8 :   parameter[G_SC1].push_back(6.67100000);
+    1164           8 :   parameter[G_SC1].push_back(-0.00863200);
+    1165           8 :   parameter[G_SC1].push_back(1.63252300);
+    1166           8 :   parameter[G_SC1].push_back(-0.06567200);
+    1167           8 :   parameter[G_SC1].push_back(-1.48680500);
+    1168           8 :   parameter[G_SC1].push_back(0.78565600);
+    1169           8 :   parameter[G_SC1].push_back(-0.12088900);
+    1170             : 
+    1171           8 :   parameter[G_SC2].push_back(11.39400000);
+    1172           8 :   parameter[G_SC2].push_back(0.00912200);
+    1173           8 :   parameter[G_SC2].push_back(-0.22869000);
+    1174           8 :   parameter[G_SC2].push_back(0.49616400);
+    1175           8 :   parameter[G_SC2].push_back(-1.75039000);
+    1176           8 :   parameter[G_SC2].push_back(0.98649200);
+    1177           8 :   parameter[G_SC2].push_back(-0.16141600);
+    1178             : 
+    1179           8 :   parameter[G_SC3].push_back(10.90100000);
+    1180           8 :   parameter[G_SC3].push_back(0.02208700);
+    1181           8 :   parameter[G_SC3].push_back(0.17032800);
+    1182           8 :   parameter[G_SC3].push_back(0.73280800);
+    1183           8 :   parameter[G_SC3].push_back(-1.95292000);
+    1184           8 :   parameter[G_SC3].push_back(0.98357600);
+    1185           8 :   parameter[G_SC3].push_back(-0.14790900);
+    1186             : 
+    1187           8 :   parameter[G_SC4].push_back(6.45900000);
+    1188           8 :   parameter[G_SC4].push_back(0.02023700);
+    1189           8 :   parameter[G_SC4].push_back(4.17655400);
+    1190           8 :   parameter[G_SC4].push_back(0.98731800);
+    1191           8 :   parameter[G_SC4].push_back(-5.04352800);
+    1192           8 :   parameter[G_SC4].push_back(2.56059400);
+    1193           8 :   parameter[G_SC4].push_back(-0.39234300);
+    1194             : 
+    1195           8 :   parameter[G_3TE].push_back(4.23000000);
+    1196           8 :   parameter[G_3TE].push_back(0.00066300);
+    1197           8 :   parameter[G_3TE].push_back(0.92118800);
+    1198           8 :   parameter[G_3TE].push_back(0.08062700);
+    1199           8 :   parameter[G_3TE].push_back(-0.39041600);
+    1200           8 :   parameter[G_3TE].push_back(0.12419400);
+    1201           8 :   parameter[G_3TE].push_back(-0.01120500);
+    1202             : 
+    1203           8 :   parameter[G_5TE].push_back(4.23000000);
+    1204          16 :   parameter[G_5TE].push_back(0.00062800);
+    1205           8 :   parameter[G_5TE].push_back(0.92133500);
+    1206           8 :   parameter[G_5TE].push_back(0.08029900);
+    1207           8 :   parameter[G_5TE].push_back(-0.39015300);
+    1208           8 :   parameter[G_5TE].push_back(0.12411600);
+    1209           8 :   parameter[G_5TE].push_back(-0.01119900);
+    1210             : 
+    1211           8 :   parameter[G_TE3].push_back(7.82400000);
+    1212           8 :   parameter[G_TE3].push_back(-0.05177400);
+    1213           8 :   parameter[G_TE3].push_back(8.34606700);
+    1214           8 :   parameter[G_TE3].push_back(-1.02936300);
+    1215           8 :   parameter[G_TE3].push_back(-9.55211900);
+    1216           8 :   parameter[G_TE3].push_back(6.37776600);
+    1217           8 :   parameter[G_TE3].push_back(-1.17898000);
+    1218             : 
+    1219           8 :   parameter[G_TE5].push_back(8.03600000);
+    1220           8 :   parameter[G_TE5].push_back(0.00525100);
+    1221           8 :   parameter[G_TE5].push_back(4.71070600);
+    1222           8 :   parameter[G_TE5].push_back(0.66746900);
+    1223           8 :   parameter[G_TE5].push_back(-6.72538700);
+    1224           8 :   parameter[G_TE5].push_back(4.03644100);
+    1225           8 :   parameter[G_TE5].push_back(-0.70605700);
+    1226             : 
+    1227           8 :   parameter[U_BB1].push_back(32.88500000);
+    1228           8 :   parameter[U_BB1].push_back(0.08321400);
+    1229           8 :   parameter[U_BB1].push_back(-7.35634900);
+    1230           8 :   parameter[U_BB1].push_back(2.18826800);
+    1231           8 :   parameter[U_BB1].push_back(-3.56047400);
+    1232           8 :   parameter[U_BB1].push_back(2.33064700);
+    1233           8 :   parameter[U_BB1].push_back(-0.39744000);
+    1234             : 
+    1235           8 :   parameter[U_BB2].push_back(3.80600000);
+    1236           8 :   parameter[U_BB2].push_back(-0.10773100);
+    1237           8 :   parameter[U_BB2].push_back(9.60099900);
+    1238           8 :   parameter[U_BB2].push_back(-6.26131900);
+    1239           8 :   parameter[U_BB2].push_back(-0.46668300);
+    1240           8 :   parameter[U_BB2].push_back(1.13698100);
+    1241           8 :   parameter[U_BB2].push_back(-0.21351600);
+    1242             : 
+    1243           8 :   parameter[U_BB3].push_back(3.59400000);
+    1244           8 :   parameter[U_BB3].push_back(0.04544300);
+    1245           8 :   parameter[U_BB3].push_back(9.59625900);
+    1246           8 :   parameter[U_BB3].push_back(-1.29222200);
+    1247           8 :   parameter[U_BB3].push_back(-7.11143200);
+    1248           8 :   parameter[U_BB3].push_back(4.05687700);
+    1249           8 :   parameter[U_BB3].push_back(-0.63382800);
+    1250             : 
+    1251           8 :   parameter[U_SC1].push_back(5.95100000);
+    1252           8 :   parameter[U_SC1].push_back(-0.02924500);
+    1253           8 :   parameter[U_SC1].push_back(2.59668700);
+    1254           8 :   parameter[U_SC1].push_back(-0.56118700);
+    1255           8 :   parameter[U_SC1].push_back(-1.56477100);
+    1256           8 :   parameter[U_SC1].push_back(0.89265100);
+    1257           8 :   parameter[U_SC1].push_back(-0.14130800);
+    1258             : 
+    1259           8 :   parameter[U_SC2].push_back(10.90100000);
+    1260           8 :   parameter[U_SC2].push_back(0.02178900);
+    1261           8 :   parameter[U_SC2].push_back(0.18839000);
+    1262           8 :   parameter[U_SC2].push_back(0.72223100);
+    1263           8 :   parameter[U_SC2].push_back(-1.92581600);
+    1264           8 :   parameter[U_SC2].push_back(0.96654300);
+    1265           8 :   parameter[U_SC2].push_back(-0.14501300);
+    1266             : 
+    1267           8 :   parameter[U_SC3].push_back(5.24600000);
+    1268           8 :   parameter[U_SC3].push_back(-0.04586500);
+    1269           8 :   parameter[U_SC3].push_back(5.89978100);
+    1270           8 :   parameter[U_SC3].push_back(-1.50664700);
+    1271           8 :   parameter[U_SC3].push_back(-3.17054400);
+    1272           8 :   parameter[U_SC3].push_back(1.93717100);
+    1273           8 :   parameter[U_SC3].push_back(-0.31701000);
+    1274             : 
+    1275           8 :   parameter[U_3TE].push_back(4.23000000);
+    1276           8 :   parameter[U_3TE].push_back(0.00067500);
+    1277           8 :   parameter[U_3TE].push_back(0.92102300);
+    1278           8 :   parameter[U_3TE].push_back(0.08100800);
+    1279           8 :   parameter[U_3TE].push_back(-0.39084300);
+    1280           8 :   parameter[U_3TE].push_back(0.12441900);
+    1281           8 :   parameter[U_3TE].push_back(-0.01124900);
+    1282             : 
+    1283           8 :   parameter[U_5TE].push_back(4.23000000);
+    1284           8 :   parameter[U_5TE].push_back(0.00059000);
+    1285           8 :   parameter[U_5TE].push_back(0.92154600);
+    1286           8 :   parameter[U_5TE].push_back(0.07968200);
+    1287           8 :   parameter[U_5TE].push_back(-0.38950100);
+    1288           8 :   parameter[U_5TE].push_back(0.12382500);
+    1289           8 :   parameter[U_5TE].push_back(-0.01115100);
+    1290             : 
+    1291           8 :   parameter[U_TE3].push_back(7.82400000);
+    1292           8 :   parameter[U_TE3].push_back(-0.02968100);
+    1293           8 :   parameter[U_TE3].push_back(7.93783200);
+    1294           8 :   parameter[U_TE3].push_back(-0.33078100);
+    1295           8 :   parameter[U_TE3].push_back(-10.14120200);
+    1296           8 :   parameter[U_TE3].push_back(6.63334700);
+    1297           8 :   parameter[U_TE3].push_back(-1.22111200);
+    1298             : 
+    1299           8 :   parameter[U_TE5].push_back(8.03600000);
+    1300           8 :   parameter[U_TE5].push_back(-0.00909700);
+    1301           8 :   parameter[U_TE5].push_back(4.33193500);
+    1302           8 :   parameter[U_TE5].push_back(0.43416500);
+    1303           8 :   parameter[U_TE5].push_back(-5.80831400);
+    1304           8 :   parameter[U_TE5].push_back(3.52438800);
+    1305           8 :   parameter[U_TE5].push_back(-0.62382400);
+    1306             : 
+    1307           8 :   parameter[DA_BB1].push_back(32.88500000);
+    1308           8 :   parameter[DA_BB1].push_back(0.08179900);
+    1309           8 :   parameter[DA_BB1].push_back(-7.31735900);
+    1310           8 :   parameter[DA_BB1].push_back(2.15614500);
+    1311           8 :   parameter[DA_BB1].push_back(-3.52263200);
+    1312           8 :   parameter[DA_BB1].push_back(2.30604700);
+    1313           8 :   parameter[DA_BB1].push_back(-0.39270100);
+    1314             : 
+    1315           8 :   parameter[DA_BB2].push_back(3.80600000);
+    1316           8 :   parameter[DA_BB2].push_back(-0.10597700);
+    1317           8 :   parameter[DA_BB2].push_back(9.52537500);
+    1318           8 :   parameter[DA_BB2].push_back(-6.12991000);
+    1319           8 :   parameter[DA_BB2].push_back(-0.54092600);
+    1320           8 :   parameter[DA_BB2].push_back(1.15429100);
+    1321           8 :   parameter[DA_BB2].push_back(-0.21503500);
+    1322             : 
+    1323           8 :   parameter[DA_BB3].push_back(-1.35600000);
+    1324           8 :   parameter[DA_BB3].push_back(0.58928300);
+    1325           8 :   parameter[DA_BB3].push_back(6.71894100);
+    1326           8 :   parameter[DA_BB3].push_back(4.14050900);
+    1327           8 :   parameter[DA_BB3].push_back(-9.65859900);
+    1328           8 :   parameter[DA_BB3].push_back(4.43185000);
+    1329           8 :   parameter[DA_BB3].push_back(-0.64657300);
+    1330             : 
+    1331           8 :   parameter[DA_SC1].push_back(6.67100000);
+    1332           8 :   parameter[DA_SC1].push_back(-0.00871400);
+    1333           8 :   parameter[DA_SC1].push_back(1.63289100);
+    1334           8 :   parameter[DA_SC1].push_back(-0.06637700);
+    1335           8 :   parameter[DA_SC1].push_back(-1.48632900);
+    1336           8 :   parameter[DA_SC1].push_back(0.78551800);
+    1337           8 :   parameter[DA_SC1].push_back(-0.12087300);
+    1338             : 
+    1339           8 :   parameter[DA_SC2].push_back(5.95100000);
+    1340           8 :   parameter[DA_SC2].push_back(-0.02634300);
+    1341           8 :   parameter[DA_SC2].push_back(2.54864300);
+    1342           8 :   parameter[DA_SC2].push_back(-0.49015800);
+    1343           8 :   parameter[DA_SC2].push_back(-1.55386900);
+    1344           8 :   parameter[DA_SC2].push_back(0.86630200);
+    1345           8 :   parameter[DA_SC2].push_back(-0.13546200);
+    1346             : 
+    1347           8 :   parameter[DA_SC3].push_back(11.39400000);
+    1348           8 :   parameter[DA_SC3].push_back(0.00859500);
+    1349           8 :   parameter[DA_SC3].push_back(-0.25471400);
+    1350           8 :   parameter[DA_SC3].push_back(0.48718800);
+    1351           8 :   parameter[DA_SC3].push_back(-1.74520000);
+    1352           8 :   parameter[DA_SC3].push_back(0.99246200);
+    1353           8 :   parameter[DA_SC3].push_back(-0.16351900);
+    1354             : 
+    1355           8 :   parameter[DA_SC4].push_back(6.45900000);
+    1356           8 :   parameter[DA_SC4].push_back(0.01991800);
+    1357           8 :   parameter[DA_SC4].push_back(4.17962300);
+    1358           8 :   parameter[DA_SC4].push_back(0.97469100);
+    1359           8 :   parameter[DA_SC4].push_back(-5.02950400);
+    1360           8 :   parameter[DA_SC4].push_back(2.55371800);
+    1361           8 :   parameter[DA_SC4].push_back(-0.39113400);
+    1362             : 
+    1363           8 :   parameter[DA_3TE].push_back(4.23000000);
+    1364           8 :   parameter[DA_3TE].push_back(0.00062600);
+    1365           8 :   parameter[DA_3TE].push_back(0.92142000);
+    1366           8 :   parameter[DA_3TE].push_back(0.08016400);
+    1367           8 :   parameter[DA_3TE].push_back(-0.39000300);
+    1368           8 :   parameter[DA_3TE].push_back(0.12402500);
+    1369           8 :   parameter[DA_3TE].push_back(-0.01117900);
+    1370             : 
+    1371           8 :   parameter[DA_5TE].push_back(4.23000000);
+    1372           8 :   parameter[DA_5TE].push_back(0.00055500);
+    1373           8 :   parameter[DA_5TE].push_back(0.92183900);
+    1374           8 :   parameter[DA_5TE].push_back(0.07907600);
+    1375           8 :   parameter[DA_5TE].push_back(-0.38895100);
+    1376           8 :   parameter[DA_5TE].push_back(0.12359600);
+    1377           8 :   parameter[DA_5TE].push_back(-0.01111600);
+    1378             : 
+    1379           8 :   parameter[DA_TE3].push_back(2.87400000);
+    1380           8 :   parameter[DA_TE3].push_back(0.00112900);
+    1381           8 :   parameter[DA_TE3].push_back(12.51167200);
+    1382           8 :   parameter[DA_TE3].push_back(-7.67548000);
+    1383           8 :   parameter[DA_TE3].push_back(-2.02234000);
+    1384           8 :   parameter[DA_TE3].push_back(2.50837100);
+    1385           8 :   parameter[DA_TE3].push_back(-0.49458500);
+    1386             : 
+    1387           8 :   parameter[DA_TE5].push_back(8.03600000);
+    1388           8 :   parameter[DA_TE5].push_back(0.00473100);
+    1389           8 :   parameter[DA_TE5].push_back(4.65554400);
+    1390           8 :   parameter[DA_TE5].push_back(0.66424100);
+    1391           8 :   parameter[DA_TE5].push_back(-6.62131300);
+    1392           8 :   parameter[DA_TE5].push_back(3.96107400);
+    1393           8 :   parameter[DA_TE5].push_back(-0.69075800);
+    1394             : 
+    1395           8 :   parameter[DC_BB1].push_back(32.88500000);
+    1396           8 :   parameter[DC_BB1].push_back(0.08189900);
+    1397           8 :   parameter[DC_BB1].push_back(-7.32493500);
+    1398           8 :   parameter[DC_BB1].push_back(2.15976900);
+    1399           8 :   parameter[DC_BB1].push_back(-3.52612100);
+    1400           8 :   parameter[DC_BB1].push_back(2.31058600);
+    1401           8 :   parameter[DC_BB1].push_back(-0.39402700);
+    1402             : 
+    1403           8 :   parameter[DC_BB2].push_back(3.80600000);
+    1404           8 :   parameter[DC_BB2].push_back(-0.10559800);
+    1405           8 :   parameter[DC_BB2].push_back(9.52527700);
+    1406           8 :   parameter[DC_BB2].push_back(-6.12131700);
+    1407           8 :   parameter[DC_BB2].push_back(-0.54899400);
+    1408           8 :   parameter[DC_BB2].push_back(1.15592900);
+    1409           8 :   parameter[DC_BB2].push_back(-0.21494500);
+    1410             : 
+    1411           8 :   parameter[DC_BB3].push_back(-1.35600000);
+    1412           8 :   parameter[DC_BB3].push_back(0.55525700);
+    1413           8 :   parameter[DC_BB3].push_back(6.80305500);
+    1414           8 :   parameter[DC_BB3].push_back(4.05924700);
+    1415           8 :   parameter[DC_BB3].push_back(-9.61034700);
+    1416           8 :   parameter[DC_BB3].push_back(4.41253800);
+    1417           8 :   parameter[DC_BB3].push_back(-0.64315100);
+    1418             : 
+    1419           8 :   parameter[DC_SC1].push_back(5.95100000);
+    1420           8 :   parameter[DC_SC1].push_back(-0.02899900);
+    1421           8 :   parameter[DC_SC1].push_back(2.59587800);
+    1422           8 :   parameter[DC_SC1].push_back(-0.55388300);
+    1423           8 :   parameter[DC_SC1].push_back(-1.56395100);
+    1424           8 :   parameter[DC_SC1].push_back(0.88967400);
+    1425           8 :   parameter[DC_SC1].push_back(-0.14062500);
+    1426             : 
+    1427           8 :   parameter[DC_SC2].push_back(11.62100000);
+    1428           8 :   parameter[DC_SC2].push_back(0.01358100);
+    1429           8 :   parameter[DC_SC2].push_back(-0.24913000);
+    1430           8 :   parameter[DC_SC2].push_back(0.48787200);
+    1431           8 :   parameter[DC_SC2].push_back(-1.52867300);
+    1432           8 :   parameter[DC_SC2].push_back(0.83694900);
+    1433           8 :   parameter[DC_SC2].push_back(-0.13395300);
+    1434             : 
+    1435           8 :   parameter[DC_SC3].push_back(5.01900000);
+    1436           8 :   parameter[DC_SC3].push_back(-0.03298400);
+    1437           8 :   parameter[DC_SC3].push_back(5.54242800);
+    1438           8 :   parameter[DC_SC3].push_back(-0.96081500);
+    1439           8 :   parameter[DC_SC3].push_back(-3.71051600);
+    1440           8 :   parameter[DC_SC3].push_back(2.16500200);
+    1441           8 :   parameter[DC_SC3].push_back(-0.35023400);
+    1442             : 
+    1443           8 :   parameter[DC_3TE].push_back(4.23000000);
+    1444           8 :   parameter[DC_3TE].push_back(0.00055700);
+    1445           8 :   parameter[DC_3TE].push_back(0.92181400);
+    1446           8 :   parameter[DC_3TE].push_back(0.07924000);
+    1447           8 :   parameter[DC_3TE].push_back(-0.38916400);
+    1448           8 :   parameter[DC_3TE].push_back(0.12369900);
+    1449           8 :   parameter[DC_3TE].push_back(-0.01113300);
+    1450             : 
+    1451           8 :   parameter[DC_5TE].push_back(4.23000000);
+    1452           8 :   parameter[DC_5TE].push_back(0.00066500);
+    1453           8 :   parameter[DC_5TE].push_back(0.92103900);
+    1454           8 :   parameter[DC_5TE].push_back(0.08064600);
+    1455           8 :   parameter[DC_5TE].push_back(-0.39034900);
+    1456           8 :   parameter[DC_5TE].push_back(0.12417600);
+    1457           8 :   parameter[DC_5TE].push_back(-0.01120600);
+    1458             : 
+    1459           8 :   parameter[DC_TE3].push_back(2.87400000);
+    1460           8 :   parameter[DC_TE3].push_back(-0.05235500);
+    1461           8 :   parameter[DC_TE3].push_back(13.09201200);
+    1462           8 :   parameter[DC_TE3].push_back(-9.48128200);
+    1463           8 :   parameter[DC_TE3].push_back(-0.14958600);
+    1464           8 :   parameter[DC_TE3].push_back(1.75537200);
+    1465           8 :   parameter[DC_TE3].push_back(-0.39347500);
+    1466             : 
+    1467           8 :   parameter[DC_TE5].push_back(8.03600000);
+    1468           8 :   parameter[DC_TE5].push_back(-0.00513600);
+    1469           8 :   parameter[DC_TE5].push_back(4.67705700);
+    1470           8 :   parameter[DC_TE5].push_back(0.48333300);
+    1471           8 :   parameter[DC_TE5].push_back(-6.34511000);
+    1472           8 :   parameter[DC_TE5].push_back(3.83388500);
+    1473           8 :   parameter[DC_TE5].push_back(-0.67367800);
+    1474             : 
+    1475           8 :   parameter[DG_BB1].push_back(32.88500000);
+    1476           8 :   parameter[DG_BB1].push_back(0.08182900);
+    1477           8 :   parameter[DG_BB1].push_back(-7.32133900);
+    1478           8 :   parameter[DG_BB1].push_back(2.15767900);
+    1479           8 :   parameter[DG_BB1].push_back(-3.52369700);
+    1480           8 :   parameter[DG_BB1].push_back(2.30839600);
+    1481           8 :   parameter[DG_BB1].push_back(-0.39348300);
+    1482             : 
+    1483           8 :   parameter[DG_BB2].push_back(3.80600000);
+    1484           8 :   parameter[DG_BB2].push_back(-0.10618100);
+    1485           8 :   parameter[DG_BB2].push_back(9.54169000);
+    1486           8 :   parameter[DG_BB2].push_back(-6.15177600);
+    1487           8 :   parameter[DG_BB2].push_back(-0.53462400);
+    1488           8 :   parameter[DG_BB2].push_back(1.15581300);
+    1489           8 :   parameter[DG_BB2].push_back(-0.21567000);
+    1490             : 
+    1491           8 :   parameter[DG_BB3].push_back(-1.35600000);
+    1492           8 :   parameter[DG_BB3].push_back(0.57489100);
+    1493           8 :   parameter[DG_BB3].push_back(6.75164700);
+    1494           8 :   parameter[DG_BB3].push_back(4.11300900);
+    1495           8 :   parameter[DG_BB3].push_back(-9.63394600);
+    1496           8 :   parameter[DG_BB3].push_back(4.41675400);
+    1497           8 :   parameter[DG_BB3].push_back(-0.64339900);
+    1498             : 
+    1499           8 :   parameter[DG_SC1].push_back(6.67100000);
+    1500           8 :   parameter[DG_SC1].push_back(-0.00886600);
+    1501           8 :   parameter[DG_SC1].push_back(1.63333000);
+    1502           8 :   parameter[DG_SC1].push_back(-0.06892100);
+    1503           8 :   parameter[DG_SC1].push_back(-1.48683500);
+    1504           8 :   parameter[DG_SC1].push_back(0.78670800);
+    1505           8 :   parameter[DG_SC1].push_back(-0.12113900);
+    1506             : 
+    1507           8 :   parameter[DG_SC2].push_back(11.39400000);
+    1508           8 :   parameter[DG_SC2].push_back(0.00907900);
+    1509           8 :   parameter[DG_SC2].push_back(-0.22475500);
+    1510           8 :   parameter[DG_SC2].push_back(0.49535100);
+    1511           8 :   parameter[DG_SC2].push_back(-1.75324900);
+    1512           8 :   parameter[DG_SC2].push_back(0.98767400);
+    1513           8 :   parameter[DG_SC2].push_back(-0.16150800);
+    1514             : 
+    1515           8 :   parameter[DG_SC3].push_back(10.90100000);
+    1516           8 :   parameter[DG_SC3].push_back(0.02207600);
+    1517           8 :   parameter[DG_SC3].push_back(0.17932200);
+    1518           8 :   parameter[DG_SC3].push_back(0.73253200);
+    1519           8 :   parameter[DG_SC3].push_back(-1.95554900);
+    1520           8 :   parameter[DG_SC3].push_back(0.98339900);
+    1521           8 :   parameter[DG_SC3].push_back(-0.14763600);
+    1522             : 
+    1523           8 :   parameter[DG_SC4].push_back(6.45900000);
+    1524           8 :   parameter[DG_SC4].push_back(0.02018400);
+    1525           8 :   parameter[DG_SC4].push_back(4.17705400);
+    1526           8 :   parameter[DG_SC4].push_back(0.98531700);
+    1527           8 :   parameter[DG_SC4].push_back(-5.04354900);
+    1528           8 :   parameter[DG_SC4].push_back(2.56123700);
+    1529           8 :   parameter[DG_SC4].push_back(-0.39249300);
+    1530             : 
+    1531           8 :   parameter[DG_3TE].push_back(4.23000000);
+    1532           8 :   parameter[DG_3TE].push_back(0.00061700);
+    1533           8 :   parameter[DG_3TE].push_back(0.92140100);
+    1534           8 :   parameter[DG_3TE].push_back(0.08016400);
+    1535           8 :   parameter[DG_3TE].push_back(-0.39003500);
+    1536           8 :   parameter[DG_3TE].push_back(0.12406900);
+    1537           8 :   parameter[DG_3TE].push_back(-0.01119200);
+    1538             : 
+    1539           8 :   parameter[DG_5TE].push_back(4.23000000);
+    1540           8 :   parameter[DG_5TE].push_back(0.00064900);
+    1541           8 :   parameter[DG_5TE].push_back(0.92110500);
+    1542           8 :   parameter[DG_5TE].push_back(0.08031500);
+    1543           8 :   parameter[DG_5TE].push_back(-0.38997000);
+    1544           8 :   parameter[DG_5TE].push_back(0.12401200);
+    1545           8 :   parameter[DG_5TE].push_back(-0.01118100);
+    1546             : 
+    1547           8 :   parameter[DG_TE3].push_back(2.87400000);
+    1548           8 :   parameter[DG_TE3].push_back(0.00182000);
+    1549           8 :   parameter[DG_TE3].push_back(12.41507000);
+    1550           8 :   parameter[DG_TE3].push_back(-7.47384800);
+    1551           8 :   parameter[DG_TE3].push_back(-2.11864700);
+    1552           8 :   parameter[DG_TE3].push_back(2.50112600);
+    1553           8 :   parameter[DG_TE3].push_back(-0.48652200);
+    1554             : 
+    1555           8 :   parameter[DG_TE5].push_back(8.03600000);
+    1556           8 :   parameter[DG_TE5].push_back(0.00676400);
+    1557           8 :   parameter[DG_TE5].push_back(4.65989200);
+    1558           8 :   parameter[DG_TE5].push_back(0.78482500);
+    1559           8 :   parameter[DG_TE5].push_back(-6.86460600);
+    1560           8 :   parameter[DG_TE5].push_back(4.11675400);
+    1561           8 :   parameter[DG_TE5].push_back(-0.72249100);
+    1562             : 
+    1563           8 :   parameter[DT_BB1].push_back(32.88500000);
+    1564           8 :   parameter[DT_BB1].push_back(0.08220100);
+    1565           8 :   parameter[DT_BB1].push_back(-7.33006800);
+    1566           8 :   parameter[DT_BB1].push_back(2.16636500);
+    1567           8 :   parameter[DT_BB1].push_back(-3.53465700);
+    1568           8 :   parameter[DT_BB1].push_back(2.31447600);
+    1569           8 :   parameter[DT_BB1].push_back(-0.39445400);
+    1570             : 
+    1571           8 :   parameter[DT_BB2].push_back(3.80600000);
+    1572           8 :   parameter[DT_BB2].push_back(-0.10723000);
+    1573           8 :   parameter[DT_BB2].push_back(9.56675000);
+    1574           8 :   parameter[DT_BB2].push_back(-6.20236100);
+    1575           8 :   parameter[DT_BB2].push_back(-0.49550400);
+    1576           8 :   parameter[DT_BB2].push_back(1.14300600);
+    1577           8 :   parameter[DT_BB2].push_back(-0.21420000);
+    1578             : 
+    1579           8 :   parameter[DT_BB3].push_back(-1.35600000);
+    1580           8 :   parameter[DT_BB3].push_back(0.56737900);
+    1581           8 :   parameter[DT_BB3].push_back(6.76595400);
+    1582           8 :   parameter[DT_BB3].push_back(4.08976100);
+    1583           8 :   parameter[DT_BB3].push_back(-9.61512500);
+    1584           8 :   parameter[DT_BB3].push_back(4.40975100);
+    1585           8 :   parameter[DT_BB3].push_back(-0.64239800);
+    1586             : 
+    1587           8 :   parameter[DT_SC1].push_back(5.95100000);
+    1588           8 :   parameter[DT_SC1].push_back(-0.02926500);
+    1589           8 :   parameter[DT_SC1].push_back(2.59630300);
+    1590           8 :   parameter[DT_SC1].push_back(-0.56152200);
+    1591           8 :   parameter[DT_SC1].push_back(-1.56532600);
+    1592           8 :   parameter[DT_SC1].push_back(0.89322800);
+    1593           8 :   parameter[DT_SC1].push_back(-0.14142900);
+    1594             : 
+    1595           8 :   parameter[DT_SC2].push_back(10.90100000);
+    1596           8 :   parameter[DT_SC2].push_back(0.02183400);
+    1597           8 :   parameter[DT_SC2].push_back(0.19463000);
+    1598           8 :   parameter[DT_SC2].push_back(0.72393000);
+    1599           8 :   parameter[DT_SC2].push_back(-1.93199500);
+    1600           8 :   parameter[DT_SC2].push_back(0.96856300);
+    1601           8 :   parameter[DT_SC2].push_back(-0.14512600);
+    1602             : 
+    1603           8 :   parameter[DT_SC3].push_back(4.31400000);
+    1604           8 :   parameter[DT_SC3].push_back(-0.07745600);
+    1605           8 :   parameter[DT_SC3].push_back(12.49820300);
+    1606           8 :   parameter[DT_SC3].push_back(-7.64994200);
+    1607           8 :   parameter[DT_SC3].push_back(-3.00359600);
+    1608           8 :   parameter[DT_SC3].push_back(3.26263300);
+    1609           8 :   parameter[DT_SC3].push_back(-0.64498600);
+    1610             : 
+    1611           8 :   parameter[DT_3TE].push_back(4.23000000);
+    1612           8 :   parameter[DT_3TE].push_back(0.00062000);
+    1613           8 :   parameter[DT_3TE].push_back(0.92141100);
+    1614           8 :   parameter[DT_3TE].push_back(0.08030900);
+    1615           8 :   parameter[DT_3TE].push_back(-0.39021500);
+    1616           8 :   parameter[DT_3TE].push_back(0.12414000);
+    1617           8 :   parameter[DT_3TE].push_back(-0.01120100);
+    1618             : 
+    1619           8 :   parameter[DT_5TE].push_back(4.23000000);
+    1620           8 :   parameter[DT_5TE].push_back(0.00063700);
+    1621           8 :   parameter[DT_5TE].push_back(0.92130800);
+    1622           8 :   parameter[DT_5TE].push_back(0.08026900);
+    1623           8 :   parameter[DT_5TE].push_back(-0.39007500);
+    1624           8 :   parameter[DT_5TE].push_back(0.12406600);
+    1625           8 :   parameter[DT_5TE].push_back(-0.01118800);
+    1626             : 
+    1627           8 :   parameter[DT_TE3].push_back(2.87400000);
+    1628           8 :   parameter[DT_TE3].push_back(-0.00251200);
+    1629           8 :   parameter[DT_TE3].push_back(12.43576400);
+    1630           8 :   parameter[DT_TE3].push_back(-7.55343800);
+    1631           8 :   parameter[DT_TE3].push_back(-2.07363500);
+    1632           8 :   parameter[DT_TE3].push_back(2.51279300);
+    1633           8 :   parameter[DT_TE3].push_back(-0.49437100);
+    1634             : 
+    1635           8 :   parameter[DT_TE5].push_back(8.03600000);
+    1636           8 :   parameter[DT_TE5].push_back(0.00119900);
+    1637           8 :   parameter[DT_TE5].push_back(4.91762300);
+    1638           8 :   parameter[DT_TE5].push_back(0.65637000);
+    1639           8 :   parameter[DT_TE5].push_back(-7.23392500);
+    1640           8 :   parameter[DT_TE5].push_back(4.44636600);
+    1641           8 :   parameter[DT_TE5].push_back(-0.79467800);
+    1642             : 
+    1643           8 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    1644           8 :   if( moldat ) {
+    1645           8 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+    1646        8400 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    1647        8392 :       std::string Aname = moldat->getAtomName(atoms[i]);
+    1648        8392 :       std::string Rname = moldat->getResidueName(atoms[i]);
+    1649        8392 :       if(Rname=="ALA") {
+    1650          72 :         if(Aname=="BB") {
+    1651          72 :           atoi[i]=ALA_BB;
+    1652           0 :         } else error("Atom name not known: "+Aname);
+    1653        8320 :       } else if(Rname=="ARG") {
+    1654         420 :         if(Aname=="BB") {
+    1655         140 :           atoi[i]=ARG_BB;
+    1656         280 :         } else if(Aname=="SC1") {
+    1657         140 :           atoi[i]=ARG_SC1;
+    1658         140 :         } else if(Aname=="SC2") {
+    1659         140 :           atoi[i]=ARG_SC2;
+    1660           0 :         } else error("Atom name not known: "+Aname);
+    1661        7900 :       } else if(Rname=="ASN") {
+    1662         240 :         if(Aname=="BB") {
+    1663         120 :           atoi[i]=ASN_BB;
+    1664         120 :         } else if(Aname=="SC1") {
+    1665         120 :           atoi[i]=ASN_SC1;
+    1666           0 :         } else error("Atom name not known: "+Aname);
+    1667        7660 :       } else if(Rname=="ASP") {
+    1668         368 :         if(Aname=="BB") {
+    1669         184 :           atoi[i]=ASP_BB;
+    1670         184 :         } else if(Aname=="SC1") {
+    1671         184 :           atoi[i]=ASP_SC1;
+    1672           0 :         } else error("Atom name not known: "+Aname);
+    1673        7292 :       } else if(Rname=="CYS") {
+    1674          16 :         if(Aname=="BB") {
+    1675           8 :           atoi[i]=CYS_BB;
+    1676           8 :         } else if(Aname=="SC1") {
+    1677           8 :           atoi[i]=CYS_SC1;
+    1678           0 :         } else error("Atom name not known: "+Aname);
+    1679        7276 :       } else if(Rname=="GLN") {
+    1680         224 :         if(Aname=="BB") {
+    1681         112 :           atoi[i]=GLN_BB;
+    1682         112 :         } else if(Aname=="SC1") {
+    1683         112 :           atoi[i]=GLN_SC1;
+    1684           0 :         } else error("Atom name not known: "+Aname);
+    1685        7052 :       } else if(Rname=="GLU") {
+    1686         480 :         if(Aname=="BB") {
+    1687         240 :           atoi[i]=GLU_BB;
+    1688         240 :         } else if(Aname=="SC1") {
+    1689         240 :           atoi[i]=GLU_SC1;
+    1690           0 :         } else error("Atom name not known: "+Aname);
+    1691        6572 :       } else if(Rname=="GLY") {
+    1692         116 :         if(Aname=="BB") {
+    1693         116 :           atoi[i]=GLY_BB;
+    1694           0 :         } else error("Atom name not known: "+Aname);
+    1695        6456 :       } else if(Rname=="HIS") {
+    1696         576 :         if(Aname=="BB") {
+    1697         144 :           atoi[i]=HIS_BB;
+    1698         432 :         } else if(Aname=="SC1") {
+    1699         144 :           atoi[i]=HIS_SC1;
+    1700         288 :         } else if(Aname=="SC2") {
+    1701         144 :           atoi[i]=HIS_SC2;
+    1702         144 :         } else if(Aname=="SC3") {
+    1703         144 :           atoi[i]=HIS_SC3;
+    1704           0 :         } else error("Atom name not known: "+Aname);
+    1705        5880 :       } else if(Rname=="ILE") {
+    1706         584 :         if(Aname=="BB") {
+    1707         292 :           atoi[i]=ILE_BB;
+    1708         292 :         } else if(Aname=="SC1") {
+    1709         292 :           atoi[i]=ILE_SC1;
+    1710           0 :         } else error("Atom name not known: "+Aname);
+    1711        5296 :       } else if(Rname=="LEU") {
+    1712         448 :         if(Aname=="BB") {
+    1713         224 :           atoi[i]=LEU_BB;
+    1714         224 :         } else if(Aname=="SC1") {
+    1715         224 :           atoi[i]=LEU_SC1;
+    1716           0 :         } else error("Atom name not known: "+Aname);
+    1717        4848 :       } else if(Rname=="LYS") {
+    1718         792 :         if(Aname=="BB") {
+    1719         264 :           atoi[i]=LYS_BB;
+    1720         528 :         } else if(Aname=="SC1") {
+    1721         264 :           atoi[i]=LYS_SC1;
+    1722         264 :         } else if(Aname=="SC2") {
+    1723         264 :           atoi[i]=LYS_SC2;
+    1724           0 :         } else error("Atom name not known: "+Aname);
+    1725        4056 :       } else if(Rname=="MET") {
+    1726          80 :         if(Aname=="BB") {
+    1727          40 :           atoi[i]=MET_BB;
+    1728          40 :         } else if(Aname=="SC1") {
+    1729          40 :           atoi[i]=MET_SC1;
+    1730           0 :         } else error("Atom name not known: "+Aname);
+    1731        3976 :       } else if(Rname=="PHE") {
+    1732         512 :         if(Aname=="BB") {
+    1733         128 :           atoi[i]=PHE_BB;
+    1734         384 :         } else if(Aname=="SC1") {
+    1735         128 :           atoi[i]=PHE_SC1;
+    1736         256 :         } else if(Aname=="SC2") {
+    1737         128 :           atoi[i]=PHE_SC2;
+    1738         128 :         } else if(Aname=="SC3") {
+    1739         128 :           atoi[i]=PHE_SC3;
+    1740           0 :         } else error("Atom name not known: "+Aname);
+    1741        3464 :       } else if(Rname=="PRO") {
+    1742         128 :         if(Aname=="BB") {
+    1743          64 :           atoi[i]=PRO_BB;
+    1744          64 :         } else if(Aname=="SC1") {
+    1745          64 :           atoi[i]=PRO_SC1;
+    1746           0 :         } else error("Atom name not known: "+Aname);
+    1747        3336 :       } else if(Rname=="SER") {
+    1748         248 :         if(Aname=="BB") {
+    1749         124 :           atoi[i]=SER_BB;
+    1750         124 :         } else if(Aname=="SC1") {
+    1751         124 :           atoi[i]=SER_SC1;
+    1752           0 :         } else error("Atom name not known: "+Aname);
+    1753        3088 :       } else if(Rname=="THR") {
+    1754         288 :         if(Aname=="BB") {
+    1755         144 :           atoi[i]=THR_BB;
+    1756         144 :         } else if(Aname=="SC1") {
+    1757         144 :           atoi[i]=THR_SC1;
+    1758           0 :         } else error("Atom name not known: "+Aname);
+    1759        2800 :       } else if(Rname=="TRP") {
+    1760           0 :         if(Aname=="BB") {
+    1761           0 :           atoi[i]=TRP_BB;
+    1762           0 :         } else if(Aname=="SC1") {
+    1763           0 :           atoi[i]=TRP_SC1;
+    1764           0 :         } else if(Aname=="SC2") {
+    1765           0 :           atoi[i]=TRP_SC2;
+    1766           0 :         } else if(Aname=="SC3") {
+    1767           0 :           atoi[i]=TRP_SC3;
+    1768           0 :         } else if(Aname=="SC4") {
+    1769           0 :           atoi[i]=TRP_SC4;
+    1770           0 :         } else error("Atom name not known: "+Aname);
+    1771        2800 :       } else if(Rname=="TYR") {
+    1772         544 :         if(Aname=="BB") {
+    1773         136 :           atoi[i]=TYR_BB;
+    1774         408 :         } else if(Aname=="SC1") {
+    1775         136 :           atoi[i]=TYR_SC1;
+    1776         272 :         } else if(Aname=="SC2") {
+    1777         136 :           atoi[i]=TYR_SC2;
+    1778         136 :         } else if(Aname=="SC3") {
+    1779         136 :           atoi[i]=TYR_SC3;
+    1780           0 :         } else error("Atom name not known: "+Aname);
+    1781        2256 :       } else if(Rname=="VAL") {
+    1782         288 :         if(Aname=="BB") {
+    1783         144 :           atoi[i]=VAL_BB;
+    1784         144 :         } else if(Aname=="SC1") {
+    1785         144 :           atoi[i]=VAL_SC1;
+    1786           0 :         } else error("Atom name not known: "+Aname);
+    1787        1968 :       } else if(Rname=="  A") {
+    1788           0 :         if(Aname=="BB1") {
+    1789           0 :           atoi[i]=A_BB1;
+    1790           0 :         } else if(Aname=="BB2") {
+    1791           0 :           atoi[i]=A_BB2;
+    1792           0 :         } else if(Aname=="BB3") {
+    1793           0 :           atoi[i]=A_BB3;
+    1794           0 :         } else if(Aname=="SC1") {
+    1795           0 :           atoi[i]=A_SC1;
+    1796           0 :         } else if(Aname=="SC2") {
+    1797           0 :           atoi[i]=A_SC2;
+    1798           0 :         } else if(Aname=="SC3") {
+    1799           0 :           atoi[i]=A_SC3;
+    1800           0 :         } else if(Aname=="SC4") {
+    1801           0 :           atoi[i]=A_SC4;
+    1802           0 :         } else if(Aname=="3TE") {
+    1803           0 :           atoi[i]=A_3TE;
+    1804           0 :         } else if(Aname=="5TE") {
+    1805           0 :           atoi[i]=A_5TE;
+    1806           0 :         } else if(Aname=="TE3") {
+    1807           0 :           atoi[i]=A_TE3;
+    1808           0 :         } else if(Aname=="TE5") {
+    1809           0 :           atoi[i]=A_TE5;
+    1810           0 :         } else error("Atom name not known: "+Aname);
+    1811        1968 :       } else if(Rname=="  C") {
+    1812           0 :         if(Aname=="BB1") {
+    1813           0 :           atoi[i]=C_BB1;
+    1814           0 :         } else if(Aname=="BB2") {
+    1815           0 :           atoi[i]=C_BB2;
+    1816           0 :         } else if(Aname=="BB3") {
+    1817           0 :           atoi[i]=C_BB3;
+    1818           0 :         } else if(Aname=="SC1") {
+    1819           0 :           atoi[i]=C_SC1;
+    1820           0 :         } else if(Aname=="SC2") {
+    1821           0 :           atoi[i]=C_SC2;
+    1822           0 :         } else if(Aname=="SC3") {
+    1823           0 :           atoi[i]=C_SC3;
+    1824           0 :         } else if(Aname=="3TE") {
+    1825           0 :           atoi[i]=C_3TE;
+    1826           0 :         } else if(Aname=="5TE") {
+    1827           0 :           atoi[i]=C_5TE;
+    1828           0 :         } else if(Aname=="TE3") {
+    1829           0 :           atoi[i]=C_TE3;
+    1830           0 :         } else if(Aname=="TE5") {
+    1831           0 :           atoi[i]=C_TE5;
+    1832           0 :         } else error("Atom name not known: "+Aname);
+    1833        1968 :       } else if(Rname=="  G") {
+    1834           0 :         if(Aname=="BB1") {
+    1835           0 :           atoi[i]=G_BB1;
+    1836           0 :         } else if(Aname=="BB2") {
+    1837           0 :           atoi[i]=G_BB2;
+    1838           0 :         } else if(Aname=="BB3") {
+    1839           0 :           atoi[i]=G_BB3;
+    1840           0 :         } else if(Aname=="SC1") {
+    1841           0 :           atoi[i]=G_SC1;
+    1842           0 :         } else if(Aname=="SC2") {
+    1843           0 :           atoi[i]=G_SC2;
+    1844           0 :         } else if(Aname=="SC3") {
+    1845           0 :           atoi[i]=G_SC3;
+    1846           0 :         } else if(Aname=="SC4") {
+    1847           0 :           atoi[i]=G_SC4;
+    1848           0 :         } else if(Aname=="3TE") {
+    1849           0 :           atoi[i]=G_3TE;
+    1850           0 :         } else if(Aname=="5TE") {
+    1851           0 :           atoi[i]=G_5TE;
+    1852           0 :         } else if(Aname=="TE3") {
+    1853           0 :           atoi[i]=G_TE3;
+    1854           0 :         } else if(Aname=="TE5") {
+    1855           0 :           atoi[i]=G_TE5;
+    1856           0 :         } else error("Atom name not known: "+Aname);
+    1857        1968 :       } else if(Rname=="  U") {
+    1858           0 :         if(Aname=="BB1") {
+    1859           0 :           atoi[i]=U_BB1;
+    1860           0 :         } else if(Aname=="BB2") {
+    1861           0 :           atoi[i]=U_BB2;
+    1862           0 :         } else if(Aname=="BB3") {
+    1863           0 :           atoi[i]=U_BB3;
+    1864           0 :         } else if(Aname=="SC1") {
+    1865           0 :           atoi[i]=U_SC1;
+    1866           0 :         } else if(Aname=="SC2") {
+    1867           0 :           atoi[i]=U_SC2;
+    1868           0 :         } else if(Aname=="SC3") {
+    1869           0 :           atoi[i]=U_SC3;
+    1870           0 :         } else if(Aname=="3TE") {
+    1871           0 :           atoi[i]=U_3TE;
+    1872           0 :         } else if(Aname=="5TE") {
+    1873           0 :           atoi[i]=U_5TE;
+    1874           0 :         } else if(Aname=="TE3") {
+    1875           0 :           atoi[i]=U_TE3;
+    1876           0 :         } else if(Aname=="TE5") {
+    1877           0 :           atoi[i]=U_TE5;
+    1878           0 :         } else error("Atom name not known: "+Aname);
+    1879        1968 :       } else if(Rname==" DA") {
+    1880         696 :         if(Aname=="BB1") {
+    1881          96 :           atoi[i]=DA_BB1;
+    1882         600 :         } else if(Aname=="BB2") {
+    1883          96 :           atoi[i]=DA_BB2;
+    1884         504 :         } else if(Aname=="BB3") {
+    1885          96 :           atoi[i]=DA_BB3;
+    1886         408 :         } else if(Aname=="SC1") {
+    1887         100 :           atoi[i]=DA_SC1;
+    1888         308 :         } else if(Aname=="SC2") {
+    1889         100 :           atoi[i]=DA_SC2;
+    1890         208 :         } else if(Aname=="SC3") {
+    1891         100 :           atoi[i]=DA_SC3;
+    1892         108 :         } else if(Aname=="SC4") {
+    1893         100 :           atoi[i]=DA_SC4;
+    1894           8 :         } else if(Aname=="3TE") {
+    1895           0 :           atoi[i]=DA_3TE;
+    1896           8 :         } else if(Aname=="5TE") {
+    1897           0 :           atoi[i]=DA_5TE;
+    1898           8 :         } else if(Aname=="TE3") {
+    1899           4 :           atoi[i]=DA_TE3;
+    1900           4 :         } else if(Aname=="TE5") {
+    1901           4 :           atoi[i]=DA_TE5;
+    1902           0 :         } else error("Atom name not known: "+Aname);
+    1903        1272 :       } else if(Rname==" DC") {
+    1904         312 :         if(Aname=="BB1") {
+    1905          52 :           atoi[i]=DC_BB1;
+    1906         260 :         } else if(Aname=="BB2") {
+    1907          52 :           atoi[i]=DC_BB2;
+    1908         208 :         } else if(Aname=="BB3") {
+    1909          52 :           atoi[i]=DC_BB3;
+    1910         156 :         } else if(Aname=="SC1") {
+    1911          52 :           atoi[i]=DC_SC1;
+    1912         104 :         } else if(Aname=="SC2") {
+    1913          52 :           atoi[i]=DC_SC2;
+    1914          52 :         } else if(Aname=="SC3") {
+    1915          52 :           atoi[i]=DC_SC3;
+    1916           0 :         } else if(Aname=="3TE") {
+    1917           0 :           atoi[i]=DC_3TE;
+    1918           0 :         } else if(Aname=="5TE") {
+    1919           0 :           atoi[i]=DC_5TE;
+    1920           0 :         } else if(Aname=="TE3") {
+    1921           0 :           atoi[i]=DC_TE3;
+    1922           0 :         } else if(Aname=="TE5") {
+    1923           0 :           atoi[i]=DC_TE5;
+    1924           0 :         } else error("Atom name not known: "+Aname);
+    1925         960 :       } else if(Rname==" DG") {
+    1926         364 :         if(Aname=="BB1") {
+    1927          52 :           atoi[i]=DG_BB1;
+    1928         312 :         } else if(Aname=="BB2") {
+    1929          52 :           atoi[i]=DG_BB2;
+    1930         260 :         } else if(Aname=="BB3") {
+    1931          52 :           atoi[i]=DG_BB3;
+    1932         208 :         } else if(Aname=="SC1") {
+    1933          52 :           atoi[i]=DG_SC1;
+    1934         156 :         } else if(Aname=="SC2") {
+    1935          52 :           atoi[i]=DG_SC2;
+    1936         104 :         } else if(Aname=="SC3") {
+    1937          52 :           atoi[i]=DG_SC3;
+    1938          52 :         } else if(Aname=="SC4") {
+    1939          52 :           atoi[i]=DG_SC4;
+    1940           0 :         } else if(Aname=="3TE") {
+    1941           0 :           atoi[i]=DG_3TE;
+    1942           0 :         } else if(Aname=="5TE") {
+    1943           0 :           atoi[i]=DG_5TE;
+    1944           0 :         } else if(Aname=="TE3") {
+    1945           0 :           atoi[i]=DG_TE3;
+    1946           0 :         } else if(Aname=="TE5") {
+    1947           0 :           atoi[i]=DG_TE5;
+    1948           0 :         } else error("Atom name not known: "+Aname);
+    1949         596 :       } else if(Rname==" DT") {
+    1950         596 :         if(Aname=="BB1") {
+    1951          96 :           atoi[i]=DT_BB1;
+    1952         500 :         } else if(Aname=="BB2") {
+    1953          96 :           atoi[i]=DT_BB2;
+    1954         404 :         } else if(Aname=="BB3") {
+    1955          96 :           atoi[i]=DT_BB3;
+    1956         308 :         } else if(Aname=="SC1") {
+    1957         100 :           atoi[i]=DT_SC1;
+    1958         208 :         } else if(Aname=="SC2") {
+    1959         100 :           atoi[i]=DT_SC2;
+    1960         108 :         } else if(Aname=="SC3") {
+    1961         100 :           atoi[i]=DT_SC3;
+    1962           8 :         } else if(Aname=="3TE") {
+    1963           0 :           atoi[i]=DT_3TE;
+    1964           8 :         } else if(Aname=="5TE") {
+    1965           0 :           atoi[i]=DT_5TE;
+    1966           8 :         } else if(Aname=="TE3") {
+    1967           4 :           atoi[i]=DT_TE3;
+    1968           4 :         } else if(Aname=="TE5") {
+    1969           4 :           atoi[i]=DT_TE5;
+    1970           0 :         } else error("Atom name not known: "+Aname);
+    1971           0 :       } else error("Residue not known: "+Rname);
+    1972             :     }
+    1973             :   } else {
+    1974           0 :     error("MOLINFO DATA not found\n");
+    1975             :   }
+    1976           8 : }
+    1977             : 
+    1978           2 : double SAXS::calculateASF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho)
+    1979             : {
+    1980             :   std::map<std::string, unsigned> AA_map;
+    1981           2 :   AA_map["H"] = H;
+    1982           2 :   AA_map["C"] = C;
+    1983           2 :   AA_map["N"] = N;
+    1984           2 :   AA_map["O"] = O;
+    1985           2 :   AA_map["P"] = P;
+    1986           2 :   AA_map["S"] = S;
+    1987             : 
+    1988             :   std::vector<std::vector<double> > param_a;
+    1989             :   std::vector<std::vector<double> > param_b;
+    1990             :   std::vector<double> param_c;
+    1991             :   std::vector<double> param_v;
+    1992             : 
+    1993           2 :   param_a.resize(NTT, std::vector<double>(5));
+    1994           2 :   param_b.resize(NTT, std::vector<double>(5));
+    1995           2 :   param_c.resize(NTT);
+    1996           2 :   param_v.resize(NTT);
+    1997             : 
+    1998           2 :   param_a[H][0] = 0.493002; param_b[H][0] = 10.5109; param_c[H] = 0.003038;
+    1999           2 :   param_a[H][1] = 0.322912; param_b[H][1] = 26.1257; param_v[H] = 5.15;
+    2000           2 :   param_a[H][2] = 0.140191; param_b[H][2] = 3.14236;
+    2001           2 :   param_a[H][3] = 0.040810; param_b[H][3] = 57.7997;
+    2002           2 :   param_a[H][4] = 0.0;      param_b[H][4] = 1.0;
+    2003             : 
+    2004           2 :   param_a[C][0] = 2.31000; param_b[C][0] = 20.8439; param_c[C] = 0.215600;
+    2005           2 :   param_a[C][1] = 1.02000; param_b[C][1] = 10.2075; param_v[C] = 16.44;
+    2006           2 :   param_a[C][2] = 1.58860; param_b[C][2] = 0.56870;
+    2007           2 :   param_a[C][3] = 0.86500; param_b[C][3] = 51.6512;
+    2008           2 :   param_a[C][4] = 0.0;     param_b[C][4] = 1.0;
+    2009             : 
+    2010           2 :   param_a[N][0] = 12.2126; param_b[N][0] = 0.00570; param_c[N] = -11.529;
+    2011           2 :   param_a[N][1] = 3.13220; param_b[N][1] = 9.89330; param_v[N] = 2.49;
+    2012           2 :   param_a[N][2] = 2.01250; param_b[N][2] = 28.9975;
+    2013           2 :   param_a[N][3] = 1.16630; param_b[N][3] = 0.58260;
+    2014           2 :   param_a[N][4] = 0.0;     param_b[N][4] = 1.0;
+    2015             : 
+    2016           2 :   param_a[O][0] = 3.04850; param_b[O][0] = 13.2771; param_c[O] = 0.250800 ;
+    2017           2 :   param_a[O][1] = 2.28680; param_b[O][1] = 5.70110; param_v[O] = 9.13;
+    2018           2 :   param_a[O][2] = 1.54630; param_b[O][2] = 0.32390;
+    2019           2 :   param_a[O][3] = 0.86700; param_b[O][3] = 32.9089;
+    2020           2 :   param_a[O][4] = 0.0;     param_b[O][4] = 1.0;
+    2021             : 
+    2022           2 :   param_a[P][0] = 6.43450; param_b[P][0] = 1.90670; param_c[P] = 1.11490;
+    2023           2 :   param_a[P][1] = 4.17910; param_b[P][1] = 27.1570; param_v[P] = 5.73;
+    2024           2 :   param_a[P][2] = 1.78000; param_b[P][2] = 0.52600;
+    2025           2 :   param_a[P][3] = 1.49080; param_b[P][3] = 68.1645;
+    2026           2 :   param_a[P][4] = 0.0;     param_b[P][4] = 1.0;
+    2027             : 
+    2028           2 :   param_a[S][0] = 6.90530; param_b[S][0] = 1.46790; param_c[S] = 0.866900;
+    2029           2 :   param_a[S][1] = 5.20340; param_b[S][1] = 22.2151; param_v[S] = 19.86;
+    2030           2 :   param_a[S][2] = 1.43790; param_b[S][2] = 0.25360;
+    2031           2 :   param_a[S][3] = 1.58630; param_b[S][3] = 56.1720;
+    2032           2 :   param_a[S][4] = 0.0;     param_b[S][4] = 1.0;
+    2033             : 
+    2034           2 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    2035             : 
+    2036             :   double Iq0=0.;
+    2037           2 :   if( moldat ) {
+    2038           2 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+    2039             :     // cycle over the atom types
+    2040          14 :     for(unsigned i=0; i<NTT; i++) {
+    2041          12 :       const double volr = std::pow(param_v[i], (2.0/3.0)) /(4. * M_PI);
+    2042             :       // cycle over q
+    2043         120 :       for(unsigned k=0; k<q_list.size(); ++k) {
+    2044         108 :         const double q = q_list[k];
+    2045         108 :         const double s = q / (4. * M_PI);
+    2046         108 :         FF_tmp[k][i] = param_c[i];
+    2047             :         // SUM [a_i * EXP( - b_i * (q/4pi)^2 )] Waasmaier and Kirfel (1995)
+    2048         540 :         for(unsigned j=0; j<4; j++) {
+    2049         432 :           FF_tmp[k][i] += param_a[i][j]*std::exp(-param_b[i][j]*s*s);
+    2050             :         }
+    2051             :         // subtract solvation: rho * v_i * EXP( (- v_i^(2/3) / (4pi)) * q^2  ) // since  D in Fraser 1978 is 2*s
+    2052         108 :         FF_tmp[k][i] -= rho*param_v[i]*std::exp(-volr*q*q);
+    2053             :       }
+    2054             :     }
+    2055             :     // cycle over the atoms to assign the atom type and calculate I0
+    2056        6824 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    2057             :       // get atom name
+    2058        6822 :       std::string name = moldat->getAtomName(atoms[i]);
+    2059             :       char type;
+    2060             :       // get atom type
+    2061        6822 :       char first = name.at(0);
+    2062             :       // GOLDEN RULE: type is first letter, if not a number
+    2063        6822 :       if (!isdigit(first)) {
+    2064             :         type = first;
+    2065             :         // otherwise is the second
+    2066             :       } else {
+    2067         816 :         type = name.at(1);
+    2068             :       }
+    2069        6822 :       std::string type_s = std::string(1,type);
+    2070        6822 :       if(AA_map.find(type_s) != AA_map.end()) {
+    2071        6822 :         const unsigned index=AA_map[type_s];
+    2072        6822 :         atoi[i] = AA_map[type_s];
+    2073       34110 :         for(unsigned j=0; j<4; j++) Iq0 += param_a[index][j];
+    2074        6822 :         Iq0 = Iq0 -rho*param_v[index] + param_c[index];
+    2075             :       } else {
+    2076           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    2077             :       }
+    2078             :     }
+    2079             :   } else {
+    2080           0 :     error("MOLINFO DATA not found\n");
+    2081             :   }
+    2082             : 
+    2083           2 :   return Iq0;
+    2084           2 : }
+    2085             : 
+    2086             : }
+    2087             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..c093453593 --- /dev/null +++ b/coverage/isdb/Select.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2121100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6SelectC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe776createERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6SelectC1ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6Select16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4isdb6Select9calculateEv8
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe77C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe77D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Select.cpp.func.html b/coverage/isdb/Select.cpp.func.html new file mode 100644 index 0000000000..89dbadd47b --- /dev/null +++ b/coverage/isdb/Select.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2121100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe776createERKNS_13ActionOptionsE2
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe77C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe77D2Ev3473
_ZN4PLMD4isdb6Select16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4isdb6Select9calculateEv8
_ZN4PLMD4isdb6SelectC1ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6SelectC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Select.cpp.gcov.html b/coverage/isdb/Select.cpp.gcov.html new file mode 100644 index 0000000000..55a4954caa --- /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:2121100.0 %
Date:2024-06-10 08:19:14Functions: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             : /*
+      23             : 
+      24             : */
+      25             : #include "function/Function.h"
+      26             : #include "function/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       10423 : PLUMED_REGISTER_ACTION(Select,"SELECT")
+      78             : 
+      79           3 : void Select::registerKeywords(Keywords& keys) {
+      80           3 :   Function::registerKeywords(keys);
+      81           3 :   keys.use("ARG");
+      82           6 :   keys.add("compulsory","SELECTOR","name of the variable used to select");
+      83           3 : }
+      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           8 :   setDerivative(iselect, 1.0);
+     112           8 : }
+     113             : 
+     114             : }
+     115             : }
+     116             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..eab36c6b8c --- /dev/null +++ b/coverage/isdb/Selector.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:121485.7 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb8Selector5applyEv0
_ZN4PLMD4isdb8Selector9calculateEv0
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe726createERKNS_13ActionOptionsE2
_ZN4PLMD4isdb8SelectorC2ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb8Selector16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe72C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe72D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Selector.cpp.func.html b/coverage/isdb/Selector.cpp.func.html new file mode 100644 index 0000000000..da7b1f0878 --- /dev/null +++ b/coverage/isdb/Selector.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:121485.7 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe726createERKNS_13ActionOptionsE2
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe72C2Ev3473
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe72D2Ev3473
_ZN4PLMD4isdb8Selector16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4isdb8Selector5applyEv0
_ZN4PLMD4isdb8Selector9calculateEv0
_ZN4PLMD4isdb8SelectorC2ERKNS_13ActionOptionsE2
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/Selector.cpp.gcov.html b/coverage/isdb/Selector.cpp.gcov.html new file mode 100644 index 0000000000..d6182dd842 --- /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:121485.7 %
Date:2024-06-10 08:19:14Functions:5771.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/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       10421 : PLUMED_REGISTER_ACTION(Selector,"SELECTOR")
+      73             : 
+      74           3 : void Selector::registerKeywords( Keywords& keys ) {
+      75           3 :   Action::registerKeywords(keys);
+      76           6 :   keys.add("compulsory","NAME","name of the SELECTOR");
+      77           6 :   keys.add("compulsory","VALUE","set (initial) value of the SELECTOR");
+      78           3 : }
+      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.15
+
+ + + diff --git a/coverage/isdb/index-sort-f.html b/coverage/isdb/index-sort-f.html new file mode 100644 index 0000000000..1c0114ac49 --- /dev/null +++ b/coverage/isdb/index-sort-f.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:5203610885.2 %
Date:2024-06-10 08:19:14Functions:18623180.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Rescale.cpp +
11.6%11.6%
+
11.6 %22 / 19020.0 %3 / 15
Selector.cpp +
85.7%85.7%
+
85.7 %12 / 1471.4 %5 / 7
Caliber.cpp +
78.8%78.8%
+
78.8 %115 / 14672.7 %8 / 11
EMMI.cpp +
75.5%75.5%
+
75.5 %593 / 78576.2 %32 / 42
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %757 / 88882.1 %23 / 28
RDC.cpp +
94.0%94.0%
+
94.0 %171 / 18283.3 %10 / 12
SAXS.cpp +
90.0%90.0%
+
90.0 %1366 / 151883.3 %10 / 12
FretEfficiency.cpp +
94.7%94.7%
+
94.7 %36 / 3885.7 %6 / 7
Select.cpp +
100.0%
+
100.0 %21 / 2185.7 %6 / 7
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12987.5 %7 / 8
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17287.5 %7 / 8
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10487.5 %7 / 8
Metainference.cpp +
84.2%84.2%
+
84.2 %741 / 88090.0 %27 / 30
CS2Backbone.cpp +
94.7%94.7%
+
94.7 %918 / 96996.2 %25 / 26
MetainferenceBase.h +
97.2%97.2%
+
97.2 %70 / 72100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/index-sort-l.html b/coverage/isdb/index-sort-l.html new file mode 100644 index 0000000000..4d0503e399 --- /dev/null +++ b/coverage/isdb/index-sort-l.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:5203610885.2 %
Date:2024-06-10 08:19:14Functions:18623180.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Rescale.cpp +
11.6%11.6%
+
11.6 %22 / 19020.0 %3 / 15
EMMI.cpp +
75.5%75.5%
+
75.5 %593 / 78576.2 %32 / 42
Caliber.cpp +
78.8%78.8%
+
78.8 %115 / 14672.7 %8 / 11
Metainference.cpp +
84.2%84.2%
+
84.2 %741 / 88090.0 %27 / 30
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %757 / 88882.1 %23 / 28
Selector.cpp +
85.7%85.7%
+
85.7 %12 / 1471.4 %5 / 7
SAXS.cpp +
90.0%90.0%
+
90.0 %1366 / 151883.3 %10 / 12
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12987.5 %7 / 8
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17287.5 %7 / 8
RDC.cpp +
94.0%94.0%
+
94.0 %171 / 18283.3 %10 / 12
FretEfficiency.cpp +
94.7%94.7%
+
94.7 %36 / 3885.7 %6 / 7
CS2Backbone.cpp +
94.7%94.7%
+
94.7 %918 / 96996.2 %25 / 26
MetainferenceBase.h +
97.2%97.2%
+
97.2 %70 / 72100.0 %10 / 10
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10487.5 %7 / 8
Select.cpp +
100.0%
+
100.0 %21 / 2185.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/isdb/index.html b/coverage/isdb/index.html new file mode 100644 index 0000000000..af6c8ca353 --- /dev/null +++ b/coverage/isdb/index.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:5203610885.2 %
Date:2024-06-10 08:19:14Functions:18623180.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CS2Backbone.cpp +
94.7%94.7%
+
94.7 %918 / 96996.2 %25 / 26
Caliber.cpp +
78.8%78.8%
+
78.8 %115 / 14672.7 %8 / 11
EMMI.cpp +
75.5%75.5%
+
75.5 %593 / 78576.2 %32 / 42
FretEfficiency.cpp +
94.7%94.7%
+
94.7 %36 / 3885.7 %6 / 7
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17287.5 %7 / 8
Metainference.cpp +
84.2%84.2%
+
84.2 %741 / 88090.0 %27 / 30
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %757 / 88882.1 %23 / 28
MetainferenceBase.h +
97.2%97.2%
+
97.2 %70 / 72100.0 %10 / 10
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10487.5 %7 / 8
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12987.5 %7 / 8
RDC.cpp +
94.0%94.0%
+
94.0 %171 / 18283.3 %10 / 12
Rescale.cpp +
11.6%11.6%
+
11.6 %22 / 19020.0 %3 / 15
SAXS.cpp +
90.0%90.0%
+
90.0 %1366 / 151883.3 %10 / 12
Select.cpp +
100.0%
+
100.0 %21 / 2185.7 %6 / 7
Selector.cpp +
85.7%85.7%
+
85.7 %12 / 1471.4 %5 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..480d887d6d --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + 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:29833489.2 %
Date:2024-06-10 08:19:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logmfd6LogMFDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe4256createERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6logmfd6LogMFD8updateVSEv5
_ZN4PLMD6logmfd6LogMFD9updateNVEEv5
_ZN4PLMD6logmfd6LogMFD9updateNVTEv5
_ZN4PLMD6logmfd6LogMFD13calcMeanForceEv15
_ZN4PLMD6logmfd6LogMFD8calcClogEv40
_ZN4PLMD6logmfd6LogMFD8calcFlogEv55
_ZN4PLMD6logmfd6LogMFD8calcEkinEv82
_ZN4PLMD6logmfd6LogMFD6updateEv1500
_ZN4PLMD6logmfd6LogMFD9calculateEv1500
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe425C2Ev3473
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe425D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.func.html b/coverage/logmfd/LogMFD.cpp.func.html new file mode 100644 index 0000000000..a7f506e6ca --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + 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:29833489.2 %
Date:2024-06-10 08:19:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe4256createERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe425C2Ev3473
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe425D2Ev3473
_ZN4PLMD6logmfd6LogMFD13calcMeanForceEv15
_ZN4PLMD6logmfd6LogMFD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6logmfd6LogMFD6updateEv1500
_ZN4PLMD6logmfd6LogMFD8calcClogEv40
_ZN4PLMD6logmfd6LogMFD8calcEkinEv82
_ZN4PLMD6logmfd6LogMFD8calcFlogEv55
_ZN4PLMD6logmfd6LogMFD8updateVSEv5
_ZN4PLMD6logmfd6LogMFD9calculateEv1500
_ZN4PLMD6logmfd6LogMFD9updateNVEEv5
_ZN4PLMD6logmfd6LogMFD9updateNVTEv5
_ZN4PLMD6logmfd6LogMFDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.gcov.html b/coverage/logmfd/LogMFD.cpp.gcov.html new file mode 100644 index 0000000000..85160136c7 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.gcov.html @@ -0,0 +1,1221 @@ + + + + + + + + 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:29833489.2 %
Date:2024-06-10 08:19:14Functions:141593.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=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 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, reconstructing free energy profiles can be performed more efficiently (requiring less elapsed computing time) in LogPD than with a single MD system in LogMFD. In the case that there exists 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, and NAMD.
+     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) &=& V_{X_i}^\prime \left( {{t_n}} \right) + \Delta t\left[ { - \left( {\frac{{\alpha \gamma }}{{\alpha F\left( {{t_n}} \right) + 1}}} \right)\frac{{\partial F\left( {{t_n}} \right)}}{{\partial {X_i}}}} \right]\\
+     193             : S\left( {{t_{n + 1}}} \right) &=& \sqrt {\frac{{N{k_B}T}}{{\sum\limits_i {{M_i}V_{{X_i}}^2\left( {{t_{n + 1}}} \right)} }}} \\
+     194             : {V_{{X_i}}}^\prime \left( {{t_{n + 1}}} \right) &=& S\left( {{t_{n + 1}}} \right){V_{{X_i}}}\left( {{t_{n + 1}}} \right)\\
+     195             : {X_i}\left( {{t_{n + 1}}} \right) &=& {X_i}\left( {{t_n}} \right) + \Delta t V_{X_i}^\prime \left( {{t_{n + 1}}} \right)\\
+     196             : {\Psi_{\rm log}}\left( {{t_{n + 1}}} \right) &=& N{k_B}T\log S\left( {{t_{n + 1}}} \right) + {\Psi_{\rm log}}\left( {{t_n}} \right)\\
+     197             : F\left( {{t_{n + 1}}} \right) &=& \frac{1}{\alpha} \left[
+     198             :     \exp \left\{ \Psi_{\rm log} \left( t_{n+1} \right) / \gamma \right\} - 1 \right]
+     199             : \f}
+     200             : 
+     201             : Note that \f$V_{X_i}^\prime\left( {{t_0}} \right)\f$ is assumed to be initially given, which meets the following relation,
+     202             : 
+     203             : \f[
+     204             :   \sum\limits_{i = 1}^N M_i V_{X_i}^{\prime 2} \left( t_0 \right)  = N{k_B}{T}
+     205             : \f]
+     206             : 
+     207             : 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.
+     208             : 
+     209             : 
+     210             : \par Examples
+     211             : \section Examples Examples
+     212             : 
+     213             : \subsection Example-LoGMFD Example of LogMFD
+     214             : 
+     215             : The following input file tells plumed to restrain collective variables
+     216             : to the fictitious dynamical variables in LogMFD/PD.
+     217             : 
+     218             : plumed.dat
+     219             : \plumedfile
+     220             : UNITS TIME=fs LENGTH=1.0 ENERGY=kcal/mol MASS=1.0 CHARGE=1.0
+     221             : phi: TORSION ATOMS=5,7,9,15
+     222             : psi: TORSION ATOMS=7,9,15,17
+     223             : 
+     224             : # LogMFD
+     225             : LOGMFD ...
+     226             : LABEL=logmfd
+     227             : ARG=phi,psi
+     228             : KAPPA=100.0,100.0
+     229             : DELTA_T=0.5
+     230             : INTERVAL=500
+     231             : TEMP=300.0
+     232             : FLOG=5.0
+     233             : MFICT=5000000.0,5000000.0
+     234             : VFICT=3.5e-4,3.5e-4
+     235             : ALPHA=4.0
+     236             : THERMOSTAT=NVE
+     237             : VETA=0.0
+     238             : META=20000.0
+     239             : FICT_MAX=3.1,3.1
+     240             : FICT_MIN=-3.1,-3.1
+     241             : ... LOGMFD
+     242             : \endplumedfile
+     243             : 
+     244             : To submit this simulation with Gromacs, use the following command line
+     245             : to execute a LogMFD run with Gromacs-MD.
+     246             : Here TOPO/topol0.tpr is an input file
+     247             : which contains atomic coordinates and Gromacs parameters.
+     248             : 
+     249             : \verbatim
+     250             : gmx_mpi mdrun -s TOPO/topol0.tpr -plumed
+     251             : \endverbatim
+     252             : 
+     253             : This command will output files named logmfd.out and replica.out.
+     254             : 
+     255             : The output file logmfd.out records free energy and all fictitious dynamical variables at every MFD step.
+     256             : 
+     257             : logmfd.out
+     258             : 
+     259             : \verbatim
+     260             : # LogMFD
+     261             : # CVs : phi psi
+     262             : # Mass for CV particles : 5000000.000000000 5000000.000000000
+     263             : # Mass for thermostat   :   20000.000000000
+     264             : # 1:iter_md, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,
+     265             : # 6:phi_fict(t), 7:phi_vfict(t), 8:phi_force(t),
+     266             : # 9:psi_fict(t), 10:psi_vfict(t), 11:psi_force(t),
+     267             :        1       4.99918574     308.24149708       0.00000000       0.00000000      -2.85605938       0.00035002       5.19074544       2.79216364       0.00035000      -0.53762989
+     268             :        2       4.99836196     308.26124159       0.00000000       0.00000000      -2.85588436       0.00035005       4.71247605       2.79233863       0.00035000      -0.00532474
+     269             :        3       4.99743572     308.28344595       0.00000000       0.00000000      -2.85570932       0.00035007       5.34358230       2.79251363       0.00035000      -0.05119816
+     270             : ...
+     271             : \endverbatim
+     272             : 
+     273             : The output file replica.out records all collective variables at every MFD step.
+     274             : 
+     275             : replica.out
+     276             : 
+     277             : \verbatim
+     278             : # Replica No. 0 of 1.
+     279             : # 1:iter_md, 2:work, 3:weight,
+     280             : # 4:phi(q)
+     281             : # 5:psi(q)
+     282             :        1   -8.142952e-04     1.000000e+00       -2.80432694       2.78661234
+     283             :        2   -1.638105e-03     1.000000e+00       -2.80893462       2.79211039
+     284             :        3   -2.564398e-03     1.000000e+00       -2.80244854       2.79182665
+     285             : ...
+     286             : \endverbatim
+     287             : 
+     288             : \subsection Example-LogPD Example of LogPD
+     289             : 
+     290             : Use the following command line to execute a LogPD run using two MD replicas (note that only Gromacs is currently available for LogPD).
+     291             : Here TOPO/topol0.tpr and TOPO/topol1.tpr are input files
+     292             : which contain atomic coordinates of each replica and Gromacs parameters.
+     293             : 
+     294             : \verbatim
+     295             : mpirun -np 2 gmx_mpi mdrun -s TOPO/topol -plumed -multi 2
+     296             : \endverbatim
+     297             : 
+     298             : This command will output files named logmfd.out, replica.out.0 and replica.out.1.
+     299             : 
+     300             : The output file logmfd.out records free energy and all fictitious dynamical variables at every MFD step.
+     301             : 
+     302             : logmfd.out
+     303             : 
+     304             : \verbatim
+     305             : # LogPD, replica parallel of LogMFD
+     306             : # number of replica : 2
+     307             : # CVs : phi psi
+     308             : # Mass for CV particles : 5000000.000000000 5000000.000000000
+     309             : # Mass for thermostat   :   20000.000000000
+     310             : # 1:iter_md, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,
+     311             : # 6:phi_fict(t), 7:phi_vfict(t), 8:phi_force(t),
+     312             : # 9:psi_fict(t), 10:psi_vfict(t), 11:psi_force(t),
+     313             :        1       5.00224715     308.16814691       0.00000000       0.00000000      -0.95937173       0.00034994     -12.91277494       0.78923967       0.00035000       0.07353010
+     314             :        2       5.00476934     308.10774854       0.00000000       0.00000000      -0.95919679       0.00034989     -11.20093553       0.78941467       0.00034999      -3.21098229
+     315             :        3       5.00702463     308.05376594       0.00000000       0.00000000      -0.95902187       0.00034983     -10.81712171       0.78958965       0.00034998      -2.07196718
+     316             : ...
+     317             : \endverbatim
+     318             : 
+     319             : 
+     320             : The output file replica.out.0 records all collective variables of replica No.0 at every MFD step.
+     321             : 
+     322             : replica.out.0
+     323             : 
+     324             : \verbatim
+     325             : # Replica No. 0 of 2.
+     326             : # 1:iter_md, 2:work, 3:weight,
+     327             : # 4:phi(q)
+     328             : # 5:psi(q)
+     329             :        1    1.843110e-03     5.003389e-01       -1.10929125       0.83348865
+     330             :        2    3.466179e-03     5.010942e-01       -1.05020764       0.78731283
+     331             :        3    4.927870e-03     5.017619e-01       -1.04968867       0.79635198
+     332             : ...
+     333             : \endverbatim
+     334             : 
+     335             : The output file replica.out.1 records all collective variables of replica No.1 at every MFD step.
+     336             : 
+     337             : replica.out.1
+     338             : 
+     339             : \verbatim
+     340             : # Replica No. 1 of 2.
+     341             : # 1:iter_md, 2:work, 3:weight,
+     342             : # 4:phi(q)
+     343             : # 5:psi(q)
+     344             :        1    2.651173e-03     4.996611e-01       -1.06802968       0.74605205
+     345             :        2    6.075530e-03     4.989058e-01       -1.09264741       0.72681448
+     346             :        3    9.129358e-03     4.982381e-01       -1.08517238       0.74084241
+     347             : ...
+     348             : \endverbatim
+     349             : 
+     350             : */
+     351             : //+ENDPLUMEDOC
+     352             : 
+     353             : #include "bias/Bias.h"
+     354             : #include "core/ActionRegister.h"
+     355             : #include "core/Atoms.h"
+     356             : #include "core/PlumedMain.h"
+     357             : 
+     358             : #include <iostream>
+     359             : 
+     360             : using namespace std;
+     361             : using namespace PLMD;
+     362             : using namespace bias;
+     363             : 
+     364             : namespace PLMD {
+     365             : namespace logmfd {
+     366             : /**
+     367             :    \brief class for LogMFD parameters, variables and subroutines.
+     368             :  */
+     369             : class LogMFD : public Bias {
+     370             :   bool firsttime;               ///< flag that indicates first MFD step or not.
+     371             :   int    interval;              ///< input parameter, period of MD steps when fictitious dynamical variables are evolved.
+     372             :   double delta_t;               ///< input parameter, one time step of MFD when fictitious dynamical variables are evolved.
+     373             :   string thermostat;            ///< input parameter, type of thermostat for canonical dyanamics.
+     374             :   double kbt;                   ///< k_B*temperature
+     375             : 
+     376             :   int    TAMD;                  ///< input parameter, perform TAMD instead of LogMFD.
+     377             :   double alpha;                 ///< input parameter, alpha parameter for LogMFD.
+     378             :   double gamma;                 ///< input parameter, gamma parameter for LogMFD.
+     379             :   std::vector<double> kappa;    ///< input parameter, strength of the harmonic restraining potential.
+     380             : 
+     381             :   std::vector<double> fict_max; ///< input parameter, maximum of each fictitous dynamical variable.
+     382             :   std::vector<double> fict_min; ///< input parameter, minimum of each fictitous dynamical variable.
+     383             : 
+     384             :   std::vector<double>  fict;    ///< current values of each fictitous dynamical variable.
+     385             :   std::vector<double> vfict;    ///< current velocity of each fictitous dynamical variable.
+     386             :   std::vector<double> mfict;    ///< mass of each fictitous dynamical variable.
+     387             : 
+     388             :   double xeta;                  ///< current eta variable of thermostat.
+     389             :   double veta;                  ///< current velocity of eta variable of thermostat.
+     390             :   double meta;                  ///< mass of eta variable of thermostat.
+     391             : 
+     392             :   double flog;                  ///< current free energy
+     393             : 
+     394             :   double hlog;                  ///< value invariant
+     395             :   double phivs;                 ///< potential used in VS method
+     396             :   double work;                  ///< current works done by fictitious dynamical variables in this replica.
+     397             :   double weight;                ///< current weight of this replica.
+     398             : 
+     399             :   std::vector<double> ffict;    ///< current force of each fictitous dynamical variable.
+     400             :   std::vector<double> fict_ave; ///< averaged values of each collective variable.
+     401             : 
+     402             :   std::vector<Value*>  fictValue; ///< pointers to fictitious dynamical variables
+     403             :   std::vector<Value*> vfictValue; ///< pointers to velocity of fictitious dynamical variables
+     404             : 
+     405             : public:
+     406             :   static void registerKeywords(Keywords& keys);
+     407             : 
+     408             :   explicit LogMFD(const ActionOptions&);
+     409             :   void calculate();
+     410             :   void update();
+     411             :   void updateNVE();
+     412             :   void updateNVT();
+     413             :   void updateVS();
+     414             :   void calcMeanForce();
+     415             :   double calcEkin();
+     416             :   double calcFlog();
+     417             :   double calcClog();
+     418             : 
+     419             : private:
+     420             :   double sgn( double x ) {
+     421          55 :     return x>0.0 ? 1.0 : x<0.0 ? -1.0 : 0.0;
+     422             :   }
+     423             : };
+     424             : 
+     425       10425 : PLUMED_REGISTER_ACTION(LogMFD,"LOGMFD")
+     426             : 
+     427             : /**
+     428             :    \brief instruction of parameters for Plumed manual.
+     429             : */
+     430           4 : void LogMFD::registerKeywords(Keywords& keys) {
+     431           4 :   Bias::registerKeywords(keys);
+     432           4 :   keys.use("ARG");
+     433           8 :   keys.add("compulsory","INTERVAL",
+     434             :            "Period of MD steps (\\f$N_m\\f$) to update fictitious dynamical variables." );
+     435           8 :   keys.add("compulsory","DELTA_T",
+     436             :            "Time step for the fictitious dynamical variables (MFD step)." );
+     437           8 :   keys.add("compulsory","THERMOSTAT",
+     438             :            "Type of thermostat for the fictitious dynamical variables. NVE, NVT, VS are available." );
+     439           8 :   keys.add("optional","TEMP",
+     440             :            "Temperature of the fictitious dynamical variables in LogMFD/PD thermostat. "
+     441             :            "If not provided or provided as 0, it will be taken from the temperature of the MD system." );
+     442             : 
+     443           8 :   keys.add("optional","TAMD",
+     444             :            "When TAMD=1, TAMD/d-AFED calculations can be performed instead of LogMFD. Otherwise, the LogMFD protocol is switched on (default)." );
+     445             : 
+     446           8 :   keys.add("optional","ALPHA",
+     447             :            "Alpha parameter for LogMFD. "
+     448             :            "If not provided or provided as 0, it will be taken as 1/gamma. "
+     449             :            "If gamma is also not provided, Alpha is set as 4, which is a sensible value when the unit of kcal/mol is used." );
+     450           8 :   keys.add("optional","GAMMA",
+     451             :            "Gamma parameter for LogMFD. "
+     452             :            "If not provided or provided as 0, it will be taken as 1/alpha. "
+     453             :            "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." );
+     454           8 :   keys.add("compulsory","KAPPA",
+     455             :            "Spring constant of the harmonic restraining potential for the fictitious dynamical variables." );
+     456             : 
+     457           8 :   keys.add("compulsory","FICT_MAX",
+     458             :            "Maximum values reachable for the fictitious dynamical variables. The variables will elastically bounce back at the boundary (mirror boundary)." );
+     459           8 :   keys.add("compulsory","FICT_MIN",
+     460             :            "Minimum values reachable for the fictitious dynamical variables. The variables will elastically bounce back at the boundary (mirror boundary)." );
+     461             : 
+     462           8 :   keys.add("optional","FICT",
+     463             :            "The initial values of the fictitious dynamical variables. "
+     464             :            "If not provided, they are set equal to their corresponding CVs for the initial atomic configuration." );
+     465           8 :   keys.add("optional","VFICT",
+     466             :            "The initial velocities of the fictitious dynamical variables. "
+     467             :            "If not provided, they will be taken as 0." );
+     468           8 :   keys.add("optional","MFICT",
+     469             :            "Masses of each fictitious dynamical variable. "
+     470             :            "If not provided, they will be taken as 10000." );
+     471             : 
+     472           8 :   keys.add("optional","XETA",
+     473             :            "The initial eta variable of the Nose-Hoover thermostat "
+     474             :            "for the fictitious dynamical variables. "
+     475             :            "If not provided, it will be taken as 0." );
+     476           8 :   keys.add("optional","VETA",
+     477             :            "The initial velocity of eta variable. "
+     478             :            "If not provided, it will be taken as 0." );
+     479           8 :   keys.add("optional","META",
+     480             :            "Mass of eta variable. "
+     481             :            "If not provided, it will be taken as \\f$N*kb*T*100*100\\f$." );
+     482             : 
+     483           8 :   keys.add("compulsory","FLOG",
+     484             :            "The initial free energy value in the LogMFD/PD run."
+     485             :            "The origin of the free energy profile is adjusted by FLOG to "
+     486             :            "realize \\f$F({\\bf X}(t)) > 0\\f$ at any \\f${\\bf X}(t)\\f$, "
+     487             :            "resulting in enhanced barrier-crossing. "
+     488             :            "(The value of \\f$H_{\\rm log}\\f$ is automatically "
+     489             :            "set according to FLOG).");
+     490             : 
+     491           8 :   keys.add("optional","WORK",
+     492             :            "The initial value of the work done by fictitious dynamical "
+     493             :            "variables in each replica. "
+     494             :            "If not provided, it will be taken as 0.");
+     495             : 
+     496           4 :   componentsAreNotOptional(keys);
+     497           8 :   keys.addOutputComponent("_fict","default",
+     498             :                           "For example, the fictitious collective variable for LogMFD is specified as "
+     499             :                           "ARG=dist12 and LABEL=logmfd in LOGMFD section in Plumed input file, "
+     500             :                           "the associated fictitious dynamical variable can be specified as "
+     501             :                           "PRINT ARG=dist12,logmfd.dist12_fict FILE=COLVAR");
+     502           8 :   keys.addOutputComponent("_vfict","default",
+     503             :                           "For example, the fictitious collective variable for LogMFD is specified as "
+     504             :                           "ARG=dist12 and LABEL=logmfd in LOGMFD section in Plumed input file, the "
+     505             :                           "velocity of the associated fictitious dynamical variable can be specified as "
+     506             :                           "PRINT ARG=dist12,logmfd.dist12_vfict FILE=COLVAR");
+     507           4 : }
+     508             : 
+     509             : 
+     510             : /**
+     511             :    \brief constructor of LogMFD class
+     512             :    \details This constructor initializes all parameters and variables,
+     513             :    reads input file and set value of parameters and initial value of variables,
+     514             :    and writes messages as Plumed log.
+     515             : */
+     516           3 : LogMFD::LogMFD( const ActionOptions& ao ):
+     517             :   PLUMED_BIAS_INIT(ao),
+     518           3 :   firsttime(true),
+     519           3 :   interval(10),
+     520           3 :   delta_t(1.0),
+     521           6 :   thermostat("NVE"),
+     522           3 :   kbt(-1.0),
+     523           3 :   TAMD(0),
+     524           3 :   alpha(0.0),
+     525           3 :   gamma(0.0),
+     526           3 :   kappa(getNumberOfArguments(),0.0),
+     527           3 :   fict_max(getNumberOfArguments(),0.0),
+     528           3 :   fict_min(getNumberOfArguments(),0.0),
+     529           3 :   fict (getNumberOfArguments(),0.0),
+     530           3 :   vfict(getNumberOfArguments(),0.0),
+     531           3 :   mfict(getNumberOfArguments(),10000.0),
+     532           3 :   xeta(0.0),
+     533           3 :   veta(0.0),
+     534           3 :   meta(0.0),
+     535           3 :   flog(0.0),
+     536           3 :   hlog(0.0),
+     537           3 :   phivs(0.0),
+     538           3 :   work(0.0),
+     539           3 :   weight(0.0),
+     540           3 :   ffict(getNumberOfArguments(),0.0),
+     541           3 :   fict_ave(getNumberOfArguments(),0.0),
+     542           3 :   fictValue(getNumberOfArguments(),NULL),
+     543           6 :   vfictValue(getNumberOfArguments(),NULL)
+     544             : {
+     545           3 :   parse("INTERVAL",interval);
+     546           3 :   parse("DELTA_T",delta_t);
+     547           3 :   parse("THERMOSTAT",thermostat);
+     548           3 :   parse("TEMP",kbt); // read as temperature
+     549             : 
+     550           3 :   parse("TAMD",TAMD);
+     551           3 :   parse("ALPHA",alpha);
+     552           3 :   parse("GAMMA",gamma);
+     553           3 :   parseVector("KAPPA",kappa);
+     554             : 
+     555           3 :   parseVector("FICT_MAX",fict_max);
+     556           3 :   parseVector("FICT_MIN",fict_min);
+     557             : 
+     558           3 :   parseVector("FICT",fict);
+     559           3 :   parseVector("VFICT",vfict);
+     560           3 :   parseVector("MFICT",mfict);
+     561             : 
+     562           3 :   parse("XETA",xeta);
+     563           3 :   parse("VETA",veta);
+     564           3 :   parse("META",meta);
+     565             : 
+     566           3 :   parse("FLOG",flog);
+     567             : 
+     568             :   // read initial value of work for each replica of LogPD
+     569           3 :   if( multi_sim_comm.Get_size()>1 ) {
+     570           0 :     vector<double> vwork(multi_sim_comm.Get_size(),0.0);
+     571           0 :     parseVector("WORK",vwork);
+     572             :     // initial work of this replica
+     573           0 :     work = vwork[multi_sim_comm.Get_rank()];
+     574             :   }
+     575             :   else {
+     576           3 :     work = 0.0;
+     577             :   }
+     578             : 
+     579           3 :   if( kbt>=0.0 ) {
+     580           3 :     kbt *= plumed.getAtoms().getKBoltzmann();
+     581             :   }
+     582             :   else {
+     583           0 :     kbt = plumed.getAtoms().getKbT();
+     584             :   }
+     585             : 
+     586           3 :   if( meta == 0.0 ) {
+     587           2 :     const double nkt = getNumberOfArguments()*kbt;
+     588           2 :     meta = nkt*100.0*100.0;
+     589             :   }
+     590             : 
+     591           3 :   if(alpha == 0.0 && gamma == 0.0) {
+     592           0 :     alpha = 4.0;
+     593           0 :     gamma = 1 / alpha;
+     594             :   }
+     595           3 :   else if(alpha != 0.0 && gamma == 0.0) {
+     596           3 :     gamma = 1 / alpha;
+     597             :   }
+     598           0 :   else if(alpha == 0.0 && gamma != 0.0) {
+     599           0 :     alpha = 1 / gamma;
+     600             :   }
+     601             : 
+     602           3 :   checkRead();
+     603             : 
+     604             :   // output messaages to Plumed's log file
+     605           3 :   if( multi_sim_comm.Get_size()>1 ) {
+     606           0 :     if( TAMD ) {
+     607           0 :       log.printf("TAMD-PD, replica parallel of TAMD, no logarithmic flattening.\n");
+     608             :     }
+     609             :     else {
+     610           0 :       log.printf("LogPD, replica parallel of LogMFD.\n");
+     611             :     }
+     612           0 :     log.printf("number of replica : %d.\n", multi_sim_comm.Get_size() );
+     613             :   }
+     614             :   else {
+     615           3 :     if( TAMD ) {
+     616           0 :       log.printf("TAMD, no logarithmic flattening.\n");
+     617             :     }
+     618             :     else {
+     619           3 :       log.printf("LogMFD, logarithmic flattening.\n");
+     620             :     }
+     621             :   }
+     622             : 
+     623           3 :   log.printf("  with harmonic force constant      ");
+     624           6 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     625           3 :   log.printf("\n");
+     626             : 
+     627           3 :   log.printf("  with interval of cv(ideal) update ");
+     628           3 :   log.printf(" %d", interval);
+     629           3 :   log.printf("\n");
+     630             : 
+     631           3 :   log.printf("  with time step of cv(ideal) update ");
+     632           3 :   log.printf(" %f", delta_t);
+     633           3 :   log.printf("\n");
+     634             : 
+     635           3 :   if( !TAMD ) {
+     636           3 :     log.printf("  with alpha, gamma                 ");
+     637           3 :     log.printf(" %f %f", alpha, gamma);
+     638           3 :     log.printf("\n");
+     639             :   }
+     640             : 
+     641           3 :   log.printf("  with Thermostat for cv(ideal)     ");
+     642           3 :   log.printf(" %s", thermostat.c_str());
+     643           3 :   log.printf("\n");
+     644             : 
+     645           3 :   log.printf("  with initial free energy          ");
+     646           3 :   log.printf(" %f", flog);
+     647           3 :   log.printf("\n");
+     648             : 
+     649           3 :   log.printf("  with mass of cv(ideal)");
+     650           6 :   for(unsigned i=0; i<mfict.size(); i++) log.printf(" %f", mfict[i]);
+     651           3 :   log.printf("\n");
+     652             : 
+     653           3 :   log.printf("  with initial value of cv(ideal)");
+     654           6 :   for(unsigned i=0; i<fict.size(); i++) log.printf(" %f", fict[i]);
+     655           3 :   log.printf("\n");
+     656             : 
+     657           3 :   log.printf("  with initial velocity of cv(ideal)");
+     658           6 :   for(unsigned i=0; i<vfict.size(); i++) log.printf(" %f", vfict[i]);
+     659           3 :   log.printf("\n");
+     660             : 
+     661           3 :   log.printf("  with maximum value of cv(ideal)    ");
+     662           6 :   for(unsigned i=0; i<fict_max.size(); i++) log.printf(" %f",fict_max[i]);
+     663           3 :   log.printf("\n");
+     664             : 
+     665           3 :   log.printf("  with minimum value of cv(ideal)    ");
+     666           6 :   for(unsigned i=0; i<fict_min.size(); i++) log.printf(" %f",fict_min[i]);
+     667           3 :   log.printf("\n");
+     668             : 
+     669           3 :   log.printf("  and kbt                           ");
+     670           3 :   log.printf(" %f",kbt);
+     671           3 :   log.printf("\n");
+     672             : 
+     673             :   // setup Value* variables
+     674           6 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     675           3 :     std::string comp = getPntrToArgument(i)->getName()+"_fict";
+     676           3 :     addComponentWithDerivatives(comp);
+     677             : 
+     678           3 :     if(getPntrToArgument(i)->isPeriodic()) {
+     679             :       std::string a,b;
+     680           0 :       getPntrToArgument(i)->getDomain(a,b);
+     681           0 :       componentIsPeriodic(comp,a,b);
+     682             :     }
+     683             :     else {
+     684           3 :       componentIsNotPeriodic(comp);
+     685             :     }
+     686           3 :     fictValue[i] = getPntrToComponent(comp);
+     687             : 
+     688           3 :     comp = getPntrToArgument(i)->getName()+"_vfict";
+     689           3 :     addComponent(comp);
+     690             : 
+     691           3 :     componentIsNotPeriodic(comp);
+     692           3 :     vfictValue[i] = getPntrToComponent(comp);
+     693             :   }
+     694           3 : }
+     695             : 
+     696             : /**
+     697             :    \brief calculate forces for fictitious variables at every MD steps.
+     698             :    \details This function calculates initial values of fictitious variables
+     699             :    and write header messages to LogMFD log files at the first MFD step,
+     700             :    calculates restraining fources comes from difference between the fictitious variable
+     701             :    and collective variable at every MD steps.
+     702             : */
+     703        1500 : void LogMFD::calculate() {
+     704        1500 :   if( firsttime ) {
+     705           3 :     firsttime = false;
+     706             : 
+     707             :     // set initial values of fictitious variables if they were not specified.
+     708           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     709           3 :       if( fict[i] != 0.0 ) continue;
+     710             : 
+     711             :       // use the collective variables as the initial of the fictitious variable.
+     712           0 :       fict[i] = getArgument(i);
+     713             : 
+     714             :       // average values of fictitious variables by all replica.
+     715           0 :       if( multi_sim_comm.Get_size()>1 ) {
+     716           0 :         multi_sim_comm.Sum(fict[i]);
+     717           0 :         fict[i] /= multi_sim_comm.Get_size();
+     718             :       }
+     719             :     }
+     720             : 
+     721             :     // initialize accumulation value to zero
+     722           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     723           3 :       fict_ave[i] = 0.0;
+     724             :     }
+     725             : 
+     726             :     // calculate invariant for NVE
+     727           3 :     if(thermostat == "NVE") {
+     728             :       // kinetic energy
+     729           1 :       const double ekin = calcEkin();
+     730             :       // potential energy
+     731           1 :       const double pot = TAMD ? flog : sgn(flog)*gamma * std::log1p( alpha*fabs(flog) );
+     732             :       // invariant
+     733           1 :       hlog = pot + ekin;
+     734             :     }
+     735           2 :     else if(thermostat == "NVT") {
+     736           1 :       const double nkt = getNumberOfArguments()*kbt;
+     737             :       // kinetic energy
+     738           1 :       const double ekin = calcEkin();
+     739             :       // bath energy
+     740           1 :       const double ekin_bath = 0.5*veta*veta*meta + xeta*nkt;
+     741             :       // potential energy
+     742           1 :       const double pot = TAMD ? flog : sgn(flog)*gamma * std::log1p( alpha*fabs(flog) );
+     743             :       // invariant
+     744           1 :       hlog = pot + ekin + ekin_bath;
+     745             :     }
+     746           1 :     else if(thermostat == "VS") {
+     747             :       // initial velocities
+     748           2 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     749           1 :         vfict[i] = sqrt(kbt/mfict[i]);
+     750             :       }
+     751             :       // initial VS potential
+     752           1 :       phivs = TAMD ? flog : sgn(flog)* gamma*std::log1p( alpha*fabs(flog) );
+     753             : 
+     754             :       // invariant
+     755           1 :       hlog = 0.0;
+     756             :     }
+     757             : 
+     758           3 :     weight = 1.0; // for replica parallel
+     759             : 
+     760             :     // open LogMFD's log file
+     761           3 :     if( multi_sim_comm.Get_rank()==0 && comm.Get_rank()==0 ) {
+     762           3 :       FILE *outlog = std::fopen("logmfd.out", "w");
+     763             : 
+     764             :       // output messages to LogMFD's log file
+     765           3 :       if( multi_sim_comm.Get_size()>1 ) {
+     766             :         fprintf(outlog, "# LogPD, replica parallel of LogMFD\n");
+     767           0 :         fprintf(outlog, "# number of replica : %d\n", multi_sim_comm.Get_size() );
+     768             :       }
+     769             :       else {
+     770             :         fprintf(outlog, "# LogMFD\n");
+     771             :       }
+     772             : 
+     773             :       fprintf(outlog, "# CVs :");
+     774           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     775             :         fprintf(outlog, " %s",  getPntrToArgument(i)->getName().c_str() );
+     776             :       }
+     777             :       fprintf(outlog, "\n");
+     778             : 
+     779             :       fprintf(outlog, "# Mass for CV particles :");
+     780           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     781           3 :         fprintf(outlog, "%18.9f", mfict[i]);
+     782             :       }
+     783             :       fprintf(outlog, "\n");
+     784             : 
+     785             :       fprintf(outlog, "# Mass for thermostat   :");
+     786           3 :       fprintf(outlog, "%18.9f", meta);
+     787             :       fprintf(outlog, "\n");
+     788             :       fprintf(outlog, "# 1:iter_md, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,\n");
+     789             : 
+     790           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     791           3 :         fprintf(outlog, "# %u:%s_fict(t), %u:%s_vfict(t), %u:%s_force(t),\n",
+     792             :                 6+i*3, getPntrToArgument(i)->getName().c_str(),
+     793             :                 7+i*3, getPntrToArgument(i)->getName().c_str(),
+     794           3 :                 8+i*3, getPntrToArgument(i)->getName().c_str() );
+     795             :       }
+     796             : 
+     797           3 :       fclose(outlog);
+     798             :     }
+     799             : 
+     800           3 :     if( comm.Get_rank()==0 ) {
+     801             :       // the number of replica is added to file name to distingwish replica.
+     802           3 :       FILE *outlog2 = fopen("replica.out", "w");
+     803           6 :       fprintf(outlog2, "# Replica No. %d of %d.\n",
+     804           3 :               multi_sim_comm.Get_rank(), multi_sim_comm.Get_size() );
+     805             : 
+     806             :       fprintf(outlog2, "# 1:iter_md, 2:work, 3:weight,\n");
+     807           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     808           3 :         fprintf(outlog2, "# %u:%s(q)\n",
+     809             :                 4+i, getPntrToArgument(i)->getName().c_str() );
+     810             :       }
+     811           3 :       fclose(outlog2);
+     812             :     }
+     813             : 
+     814             :     // output messages to Plumed's log file
+     815             :     //    log.printf("LOGMFD thermostat parameters Xeta Veta Meta");
+     816             :     //    log.printf(" %f %f %f", xeta, veta, meta);
+     817             :     //    log.printf("\n");
+     818             :     //    log.printf("# 1:iter_md, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,");
+     819             :     //    log.printf("# 6:X1(t), 7:V1(t), 8:F1(t), 9:X2(t), 10:V2(t), 11:F2(t), ...");
+     820             : 
+     821             :   } // firsttime
+     822             : 
+     823             :   // calculate force for fictitious variable
+     824             :   double ene=0.0;
+     825        3000 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     826             :     // difference between fictitious variable and collective variable.
+     827        1500 :     const double diff = difference(i,fict[i],getArgument(i));
+     828             :     // restraining force.
+     829        1500 :     const double f = -kappa[i]*diff;
+     830             :     setOutputForce(i,f);
+     831             : 
+     832             :     // restraining energy.
+     833        1500 :     ene += 0.5*kappa[i]*diff*diff;
+     834             : 
+     835             :     // accumulate force, later it will be averaged.
+     836        1500 :     ffict[i] += -f;
+     837             : 
+     838             :     // accumulate varience of collective variable, later it will be averaged.
+     839        1500 :     fict_ave[i] += diff;
+     840             :   }
+     841             : 
+     842             :   setBias(ene);
+     843        3000 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     844             :     // correct fict so that it is inside [min:max].
+     845        1500 :     fict[i] = fictValue[i]->bringBackInPbc(fict[i]);
+     846        1500 :     fictValue[i]->set(fict[i]);
+     847        1500 :     vfictValue[i]->set(vfict[i]);
+     848             :   }
+     849        1500 : } // calculate
+     850             : 
+     851             : /**
+     852             :    \brief update fictitious variables.
+     853             :    \details This function manages evolution of fictitious variables.
+     854             :    This function calculates mean force, updates fictitious variables by one MFD step,
+     855             :    bounces back variables, updates free energy, and record logs.
+     856             : */
+     857        1500 : void LogMFD::update() {
+     858        1500 :   if(getStep() == 0 || getStep()%interval != 0 ) return;
+     859             : 
+     860             :   // calc mean force for fictitious variables
+     861          15 :   calcMeanForce();
+     862             : 
+     863             :   // update fictitious variables
+     864          15 :   if(thermostat == "NVE") {
+     865           5 :     updateNVE();
+     866             :   }
+     867          10 :   else if(thermostat == "NVT") {
+     868           5 :     updateNVT();
+     869             :   }
+     870           5 :   else if(thermostat == "VS") {
+     871           5 :     updateVS();
+     872             :   }
+     873             : 
+     874             :   // bounce back variables if they are beyond their min and max.
+     875          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     876          15 :     if(fict[i] > fict_max[i]) {
+     877           0 :       fict[i] = fict_max[i] - (fict[i] - fict_max[i]);
+     878           0 :       vfict[i] *= -1.0;
+     879             :     }
+     880          15 :     if(fict[i] < fict_min[i]) {
+     881           0 :       fict[i] = fict_min[i] + (fict_min[i] - fict[i]);
+     882           0 :       vfict[i] *= -1.0;
+     883             :     }
+     884             :   }
+     885             : 
+     886             :   // update free energy
+     887          15 :   flog = calcFlog();
+     888             : 
+     889             :   // record log for fictitious variables
+     890          15 :   if( multi_sim_comm.Get_rank()==0 && comm.Get_rank()==0 ) {
+     891          15 :     FILE *outlog = std::fopen("logmfd.out", "a");
+     892             : 
+     893          15 :     const double ekin = calcEkin();
+     894          15 :     const double temp = 2.0*ekin/getNumberOfArguments()/plumed.getAtoms().getKBoltzmann();
+     895             : 
+     896          15 :     fprintf(outlog, "%*d", 8, (int)getStep()/interval);
+     897          15 :     fprintf(outlog, "%17.8f", flog);
+     898             :     fprintf(outlog, "%17.8f", temp);
+     899          15 :     fprintf(outlog, "%17.8f", xeta);
+     900          15 :     fprintf(outlog, "%17.8f", veta);
+     901          30 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     902          15 :       fprintf(outlog, "%17.8f", fict[i]);
+     903          15 :       fprintf(outlog, "%17.8f", vfict[i]);
+     904          15 :       fprintf(outlog, "%17.8f", ffict[i]);
+     905             :     }
+     906             :     fprintf(outlog," \n");
+     907          15 :     fclose(outlog);
+     908             :   }
+     909             : 
+     910             :   // record log for collective variables
+     911          15 :   if( comm.Get_rank()==0 ) {
+     912             :     // the number of replica is added to file name to distingwish replica.
+     913          15 :     FILE *outlog2 = fopen("replica.out", "a");
+     914          15 :     fprintf(outlog2, "%*d", 8, (int)getStep()/interval);
+     915          15 :     fprintf(outlog2, "%16.6e ", work);
+     916          15 :     fprintf(outlog2, "%16.6e ", weight);
+     917          30 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     918          15 :       fprintf(outlog2, "%17.8f", fict_ave[i]);
+     919             :     }
+     920             :     fprintf(outlog2," \n");
+     921          15 :     fclose(outlog2);
+     922             :   }
+     923             : 
+     924             :   // reset mean force
+     925          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     926          15 :     ffict[i] = 0.0;
+     927          15 :     fict_ave[i] = 0.0;
+     928             :   }
+     929             : 
+     930             : } // update
+     931             : 
+     932             : /**
+     933             :    \brief update fictitious variables by NVE mechanics.
+     934             :    \details This function updates ficitious variables by one NVE-MFD step using mean forces
+     935             :    and flattening coefficient and free energy.
+     936             :  */
+     937           5 : void LogMFD::updateNVE() {
+     938           5 :   const double dt = delta_t;
+     939             : 
+     940             :   // get latest free energy and flattening coefficient
+     941           5 :   flog = calcFlog();
+     942           5 :   const double clog = calcClog();
+     943             : 
+     944             :   // update all ficitious variables by one MFD step
+     945          10 :   for( unsigned i=0; i<getNumberOfArguments(); ++i ) {
+     946             :     // update velocity (full step)
+     947           5 :     vfict[i]+=clog*ffict[i]*dt/mfict[i];
+     948             :     // update position (full step)
+     949           5 :     fict[i]+=vfict[i]*dt;
+     950             :   }
+     951           5 : } // updateNVE
+     952             : 
+     953             : /**
+     954             :    \brief update fictitious variables by NVT mechanics.
+     955             :    \details This function updates ficitious variables by one NVT-MFD step using mean forces
+     956             :    and flattening coefficient and free energy.
+     957             :  */
+     958           5 : void LogMFD::updateNVT() {
+     959           5 :   const double dt = delta_t;
+     960           5 :   const double nkt = getNumberOfArguments()*kbt;
+     961             : 
+     962             :   // backup vfict
+     963           5 :   std::vector<double> vfict_backup(getNumberOfArguments());
+     964          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     965           5 :     vfict_backup[i] = vfict[i];
+     966             :   }
+     967             : 
+     968             :   const int niter=5;
+     969          30 :   for(unsigned j=0; j<niter; ++j) {
+     970             :     // get latest free energy and flattening coefficient
+     971          25 :     flog = calcFlog();
+     972          25 :     const double clog = calcClog();
+     973             : 
+     974             :     // restore vfict from vfict_backup
+     975          50 :     for(unsigned l=0; l<getNumberOfArguments(); ++l) {
+     976          25 :       vfict[l] = vfict_backup[l];
+     977             :     }
+     978             : 
+     979             :     // evolve vfict from vfict_backup by dt/2
+     980          50 :     for(unsigned m=0; m<getNumberOfArguments(); ++m) {
+     981          25 :       vfict[m] *= exp(-0.25*dt*veta);
+     982          25 :       vfict[m] += 0.5*dt*clog*ffict[m]/mfict[m];
+     983          25 :       vfict[m] *= exp(-0.25*dt*veta);
+     984             :     }
+     985             :   }
+     986             : 
+     987             :   // get latest free energy and flattening coefficient
+     988           5 :   flog = calcFlog();
+     989           5 :   const double clog = calcClog();
+     990             : 
+     991             :   // evolve vfict by dt/2, and evolve fict by dt
+     992          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     993           5 :     vfict[i] *= exp(-0.25*dt*veta);
+     994           5 :     vfict[i] += 0.5*dt*clog*ffict[i]/mfict[i];
+     995           5 :     vfict[i] *= exp(-0.25*dt*veta);
+     996           5 :     fict[i]  += dt*vfict[i];
+     997             :   }
+     998             : 
+     999             :   // evolve xeta and veta by dt
+    1000           5 :   xeta += 0.5*dt*veta;
+    1001           5 :   const double ekin = calcEkin();
+    1002           5 :   veta += dt*(2.0*ekin-nkt)/meta;
+    1003           5 :   xeta += 0.5*dt*veta;
+    1004           5 : } // updateNVT
+    1005             : 
+    1006             : /**
+    1007             :    \brief update fictitious variables by VS mechanics.
+    1008             :    \details This function updates ficitious variables by one VS-MFD step using mean forces
+    1009             :    and flattening coefficient and free energy.
+    1010             :  */
+    1011           5 : void LogMFD::updateVS() {
+    1012           5 :   const double dt = delta_t;
+    1013           5 :   const double nkt = getNumberOfArguments()*kbt;
+    1014             : 
+    1015             :   // get latest free energy and flattening coefficient
+    1016           5 :   flog = calcFlog();
+    1017           5 :   const double clog = calcClog();
+    1018             : 
+    1019          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1020             :     // update velocity (full step)
+    1021           5 :     vfict[i] += clog*ffict[i]*dt/mfict[i];
+    1022             :   }
+    1023             : 
+    1024           5 :   const double ekin = calcEkin();
+    1025           5 :   const double svs = sqrt(nkt/ekin/2);
+    1026             : 
+    1027          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1028             :     // update position (full step)
+    1029           5 :     vfict[i] *= svs;
+    1030           5 :     fict[i] += vfict[i]*dt;
+    1031             :   }
+    1032             : 
+    1033             :   // evolve VS potential
+    1034           5 :   phivs += nkt*std::log(svs);
+    1035           5 : } // updateVS
+    1036             : 
+    1037             : /**
+    1038             :    \brief calculate mean force for fictitious variables.
+    1039             :    \details This function calculates mean forces by averaging forces accumulated during one MFD step,
+    1040             :    update work variables done by fictitious variables by one MFD step,
+    1041             :    calculate weight variable of this replica for LogPD.
+    1042             : */
+    1043          15 : void LogMFD::calcMeanForce() {
+    1044             :   // cale temporal mean force for each CV
+    1045          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1046          30 :     ffict[i] /= interval;
+    1047             :     // average of diff (getArgument(i)-fict[i])
+    1048          15 :     fict_ave[i] /= interval;
+    1049             :     // average of getArgument(i)
+    1050          15 :     fict_ave[i] += fict[i];
+    1051             : 
+    1052             :     // correct fict_ave so that it is inside [min:max].
+    1053          15 :     fict_ave[i] = fictValue[i]->bringBackInPbc(fict_ave[i]);
+    1054             :   }
+    1055             : 
+    1056             :   // accumulate work, it was initialized as 0.0
+    1057          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1058          15 :     work -= ffict[i] * vfict[i] * delta_t; // modified sign
+    1059             :   }
+    1060             : 
+    1061             :   // for replica parallel
+    1062          15 :   if( multi_sim_comm.Get_size()>1 ) {
+    1063             :     // find the minimum work among all replicas
+    1064           0 :     double work_min = work;
+    1065           0 :     multi_sim_comm.Min(work_min);
+    1066             : 
+    1067             :     // weight of this replica.
+    1068             :     // here, work is reduced by work_min to avoid all exp(-work/kbt)s disconverge
+    1069           0 :     if( kbt == 0.0 ) {
+    1070           0 :       weight = work==work_min ? 1.0 : 0.0;
+    1071             :     }
+    1072             :     else {
+    1073           0 :       weight = exp(-(work-work_min)/kbt);
+    1074             :     }
+    1075             : 
+    1076             :     // normalize the weight
+    1077           0 :     double sum_weight = weight;
+    1078           0 :     multi_sim_comm.Sum(sum_weight);
+    1079           0 :     weight /= sum_weight;
+    1080             : 
+    1081             :     // weighting force of this replica
+    1082           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1083           0 :       ffict[i] *= weight;
+    1084             :     }
+    1085             : 
+    1086             :     // mean forces of all replica.
+    1087           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1088           0 :       multi_sim_comm.Sum(ffict[i]);
+    1089             :     }
+    1090             :     // now, mean force is obtained.
+    1091             :   }
+    1092          15 : } // calcMeanForce
+    1093             : 
+    1094             : /**
+    1095             :    \brief calculate kinetic energy of fictitious variables.
+    1096             :    \retval kinetic energy.
+    1097             :    \details This function calculates sum of kinetic energy of all fictitious variables.
+    1098             :  */
+    1099          82 : double LogMFD::calcEkin() {
+    1100             :   double ekin=0.0;
+    1101         164 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1102          82 :     ekin += mfict[i]*vfict[i]*vfict[i]*0.5;
+    1103             :   }
+    1104          82 :   return ekin;
+    1105             : } // calcEkin
+    1106             : 
+    1107             : /**
+    1108             :    \brief calculate free energy of fictitious variables.
+    1109             :    \retval free energy.
+    1110             :    \details This function calculates free energy by using invariant of canonical mechanics.
+    1111             :  */
+    1112          55 : double LogMFD::calcFlog() {
+    1113          55 :   const double nkt = getNumberOfArguments()*kbt;
+    1114          55 :   const double ekin = calcEkin();
+    1115             :   double pot;
+    1116             : 
+    1117          55 :   if (thermostat == "NVE") {
+    1118          10 :     pot = hlog - ekin;
+    1119             :   }
+    1120          45 :   else if (thermostat == "NVT") {
+    1121          35 :     const double ekin_bath = 0.5*veta*veta*meta+xeta*nkt;
+    1122          35 :     pot = hlog - ekin - ekin_bath;
+    1123             :   }
+    1124          10 :   else if (thermostat == "VS") {
+    1125          10 :     pot = phivs;
+    1126             :   }
+    1127             :   else {
+    1128             :     pot = 0.0; // never occurs
+    1129             :   }
+    1130             : 
+    1131         110 :   return TAMD ? pot : sgn(pot)*expm1(fabs(pot)/gamma)/alpha;
+    1132             : } // calcFlog
+    1133             : 
+    1134             : /**
+    1135             :    \brief calculate coefficient for flattening.
+    1136             :    \retval flattering coefficient.
+    1137             :    \details This function returns 1.0 for TAMD, flattening coefficient for LogMFD.
+    1138             :  */
+    1139          40 : double LogMFD::calcClog() {
+    1140          40 :   return TAMD ? 1.0 : alpha*gamma/(alpha*fabs(flog)+1.0);
+    1141             : } // calcClog
+    1142             : 
+    1143             : } // logmfd
+    1144             : } // PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/logmfd/index-sort-f.html b/coverage/logmfd/index-sort-f.html new file mode 100644 index 0000000000..0579efa076 --- /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:29833489.2 %
Date:2024-06-10 08:19:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
89.2%89.2%
+
89.2 %298 / 33493.3 %14 / 15
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/logmfd/index-sort-l.html b/coverage/logmfd/index-sort-l.html new file mode 100644 index 0000000000..cffe4b0334 --- /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:29833489.2 %
Date:2024-06-10 08:19:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
89.2%89.2%
+
89.2 %298 / 33493.3 %14 / 15
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/logmfd/index.html b/coverage/logmfd/index.html new file mode 100644 index 0000000000..753054a0e8 --- /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:29833489.2 %
Date:2024-06-10 08:19:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
89.2%89.2%
+
89.2 %298 / 33493.3 %14 / 15
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/main/index-sort-f.html b/coverage/main/index-sort-f.html new file mode 100644 index 0000000000..aec5de5834 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/main/index-sort-l.html b/coverage/main/index-sort-l.html new file mode 100644 index 0000000000..ec129311f2 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/main/index.html b/coverage/main/index.html new file mode 100644 index 0000000000..4e07519ed2 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..890828e14a --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main3441
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/main/main.cpp.func.html b/coverage/main/main.cpp.func.html new file mode 100644 index 0000000000..401fda2341 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main3441
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/main/main.cpp.gcov.html b/coverage/main/main.cpp.gcov.html new file mode 100644 index 0000000000..ed615005ad --- /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-06-10 08:19:14Functions: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        3441 : int main(int argc,char**argv) {
+      37             : #ifdef __PLUMED_HAS_MPI
+      38             :   bool nompi=false;
+      39        7165 :   for(unsigned iarg=1; iarg<argc; iarg++) {
+      40        6546 :     if(!std::strcmp(argv[iarg],"--no-mpi")) nompi=true;
+      41        6546 :     if(!std::strcmp(argv[iarg],"--mpi"))    nompi=false;
+      42             : // stop at first non-option
+      43        6546 :     if(argv[iarg] && argv[iarg][0]!='-') break;
+      44             :   }
+      45        3441 :   if(!nompi) MPI_Init(&argc,&argv);
+      46             : #endif
+      47        3441 :   int ret=0;
+      48             : 
+      49             :   try {
+      50             :     PLMD::Plumed p;
+      51             :     p.cmd("CLTool setArgc",&argc);
+      52        3441 :     p.cmd("CLTool setArgv",argv);
+      53             : #ifdef __PLUMED_HAS_MPI
+      54        3441 :     if(!nompi) {
+      55             :       MPI_Comm comm;
+      56         336 :       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        3441 :   if(!nompi) MPI_Finalize();
+      69             : #endif
+      70        3441 :   return ret;
+      71             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..48a015f149 --- /dev/null +++ b/coverage/manyrestraints/LWalls.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:92437.5 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe716createERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints6LWallsC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints6LWallsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD14manyrestraints6LWalls13calcPotentialERKdRd0
_ZN4PLMD14manyrestraints6LWalls16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe71C2Ev3473
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe71D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/manyrestraints/LWalls.cpp.func.html b/coverage/manyrestraints/LWalls.cpp.func.html new file mode 100644 index 0000000000..0db67ea8e6 --- /dev/null +++ b/coverage/manyrestraints/LWalls.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:92437.5 %
Date:2024-06-10 08:19:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe716createERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe71C2Ev3473
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe71D2Ev3473
_ZN4PLMD14manyrestraints6LWalls16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD14manyrestraints6LWallsC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints6LWallsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD14manyrestraints6LWalls13calcPotentialERKdRd0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/manyrestraints/LWalls.cpp.gcov.html b/coverage/manyrestraints/LWalls.cpp.gcov.html new file mode 100644 index 0000000000..0ce8377d07 --- /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:92437.5 %
Date:2024-06-10 08:19:14Functions:3742.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 "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       10419 : PLUMED_REGISTER_ACTION(LWalls,"LWALLS")
+      72             : 
+      73           1 : void LWalls::registerKeywords( Keywords& keys ) {
+      74           1 :   ManyRestraintsBase::registerKeywords( keys );
+      75           2 :   keys.add("compulsory","AT","the radius of the sphere");
+      76           2 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      77           2 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      78           2 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      79           2 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      80           1 : }
+      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.15
+
+ + + 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 0000000000..e3ff37a60f --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC2ERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints18ManyRestraintsBase16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD14manyrestraints18ManyRestraintsBase5applyEv10
_ZN4PLMD14manyrestraints18ManyRestraintsBase28doJobsRequiredBeforeTaskListEv740
_ZNK4PLMD14manyrestraints18ManyRestraintsBase27transformBridgedDerivativesERKjRNS_10MultiValueES5_14800
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.cpp.func.html b/coverage/manyrestraints/ManyRestraintsBase.cpp.func.html new file mode 100644 index 0000000000..e61575624d --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints18ManyRestraintsBase16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD14manyrestraints18ManyRestraintsBase28doJobsRequiredBeforeTaskListEv740
_ZN4PLMD14manyrestraints18ManyRestraintsBase5applyEv10
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC2ERKNS_13ActionOptionsE2
_ZNK4PLMD14manyrestraints18ManyRestraintsBase27transformBridgedDerivativesERKjRNS_10MultiValueES5_14800
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.cpp.gcov.html b/coverage/manyrestraints/ManyRestraintsBase.cpp.gcov.html new file mode 100644 index 0000000000..d85012d758 --- /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-06-10 08:19:14Functions: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           4 : void ManyRestraintsBase::registerKeywords( Keywords& keys ) {
+      29           4 :   Action::registerKeywords( keys );
+      30           4 :   ActionWithValue::registerKeywords( keys );
+      31           4 :   ActionWithVessel::registerKeywords( keys );
+      32           4 :   ActionWithInputVessel::registerKeywords( keys );
+      33           4 :   ActionPilot::registerKeywords( keys );
+      34           8 :   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           4 :   keys.remove("TOL");
+      36           8 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potentials");
+      37           4 : }
+      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.15
+
+ + + 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 0000000000..4077172ddd --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.h.func.html b/coverage/manyrestraints/ManyRestraintsBase.h.func.html new file mode 100644 index 0000000000..af5be20d7a --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.h.gcov.html b/coverage/manyrestraints/ManyRestraintsBase.h.gcov.html new file mode 100644 index 0000000000..4f2202efab --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..1f5d7cebd2 --- /dev/null +++ b/coverage/manyrestraints/UWalls.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2424100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints6UWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe756createERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints6UWallsC1ERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints6UWalls16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe75C2Ev3473
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe75D2Ev3473
_ZNK4PLMD14manyrestraints6UWalls13calcPotentialERKdRd14800
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/manyrestraints/UWalls.cpp.func.html b/coverage/manyrestraints/UWalls.cpp.func.html new file mode 100644 index 0000000000..0a57763125 --- /dev/null +++ b/coverage/manyrestraints/UWalls.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2424100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe756createERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe75C2Ev3473
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe75D2Ev3473
_ZN4PLMD14manyrestraints6UWalls16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14manyrestraints6UWallsC1ERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints6UWallsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD14manyrestraints6UWalls13calcPotentialERKdRd14800
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/manyrestraints/UWalls.cpp.gcov.html b/coverage/manyrestraints/UWalls.cpp.gcov.html new file mode 100644 index 0000000000..e6accc0281 --- /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:2424100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_ACTION(UWalls,"UWALLS")
+      76             : 
+      77           3 : void UWalls::registerKeywords( Keywords& keys ) {
+      78           3 :   ManyRestraintsBase::registerKeywords( keys );
+      79           6 :   keys.add("compulsory","AT","the radius of the sphere");
+      80           6 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      81           6 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      82           6 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      83           6 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      84           3 : }
+      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.15
+
+ + + diff --git a/coverage/manyrestraints/index-sort-f.html b/coverage/manyrestraints/index-sort-f.html new file mode 100644 index 0000000000..db7b8188d7 --- /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:759281.5 %
Date:2024-06-10 08:19:14Functions:182669.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LWalls.cpp +
37.5%37.5%
+
37.5 %9 / 2442.9 %3 / 7
ManyRestraintsBase.h +
71.4%71.4%
+
71.4 %5 / 766.7 %4 / 6
ManyRestraintsBase.cpp +
100.0%
+
100.0 %37 / 3783.3 %5 / 6
UWalls.cpp +
100.0%
+
100.0 %24 / 2485.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/manyrestraints/index-sort-l.html b/coverage/manyrestraints/index-sort-l.html new file mode 100644 index 0000000000..6d27fb672a --- /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:759281.5 %
Date:2024-06-10 08:19:14Functions:182669.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LWalls.cpp +
37.5%37.5%
+
37.5 %9 / 2442.9 %3 / 7
ManyRestraintsBase.h +
71.4%71.4%
+
71.4 %5 / 766.7 %4 / 6
UWalls.cpp +
100.0%
+
100.0 %24 / 2485.7 %6 / 7
ManyRestraintsBase.cpp +
100.0%
+
100.0 %37 / 3783.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/manyrestraints/index.html b/coverage/manyrestraints/index.html new file mode 100644 index 0000000000..968ec40064 --- /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:759281.5 %
Date:2024-06-10 08:19:14Functions:182669.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LWalls.cpp +
37.5%37.5%
+
37.5 %9 / 2442.9 %3 / 7
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 %24 / 2485.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7dbdaa6252 --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:10010496.2 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12AdaptivePathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12AdaptivePathC1ERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe1136createERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12AdaptivePath16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7mapping12AdaptivePath6updateEv101
_ZN4PLMD7mapping12AdaptivePath9calculateEv101
_ZN4PLMD7mapping12AdaptivePath9getLambdaEv101
_ZNK4PLMD7mapping12AdaptivePath11performTaskERKjS3_RNS_10MultiValueE2020
_ZNK4PLMD7mapping12AdaptivePath11transformHDERKdRd2020
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe113C2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe113D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.func.html b/coverage/mapping/AdaptivePath.cpp.func.html new file mode 100644 index 0000000000..19c476dd0a --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:10010496.2 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12AdaptivePath16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7mapping12AdaptivePath6updateEv101
_ZN4PLMD7mapping12AdaptivePath9calculateEv101
_ZN4PLMD7mapping12AdaptivePath9getLambdaEv101
_ZN4PLMD7mapping12AdaptivePathC1ERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12AdaptivePathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe1136createERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe113C2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe113D2Ev3473
_ZNK4PLMD7mapping12AdaptivePath11performTaskERKjS3_RNS_10MultiValueE2020
_ZNK4PLMD7mapping12AdaptivePath11transformHDERKdRd2020
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.gcov.html b/coverage/mapping/AdaptivePath.cpp.gcov.html new file mode 100644 index 0000000000..4eb84f6a4d --- /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:10010496.2 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(AdaptivePath,"ADAPTIVE_PATH")
+     114             : 
+     115           2 : void AdaptivePath::registerKeywords( Keywords& keys ) {
+     116           2 :   Mapping::registerKeywords( keys ); keys.remove("PROPERTY");
+     117           4 :   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           4 :   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           4 :   keys.add("compulsory","UPDATE","the frequency with which the path should be updated");
+     120           4 :   keys.add("compulsory","TOLERANCE","1E-6","the tolerance to use for the path updating algorithm that makes all frames equidistant");
+     121           4 :   keys.add("optional","WFILE","file on which to write out the path");
+     122           4 :   keys.add("compulsory","FMT","%f","the format to use for output files");
+     123           4 :   keys.add("optional","WSTRIDE","frequency with which to write out the path");
+     124           2 : }
+     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           3 :   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( atoms.getUnits().getLength()/0.1, mymoldat, pathfile, ofmt );
+     253             :     }
+     254           2 :     pathfile.flush();
+     255           2 :   }
+     256         101 : }
+     257             : 
+     258             : }
+     259             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..21086ac203 --- /dev/null +++ b/coverage/mapping/Mapping.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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-06-10 08:19:14Functions:71163.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7Mapping15getArgumentNameB5cxx11ERj0
_ZN4PLMD7mapping7Mapping29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7Mapping9getLambdaEv0
_ZN4PLMD7mapping7MappingC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping7MappingC2ERKNS_13ActionOptionsE10
_ZN4PLMD7mapping7Mapping16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7mapping7Mapping17turnOnDerivativesEv19
_ZN4PLMD7mapping7Mapping5applyEv5015
_ZN4PLMD7mapping7Mapping25getReferenceConfigurationERKj13175
_ZNK4PLMD7mapping7Mapping15finishPackSetupERKjRNS_18ReferenceValuePackE172372
_ZNK4PLMD7mapping7Mapping25calculateDistanceFunctionERKjRNS_18ReferenceValuePackERKb172372
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/Mapping.cpp.func.html b/coverage/mapping/Mapping.cpp.func.html new file mode 100644 index 0000000000..539bc2e4d1 --- /dev/null +++ b/coverage/mapping/Mapping.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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-06-10 08:19:14Functions:71163.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7Mapping15getArgumentNameB5cxx11ERj0
_ZN4PLMD7mapping7Mapping16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7mapping7Mapping17turnOnDerivativesEv19
_ZN4PLMD7mapping7Mapping25getReferenceConfigurationERKj13175
_ZN4PLMD7mapping7Mapping29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7Mapping5applyEv5015
_ZN4PLMD7mapping7Mapping9getLambdaEv0
_ZN4PLMD7mapping7MappingC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping7MappingC2ERKNS_13ActionOptionsE10
_ZNK4PLMD7mapping7Mapping15finishPackSetupERKjRNS_18ReferenceValuePackE172372
_ZNK4PLMD7mapping7Mapping25calculateDistanceFunctionERKjRNS_18ReferenceValuePackERKb172372
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/Mapping.cpp.gcov.html b/coverage/mapping/Mapping.cpp.gcov.html new file mode 100644 index 0000000000..5993022a1f --- /dev/null +++ b/coverage/mapping/Mapping.cpp.gcov.html @@ -0,0 +1,286 @@ + + + + + + + + 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-06-10 08:19:14Functions:71163.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 "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             : #include "core/Atoms.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace mapping {
+      33             : 
+      34          13 : void Mapping::registerKeywords( Keywords& keys ) {
+      35          13 :   Action::registerKeywords( keys );
+      36          13 :   ActionWithValue::registerKeywords( keys );
+      37          13 :   ActionWithArguments::registerKeywords( keys );
+      38          13 :   ActionAtomistic::registerKeywords( keys );
+      39          13 :   vesselbase::ActionWithVessel::registerKeywords( keys );
+      40          26 :   keys.add("compulsory","REFERENCE","a pdb file containing the set of reference configurations");
+      41          26 :   keys.add("compulsory","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
+      42          26 :   keys.add("compulsory","TYPE","OPTIMAL-FAST","the manner in which distances are calculated. More information on the different "
+      43             :            "metrics that are available in PLUMED can be found in the section of the manual on "
+      44             :            "\\ref dists");
+      45          26 :   keys.addFlag("DISABLE_CHECKS",false,"disable checks on reference input structures.");
+      46          13 : }
+      47             : 
+      48          10 : Mapping::Mapping(const ActionOptions&ao):
+      49             :   Action(ao),
+      50             :   ActionAtomistic(ao),
+      51             :   ActionWithArguments(ao),
+      52             :   ActionWithValue(ao),
+      53          10 :   ActionWithVessel(ao)
+      54             : {
+      55             :   // Read the input
+      56          10 :   std::string mtype; parse("TYPE",mtype);
+      57          10 :   bool skipchecks; parseFlag("DISABLE_CHECKS",skipchecks);
+      58             : 
+      59             :   // Read the properties we require
+      60             :   bool ispath=false;
+      61          20 :   if( keywords.exists("PROPERTY") ) {
+      62           6 :     std::vector<std::string> propnames; parseVector("PROPERTY",propnames);
+      63           3 :     if(propnames.size()==0) error("no properties were specified");
+      64           9 :     for(unsigned i=0; i<propnames.size(); ++i) property.insert( std::pair<std::string,std::vector<double> >( propnames[i], std::vector<double>() ) );
+      65           3 :   } else {
+      66          14 :     property.insert( std::pair<std::string,std::vector<double> >( "spath", std::vector<double>() ) ); ispath=true;
+      67             :   }
+      68             : 
+      69             :   // Open reference file
+      70          10 :   std::string reference; parse("REFERENCE",reference);
+      71          10 :   FILE* fp=fopen(reference.c_str(),"r");
+      72          10 :   if(!fp) error("could not open reference file " + reference );
+      73             : 
+      74             :   // Read all reference configurations
+      75             :   bool do_read=true; unsigned nfram=0; double wnorm=0., ww;
+      76         426 :   while (do_read) {
+      77             :     // Read the pdb file
+      78         852 :     PDB mypdb; do_read=mypdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
+      79             :     // Break if we are done
+      80         426 :     if( !do_read ) break ;
+      81             :     // Check for required properties
+      82         416 :     if( !ispath ) {
+      83             :       double prop;
+      84         378 :       for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+      85         252 :         if( !mypdb.getArgumentValue( it->first, prop ) ) error("pdb input does not have contain property named " + it->first );
+      86         252 :         it->second.push_back(prop);
+      87             :       }
+      88             :     } else {
+      89         580 :       property.find("spath")->second.push_back( myframes.size()+1 );
+      90             :     }
+      91             :     // Fix argument names
+      92         416 :     expandArgKeywordInPDB( mypdb );
+      93             :     // And read the frame
+      94         416 :     myframes.emplace_back( metricRegister().create<ReferenceConfiguration>( mtype, mypdb ) );
+      95         832 :     if( !mypdb.getArgumentValue( "WEIGHT", ww ) ) ww=1.0;
+      96         416 :     weights.push_back( ww ); wnorm+=ww; nfram++;
+      97         426 :   }
+      98          10 :   fclose(fp);
+      99             : 
+     100          10 :   if(nfram==0 ) error("no reference configurations were specified");
+     101          10 :   log.printf("  found %u configurations in file %s\n",nfram,reference.c_str() );
+     102         426 :   for(unsigned i=0; i<weights.size(); ++i) weights[i] = weights[i]/wnorm;
+     103             : 
+     104             :   // Finish the setup of the mapping object
+     105             :   // Get the arguments and atoms that are required
+     106             :   std::vector<AtomNumber> atoms; std::vector<std::string> args;
+     107         426 :   for(unsigned i=0; i<myframes.size(); ++i) { myframes[i]->getAtomRequests( atoms, skipchecks ); myframes[i]->getArgumentRequests( args, skipchecks ); }
+     108          10 :   std::vector<Value*> req_args; interpretArgumentList( args, req_args );
+     109          10 :   if( req_args.size()>0 && atoms.size()>0 ) error("cannot mix atoms and arguments");
+     110          10 :   if( req_args.size()>0 ) requestArguments( req_args );
+     111          10 :   if( atoms.size()>0 ) {
+     112           8 :     log.printf("  found %zu atoms in input \n",atoms.size());
+     113           8 :     log.printf("  with indices : ");
+     114         112 :     for(unsigned i=0; i<atoms.size(); ++i) {
+     115         104 :       if(i%25==0) log<<"\n";
+     116         104 :       log.printf("%d ",atoms[i].serial());
+     117             :     }
+     118           8 :     log.printf("\n");
+     119           8 :     requestAtoms( atoms );
+     120             :   }
+     121             :   // Duplicate all frames (duplicates are used by sketch-map)
+     122             :   // mymap->duplicateFrameList();
+     123             :   // fframes.resize( 2*nfram, 0.0 ); dfframes.resize( 2*nfram, 0.0 );
+     124             :   // plumed_assert( !mymap->mappingNeedsSetup() );
+     125             :   // Resize all derivative arrays
+     126             :   // mymap->setNumberOfAtomsAndArguments( atoms.size(), args.size() );
+     127             :   // Resize forces array
+     128          10 :   if( getNumberOfAtoms()>0 ) {
+     129           8 :     forcesToApply.resize( 3*getNumberOfAtoms() + 9 + getNumberOfArguments() );
+     130             :   } else {
+     131           2 :     forcesToApply.resize( getNumberOfArguments() );
+     132             :   }
+     133          20 : }
+     134             : 
+     135          19 : void Mapping::turnOnDerivatives() {
+     136          19 :   ActionWithValue::turnOnDerivatives();
+     137          19 :   needsDerivatives();
+     138          19 : }
+     139             : 
+     140           0 : double Mapping::getLambda() {
+     141           0 :   plumed_merror("lambda is not defined in this mapping type");
+     142             : }
+     143             : 
+     144           0 : std::string Mapping::getArgumentName( unsigned& iarg ) {
+     145           0 :   if( iarg < getNumberOfArguments() ) return getPntrToArgument(iarg)->getName();
+     146           0 :   unsigned iatom=iarg - getNumberOfArguments();
+     147           0 :   std::string atnum; Tools::convert( getAbsoluteIndex(iatom).serial(),atnum);
+     148           0 :   unsigned icomp=iatom%3;
+     149           0 :   if(icomp==0) return "pos" + atnum + "x";
+     150           0 :   if(icomp==1) return "pos" + atnum + "y";
+     151           0 :   return "pos" + atnum + "z";
+     152             : }
+     153             : 
+     154      172372 : void Mapping::finishPackSetup( const unsigned& ifunc, ReferenceValuePack& mypack ) const {
+     155             :   mypack.setValIndex(0);
+     156      172372 :   unsigned nargs2=myframes[ifunc]->getNumberOfReferenceArguments();
+     157      172372 :   unsigned nat2=myframes[ifunc]->getNumberOfReferencePositions();
+     158      172372 :   if( mypack.getNumberOfAtoms()!=nat2 || mypack.getNumberOfArguments()!=nargs2 ) mypack.resize( nargs2, nat2 );
+     159      172372 :   if( nat2>0 ) {
+     160      137592 :     ReferenceAtoms* myat2=dynamic_cast<ReferenceAtoms*>( myframes[ifunc].get() ); plumed_dbg_assert( myat2 );
+     161     1926288 :     for(unsigned i=0; i<nat2; ++i) mypack.setAtomIndex( i, myat2->getAtomIndex(i) );
+     162             :   }
+     163      172372 : }
+     164             : 
+     165      172372 : double Mapping::calculateDistanceFunction( const unsigned& ifunc, ReferenceValuePack& myder, const bool& squared ) const {
+     166             :   // Calculate the distance
+     167      172372 :   double dd = myframes[ifunc]->calculate( getPositions(), getPbc(), getArguments(), myder, squared );
+     168             :   // Transform distance by whatever
+     169      172372 :   double df, ff=transformHD( dd, df ); myder.scaleAllDerivatives( df );
+     170             :   // And the virial
+     171      172372 :   if( getNumberOfAtoms()>0 && !myder.virialWasSet() ) {
+     172      137592 :     Tensor tvir; tvir.zero();
+     173     1926288 :     for(unsigned i=0; i<myder.getNumberOfAtoms(); ++i) tvir +=-1.0*Tensor( getPosition( myder.getAtomIndex(i) ), myder.getAtomDerivative(i) );
+     174      137592 :     myder.addBoxDerivatives( tvir );
+     175             :   }
+     176      172372 :   return ff;
+     177             : }
+     178             : 
+     179       13175 : ReferenceConfiguration* Mapping::getReferenceConfiguration( const unsigned& ifunc ) {
+     180       13175 :   return myframes[ifunc].get();
+     181             : }
+     182             : 
+     183           0 : void Mapping::calculateNumericalDerivatives( ActionWithValue* a ) {
+     184           0 :   if( getNumberOfArguments()>0 ) {
+     185           0 :     ActionWithArguments::calculateNumericalDerivatives( a );
+     186             :   }
+     187           0 :   if( getNumberOfAtoms()>0 ) {
+     188           0 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
+     189           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     190           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
+     191             :     }
+     192           0 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
+     193           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     194           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
+     195             :     }
+     196             :   }
+     197           0 : }
+     198             : 
+     199        5015 : void Mapping::apply() {
+     200        5015 :   if( getForcesFromVessels( forcesToApply ) ) {
+     201           0 :     addForcesOnArguments( forcesToApply );
+     202           0 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, getNumberOfArguments() );
+     203             :   }
+     204        5015 : }
+     205             : 
+     206             : }
+     207             : }
+     208             : 
+     209             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..04686716b4 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/mapping/Mapping.h.func.html b/coverage/mapping/Mapping.h.func.html new file mode 100644 index 0000000000..0ea74c8e3d --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/mapping/Mapping.h.gcov.html b/coverage/mapping/Mapping.h.gcov.html new file mode 100644 index 0000000000..63f9251324 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..fc0d40af41 --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:12714488.2 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7PCAVars29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7PCAVarsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe1976createERKNS_13ActionOptionsE5
_ZN4PLMD7mapping7PCAVarsC1ERKNS_13ActionOptionsE5
_ZN4PLMD7mapping7PCAVars16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7mapping7PCAVars22getNumberOfDerivativesEv36
_ZN4PLMD7mapping7PCAVars12lockRequestsEv55
_ZN4PLMD7mapping7PCAVars14unlockRequestsEv55
_ZN4PLMD7mapping7PCAVars5applyEv55
_ZN4PLMD7mapping7PCAVars9calculateEv55
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe197C2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe197D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.func.html b/coverage/mapping/PCAVars.cpp.func.html new file mode 100644 index 0000000000..9e2a2ddc48 --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:12714488.2 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe1976createERKNS_13ActionOptionsE5
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe197C2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe197D2Ev3473
_ZN4PLMD7mapping7PCAVars12lockRequestsEv55
_ZN4PLMD7mapping7PCAVars14unlockRequestsEv55
_ZN4PLMD7mapping7PCAVars16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD7mapping7PCAVars22getNumberOfDerivativesEv36
_ZN4PLMD7mapping7PCAVars29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7PCAVars5applyEv55
_ZN4PLMD7mapping7PCAVars9calculateEv55
_ZN4PLMD7mapping7PCAVarsC1ERKNS_13ActionOptionsE5
_ZN4PLMD7mapping7PCAVarsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.gcov.html b/coverage/mapping/PCAVars.cpp.gcov.html new file mode 100644 index 0000000000..2d86e0713f --- /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:12714488.2 %
Date:2024-06-10 08:19:14Functions: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 "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       10429 : PLUMED_REGISTER_ACTION(PCAVars,"PCAVARS")
+     198             : 
+     199           6 : void PCAVars::registerKeywords( Keywords& keys ) {
+     200           6 :   Action::registerKeywords( keys );
+     201           6 :   ActionWithValue::registerKeywords( keys );
+     202           6 :   ActionAtomistic::registerKeywords( keys );
+     203           6 :   ActionWithArguments::registerKeywords( keys );
+     204           6 :   componentsAreNotOptional(keys); keys.use("ARG");
+     205          12 :   keys.addOutputComponent("eig","default","the projections on each eigenvalue are stored on values labeled eig-1, eig-2, ...");
+     206          12 :   keys.addOutputComponent("residual","default","the distance of the configuration from the linear subspace defined "
+     207             :                           "by the vectors, \\f$e_i\\f$, that are contained in the rows of \\f$A\\f$.  In other words this is "
+     208             :                           "\\f$\\sqrt( r^2 - \\sum_i [\\mathbf{r}.\\mathbf{e_i}]^2)\\f$ where "
+     209             :                           "\\f$r\\f$ is the distance between the instantaneous position and the "
+     210             :                           "reference point.");
+     211          12 :   keys.add("compulsory","REFERENCE","a pdb file containing the reference configuration and configurations that define the directions for each eigenvector");
+     212          12 :   keys.add("compulsory","TYPE","OPTIMAL","The method we are using for alignment to the reference structure");
+     213          12 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     214           6 : }
+     215             : 
+     216           5 : PCAVars::PCAVars(const ActionOptions& ao):
+     217             :   Action(ao),
+     218             :   ActionWithValue(ao),
+     219             :   ActionAtomistic(ao),
+     220             :   ActionWithArguments(ao),
+     221          10 :   myvals(1,0),
+     222           5 :   mypack(0,0,myvals),
+     223          10 :   nopbc(false)
+     224             : {
+     225             : 
+     226             :   // What type of distance are we calculating
+     227           5 :   std::string mtype; parse("TYPE",mtype);
+     228             : 
+     229          10 :   parseFlag("NOPBC",nopbc);
+     230             : 
+     231             :   // Open reference file
+     232          10 :   std::string reference; parse("REFERENCE",reference);
+     233           5 :   FILE* fp=fopen(reference.c_str(),"r");
+     234           5 :   if(!fp) error("could not open reference file " + reference );
+     235             : 
+     236             :   // Read all reference configurations
+     237             :   // MultiReferenceBase myframes( "", false );
+     238             :   std::vector<std::unique_ptr<ReferenceConfiguration> > myframes;
+     239             :   bool do_read=true; unsigned nfram=0;
+     240          20 :   while (do_read) {
+     241          20 :     PDB mypdb;
+     242             :     // Read the pdb file
+     243          40 :     do_read=mypdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
+     244             :     // Fix argument names
+     245          20 :     if(do_read) {
+     246          15 :       if( nfram==0 ) {
+     247          10 :         myref=metricRegister().create<ReferenceConfiguration>( mtype, mypdb );
+     248           5 :         Direction* tdir = dynamic_cast<Direction*>( myref.get() );
+     249           5 :         if( tdir ) error("first frame should be reference configuration - not direction of vector");
+     250           5 :         if( !myref->pcaIsEnabledForThisReference() ) error("can't do PCA with reference type " + mtype );
+     251             :         // std::vector<std::string> remarks( mypdb.getRemark() ); std::string rtype;
+     252             :         // bool found=Tools::parse( remarks, "TYPE", rtype );
+     253             :         // if(!found){ std::vector<std::string> newrem(1); newrem[0]="TYPE="+mtype; mypdb.addRemark(newrem); }
+     254             :         // myframes.push_back( metricRegister().create<ReferenceConfiguration>( "", mypdb ) );
+     255             :       } else {
+     256          10 :         auto mymsd = metricRegister().create<ReferenceConfiguration>( "", mypdb );
+     257          10 :         myframes.emplace_back( std::move(mymsd) );
+     258          10 :       }
+     259          15 :       nfram++;
+     260             :     } else {
+     261             :       break;
+     262             :     }
+     263          20 :   }
+     264           5 :   fclose(fp);
+     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 :     addForcesOnArguments( forcesToApply );
+     453           0 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, getNumberOfArguments() );
+     454             :   }
+     455             : 
+     456          55 : }
+     457             : 
+     458             : }
+     459             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..dfb3617044 --- /dev/null +++ b/coverage/mapping/Path.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping4PathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe1396createERKNS_13ActionOptionsE6
_ZN4PLMD7mapping4PathC1ERKNS_13ActionOptionsE6
_ZN4PLMD7mapping4Path16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe139C2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe139D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/Path.cpp.func.html b/coverage/mapping/Path.cpp.func.html new file mode 100644 index 0000000000..1fa04d50b3 --- /dev/null +++ b/coverage/mapping/Path.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe1396createERKNS_13ActionOptionsE6
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe139C2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe139D2Ev3473
_ZN4PLMD7mapping4Path16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping4PathC1ERKNS_13ActionOptionsE6
_ZN4PLMD7mapping4PathC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/Path.cpp.gcov.html b/coverage/mapping/Path.cpp.gcov.html new file mode 100644 index 0000000000..42ae9ca1f8 --- /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:1515100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10431 : PLUMED_REGISTER_ACTION(Path,"PATH")
+     140             : 
+     141           7 : void Path::registerKeywords( Keywords& keys ) {
+     142           7 :   PathBase::registerKeywords( keys ); keys.remove("PROPERTY");
+     143          14 :   keys.addFlag("NOSPATH",false,"do not calculate the spath position");
+     144          14 :   keys.remove("LOWMEM"); keys.use("GPATH");
+     145           7 : }
+     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.15
+
+ + + 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 0000000000..cb46ea1830 --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping8PathBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping8PathBaseC2ERKNS_13ActionOptionsE9
_ZN4PLMD7mapping8PathBase16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7mapping8PathBase9getLambdaEv1103
_ZN4PLMD7mapping8PathBase9calculateEv4914
_ZNK4PLMD7mapping8PathBase11performTaskERKjS3_RNS_10MultiValueE170352
_ZNK4PLMD7mapping8PathBase11transformHDERKdRd170352
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/PathBase.cpp.func.html b/coverage/mapping/PathBase.cpp.func.html new file mode 100644 index 0000000000..b77ceff0f7 --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping8PathBase16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7mapping8PathBase9calculateEv4914
_ZN4PLMD7mapping8PathBase9getLambdaEv1103
_ZN4PLMD7mapping8PathBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping8PathBaseC2ERKNS_13ActionOptionsE9
_ZNK4PLMD7mapping8PathBase11performTaskERKjS3_RNS_10MultiValueE170352
_ZNK4PLMD7mapping8PathBase11transformHDERKdRd170352
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/PathBase.cpp.gcov.html b/coverage/mapping/PathBase.cpp.gcov.html new file mode 100644 index 0000000000..19acb4dcf6 --- /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-06-10 08:19:14Functions: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          11 : void PathBase::registerKeywords( Keywords& keys ) {
+      29          11 :   Mapping::registerKeywords( keys );
+      30          22 :   keys.add("compulsory","LAMBDA","0","the value of the lambda parameter for paths");
+      31          22 :   keys.addFlag("NOZPATH",false,"do not calculate the zpath position");
+      32          11 : }
+      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.15
+
+ + + 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 0000000000..3291c2c6b9 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.func.html b/coverage/mapping/PathReparameterization.cpp.func.html new file mode 100644 index 0000000000..e04fc90bea --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.gcov.html b/coverage/mapping/PathReparameterization.cpp.gcov.html new file mode 100644 index 0000000000..ae372beb4d --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..9fbf1a8bf9 --- /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:11912198.3 %
Date:2024-06-10 08:19:14Functions: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_119PathToolsRegisterMeC2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeD2Ev3473
_ZN4PLMD7mapping9PathTools16registerKeywordsERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.func.html b/coverage/mapping/PathTools.cpp.func.html new file mode 100644 index 0000000000..7d74d4b12e --- /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:11912198.3 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMe6createERKNS_13CLToolOptionsE8
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeC2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeD2Ev3473
_ZN4PLMD7mapping9PathTools16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD7mapping9PathTools4mainEP8_IO_FILES3_RNS_12CommunicatorE4
_ZN4PLMD7mapping9PathToolsC2ERKNS_13CLToolOptionsE8
_ZNK4PLMD7mapping9PathTools11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.gcov.html b/coverage/mapping/PathTools.cpp.gcov.html new file mode 100644 index 0000000000..ebbbb31453 --- /dev/null +++ b/coverage/mapping/PathTools.cpp.gcov.html @@ -0,0 +1,375 @@ + + + + + + + + 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:11912198.3 %
Date:2024-06-10 08:19:14Functions: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 "cltools/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       10427 : PLUMED_REGISTER_CLTOOL(PathTools,"pathtools")
+     117             : 
+     118        3473 : void PathTools::registerKeywords( Keywords& keys ) {
+     119        3473 :   CLTool::registerKeywords( keys );
+     120        6946 :   keys.add("atoms","--start","a pdb file that contains the structure for the initial frame of your path");
+     121        6946 :   keys.add("atoms","--end","a pdb file that contains the structure for the final frame of your path");
+     122        6946 :   keys.add("atoms-1","--path","a pdb file that contains an initial path in which the frames are not equally spaced");
+     123        6946 :   keys.add("compulsory","--fixed","0","the frames to fix when constructing the path using --path");
+     124        6946 :   keys.add("compulsory","--metric","the measure to use to calculate the distance between frames");
+     125        6946 :   keys.add("compulsory","--out","the name of the file on which to output your path");
+     126        6946 :   keys.add("compulsory","--arg-fmt","%f","the format to use for argument values in your frames");
+     127        6946 :   keys.add("compulsory","--tolerance","1E-4","the tolerance to use for the algorithm that is used to re-parameterize the path");
+     128       10419 :   keys.add("compulsory","--nframes-before-start","1","the number of frames to include in the path before the first frame");
+     129        6946 :   keys.add("compulsory","--nframes","1","the number of frames between the start and end frames in your path");
+     130       10419 :   keys.add("compulsory","--nframes-after-end","1","the number of frames to put after the last frame of your path");
+     131        3473 : }
+     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=[](FILE* 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           8 :   }
+     217             : 
+     218             : // Read initial frame
+     219           4 :   std::string istart; parse("--start",istart); FILE* fp2=fopen(istart.c_str(),"r"); PDB mystartpdb;
+     220           2 :   if( istart.length()==0 ) error("input is missing use --istart + --iend or --path");
+     221           2 :   if( !mystartpdb.readFromFilepointer(fp2,false,0.1) ) error("could not read fila " + istart);
+     222           2 :   auto sframe=metricRegister().create<ReferenceConfiguration>( mtype, mystartpdb );
+     223           2 :   fclose(fp2);
+     224             : 
+     225             : // Read final frame
+     226           4 :   std::string iend; parse("--end",iend); FILE* fp1=fopen(iend.c_str(),"r"); PDB myendpdb;
+     227           2 :   if( iend.length()==0 ) error("input is missing using --istart + --iend or --path");
+     228           2 :   if( !myendpdb.readFromFilepointer(fp1,false,0.1) ) error("could not read fila " + iend);
+     229           2 :   auto eframe=metricRegister().create<ReferenceConfiguration>( mtype, myendpdb );
+     230           2 :   fclose(fp1);
+     231             : // Get atoms and arg requests
+     232             :   std::vector<AtomNumber> atoms; std::vector<std::string> arg_names;
+     233           2 :   sframe->getAtomRequests( atoms); eframe->getAtomRequests( atoms);
+     234           2 :   sframe->getArgumentRequests( arg_names ); eframe->getArgumentRequests( arg_names );
+     235             : 
+     236             : // Now read in the rest of the instructions
+     237             :   unsigned nbefore, nbetween, nafter;
+     238           6 :   parse("--nframes-before-start",nbefore); parse("--nframes",nbetween); parse("--nframes-after-end",nafter);
+     239           2 :   nbetween++;
+     240             :   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() );
+     241           2 :   std::fprintf(out,"A path consisting of %u equally-spaced frames before the initial structure, %u frames between the initial and final structures "
+     242             :                "and %u frames after the final structure will be created \n",nbefore,nbetween,nafter);
+     243             : 
+     244             : // Create a vector of arguments to use for calculating displacements
+     245           2 :   Pbc fpbc;
+     246             :   std::vector<std::unique_ptr<Value>> args;
+     247           4 :   for(unsigned i=0; i<eframe->getNumberOfReferenceArguments(); ++i) {
+     248           2 :     args.emplace_back(Tools::make_unique<Value>()); args[args.size()-1]->setNotPeriodic();
+     249             :   }
+     250             : 
+     251             :   // convert pointer once:
+     252           2 :   auto args_ptr=Tools::unique2raw(args);
+     253             : 
+     254             : // Calculate the distance between the start and the end
+     255           2 :   MultiValue myvpack( 1, sframe->getNumberOfReferenceArguments() + 3*sframe->getNumberOfReferencePositions() + 9);
+     256           2 :   ReferenceValuePack mypack( sframe->getNumberOfReferenceArguments(), sframe->getNumberOfReferencePositions(), myvpack );
+     257           2 :   sframe->calc( eframe->getReferencePositions(), fpbc, args_ptr, eframe->getReferenceArguments(), mypack, false );
+     258             : // And the spacing between frames
+     259           2 :   double delr = 1.0 / static_cast<double>( nbetween );
+     260             : // Calculate the vector connecting the start to the end
+     261           2 :   PDB mypdb; mypdb.setAtomNumbers( sframe->getAbsoluteIndexes() ); mypdb.addBlockEnd( sframe->getAbsoluteIndexes().size() );
+     262           2 :   if( sframe->getArgumentNames().size()>0 ) mypdb.setArgumentNames( sframe->getArgumentNames() );
+     263           4 :   Direction mydir(ReferenceConfigurationOptions("DIRECTION")); sframe->setupPCAStorage( mypack ); mydir.read( mypdb ); mydir.zeroDirection();
+     264           2 :   sframe->extractDisplacementVector( eframe->getReferencePositions(), args_ptr, eframe->getReferenceArguments(), false, mydir );
+     265             : 
+     266             : // Now create frames
+     267           2 :   OFile ofile; ofile.open(ofilename); unsigned nframes=0;
+     268           4 :   Direction pos(ReferenceConfigurationOptions("DIRECTION")); pos.read( mypdb );
+     269           4 :   for(int i=0; i<nbefore; ++i) {
+     270           2 :     pos.setDirection( sframe->getReferencePositions(), sframe->getReferenceArguments() );
+     271           2 :     pos.displaceReferenceConfiguration( -i*delr, mydir );
+     272           2 :     mypdb.setAtomPositions( pos.getReferencePositions() );
+     273           4 :     for(unsigned j=0; j<pos.getReferenceArguments().size(); ++j) mypdb.setArgumentValue( sframe->getArgumentNames()[j], pos.getReferenceArgument(j) );
+     274           2 :     ofile.printf("REMARK TYPE=%s\n",mtype.c_str() );
+     275           2 :     mypdb.print( 10, NULL, ofile, ofmt ); nframes++;
+     276             :   }
+     277           8 :   for(unsigned i=1; i<nbetween; ++i) {
+     278           6 :     pos.setDirection( sframe->getReferencePositions(), sframe->getReferenceArguments() );
+     279           6 :     pos.displaceReferenceConfiguration( i*delr, mydir );
+     280           6 :     mypdb.setAtomPositions( pos.getReferencePositions() );
+     281          16 :     for(unsigned j=0; j<pos.getReferenceArguments().size(); ++j) mypdb.setArgumentValue( sframe->getArgumentNames()[j], pos.getReferenceArgument(j) );
+     282           6 :     ofile.printf("REMARK TYPE=%s\n",mtype.c_str() );
+     283           6 :     mypdb.print( 10, NULL, ofile, ofmt ); nframes++;
+     284             :   }
+     285           7 :   for(unsigned i=0; i<nafter; ++i) {
+     286           5 :     pos.setDirection( eframe->getReferencePositions(), eframe->getReferenceArguments() );
+     287           5 :     pos.displaceReferenceConfiguration( i*delr, mydir );
+     288           5 :     mypdb.setAtomPositions( pos.getReferencePositions() );
+     289          13 :     for(unsigned j=0; j<pos.getReferenceArguments().size(); ++j) mypdb.setArgumentValue( sframe->getArgumentNames()[j], pos.getReferenceArgument(j) );
+     290           5 :     ofile.printf("REMARK TYPE=%s\n",mtype.c_str() );
+     291           5 :     mypdb.print( 10, NULL, ofile, ofmt ); nframes++;
+     292             :   }
+     293             : 
+     294           2 :   ofile.close(); return 0;
+     295           8 : }
+     296             : 
+     297             : } // End of namespace
+     298             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..d7fd241ac2 --- /dev/null +++ b/coverage/mapping/PropertyMap.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping11PropertyMapC1ERKNS_13ActionOptionsE3
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe1046createERKNS_13ActionOptionsE3
_ZN4PLMD7mapping11PropertyMap16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe104C2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe104D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/PropertyMap.cpp.func.html b/coverage/mapping/PropertyMap.cpp.func.html new file mode 100644 index 0000000000..10bdef3505 --- /dev/null +++ b/coverage/mapping/PropertyMap.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:1515100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11PropertyMap16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7mapping11PropertyMapC1ERKNS_13ActionOptionsE3
_ZN4PLMD7mapping11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe1046createERKNS_13ActionOptionsE3
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe104C2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe104D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/PropertyMap.cpp.gcov.html b/coverage/mapping/PropertyMap.cpp.gcov.html new file mode 100644 index 0000000000..98f6197a15 --- /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:1515100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10425 : PLUMED_REGISTER_ACTION(PropertyMap,"GPROPERTYMAP")
+     105             : 
+     106           4 : void PropertyMap::registerKeywords( Keywords& keys ) {
+     107           4 :   PathBase::registerKeywords( keys );
+     108           4 :   ActionWithValue::useCustomisableComponents( keys );
+     109           8 :   keys.addFlag("NOMAPPING",false,"do not calculate the position on the manifold");
+     110           4 : }
+     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.15
+
+ + + 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 0000000000..d1ae2934c8 --- /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-06-10 08:19:14Functions: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_8KeywordsE3473
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeC2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeD2Ev3473
_ZN4PLMD7mapping11SpathVessel7prepareEv5460
_ZNK4PLMD7mapping11SpathVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE27391
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/SpathVessel.cpp.func.html b/coverage/mapping/SpathVessel.cpp.func.html new file mode 100644 index 0000000000..f4ec6b22b4 --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11SpathVessel14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD7mapping11SpathVessel16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD7mapping11SpathVessel16value_descriptorB5cxx11Ev10
_ZN4PLMD7mapping11SpathVessel7prepareEv5460
_ZN4PLMD7mapping11SpathVesselC2ERKNS_10vesselbase13VesselOptionsE10
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE10
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeC2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeD2Ev3473
_ZNK4PLMD7mapping11SpathVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE27391
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/SpathVessel.cpp.gcov.html b/coverage/mapping/SpathVessel.cpp.gcov.html new file mode 100644 index 0000000000..d54a808eb2 --- /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-06-10 08:19:14Functions: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       10429 : PLUMED_REGISTER_VESSEL(SpathVessel,"SPATH")
+      43             : 
+      44          10 : void SpathVessel::registerKeywords( Keywords& keys ) {
+      45          10 :   FunctionVessel::registerKeywords(keys);
+      46          10 : }
+      47             : 
+      48        3473 : void SpathVessel::reserveKeyword( Keywords& keys ) {
+      49        6946 :   keys.reserve("vessel","SPATH","docs should not appear");
+      50        6946 :   keys.addOutputComponent("spath","SPATH","the position on the path");
+      51        3473 : }
+      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.15
+
+ + + 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 0000000000..ba793d7732 --- /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-06-10 08:19:14Functions: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_133TrigonometricPathVesselRegisterMeC2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeD2Ev3473
_ZN4PLMD7mapping23TrigonometricPathVessel14reserveKeywordERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/TrigonometricPathVessel.cpp.func.html b/coverage/mapping/TrigonometricPathVessel.cpp.func.html new file mode 100644 index 0000000000..4a93a026ab --- /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-06-10 08:19:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE3
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeC2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeD2Ev3473
_ZN4PLMD7mapping23TrigonometricPathVessel10applyForceERSt6vectorIdSaIdEE1193
_ZN4PLMD7mapping23TrigonometricPathVessel11descriptionB5cxx11Ev3
_ZN4PLMD7mapping23TrigonometricPathVessel14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD7mapping23TrigonometricPathVessel16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7mapping23TrigonometricPathVessel6finishERKSt6vectorIdSaIdEE1193
_ZN4PLMD7mapping23TrigonometricPathVessel6resizeEv7
_ZN4PLMD7mapping23TrigonometricPathVesselC2ERKNS_10vesselbase13VesselOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/TrigonometricPathVessel.cpp.gcov.html b/coverage/mapping/TrigonometricPathVessel.cpp.gcov.html new file mode 100644 index 0000000000..05e0c079e8 --- /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-06-10 08:19:14Functions: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       10422 : PLUMED_REGISTER_VESSEL(TrigonometricPathVessel,"GPATH")
+      30             : 
+      31           3 : void TrigonometricPathVessel::registerKeywords( Keywords& keys ) {
+      32           3 :   StoreDataVessel::registerKeywords(keys);
+      33           3 : }
+      34             : 
+      35        3473 : void TrigonometricPathVessel::reserveKeyword( Keywords& keys ) {
+      36        6946 :   keys.reserve("vessel","GPATH","calculate the position on the path using trigonometry");
+      37        6946 :   keys.addOutputComponent("gspath","GPATH","the position on the path calculated using trigonometry");
+      38        6946 :   keys.addOutputComponent("gzpath","GPATH","the distance from the path calculated using trigonometry");
+      39        3473 : }
+      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           8 :     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        2386 :   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.15
+
+ + + 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 0000000000..4870c6b2f5 --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11ZpathVessel16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping11ZpathVessel16value_descriptorB5cxx11Ev7
_ZN4PLMD7mapping11ZpathVesselC2ERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping11ZpathVessel14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeC2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeD2Ev3473
_ZN4PLMD7mapping11ZpathVessel14finalTransformERKdRd3822
_ZNK4PLMD7mapping11ZpathVessel13calcTransformERKdRd19565
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/ZpathVessel.cpp.func.html b/coverage/mapping/ZpathVessel.cpp.func.html new file mode 100644 index 0000000000..39f26b294a --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11ZpathVessel14finalTransformERKdRd3822
_ZN4PLMD7mapping11ZpathVessel14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD7mapping11ZpathVessel16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping11ZpathVessel16value_descriptorB5cxx11Ev7
_ZN4PLMD7mapping11ZpathVesselC2ERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeC2Ev3473
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeD2Ev3473
_ZNK4PLMD7mapping11ZpathVessel13calcTransformERKdRd19565
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/ZpathVessel.cpp.gcov.html b/coverage/mapping/ZpathVessel.cpp.gcov.html new file mode 100644 index 0000000000..2086effdc8 --- /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-06-10 08:19:14Functions: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       10426 : PLUMED_REGISTER_VESSEL(ZpathVessel,"ZPATH")
+      42             : 
+      43           7 : void ZpathVessel::registerKeywords( Keywords& keys ) {
+      44           7 :   FunctionVessel::registerKeywords(keys);
+      45           7 : }
+      46             : 
+      47        3473 : void ZpathVessel::reserveKeyword( Keywords& keys ) {
+      48        6946 :   keys.reserve("vessel","ZPATH","calculate the distance from the low dimensionality manifold");
+      49        6946 :   keys.addOutputComponent("zpath","ZPATH","the distance from the path");
+      50        3473 : }
+      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.15
+
+ + + diff --git a/coverage/mapping/index-sort-f.html b/coverage/mapping/index-sort-f.html new file mode 100644 index 0000000000..02ff1f4bcb --- /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-06-10 08:19:14Functions:879888.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Mapping.cpp +
78.1%78.1%
+
78.1 %82 / 10563.6 %7 / 11
Mapping.h +
92.3%92.3%
+
92.3 %12 / 1380.0 %4 / 5
Path.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
PropertyMap.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
PCAVars.cpp +
88.2%88.2%
+
88.2 %127 / 14483.3 %10 / 12
PathBase.cpp +
100.0%
+
100.0 %35 / 3585.7 %6 / 7
AdaptivePath.cpp +
96.2%96.2%
+
96.2 %100 / 10490.9 %10 / 11
PathReparameterization.cpp +
100.0%
+
100.0 %65 / 65100.0 %5 / 5
PathTools.cpp +
98.3%98.3%
+
98.3 %119 / 121100.0 %7 / 7
ZpathVessel.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
SpathVessel.cpp +
100.0%
+
100.0 %29 / 29100.0 %9 / 9
TrigonometricPathVessel.cpp +
97.1%97.1%
+
97.1 %134 / 138100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/mapping/index-sort-l.html b/coverage/mapping/index-sort-l.html new file mode 100644 index 0000000000..c992812def --- /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-06-10 08:19:14Functions:879888.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Mapping.cpp +
78.1%78.1%
+
78.1 %82 / 10563.6 %7 / 11
PCAVars.cpp +
88.2%88.2%
+
88.2 %127 / 14483.3 %10 / 12
Mapping.h +
92.3%92.3%
+
92.3 %12 / 1380.0 %4 / 5
AdaptivePath.cpp +
96.2%96.2%
+
96.2 %100 / 10490.9 %10 / 11
TrigonometricPathVessel.cpp +
97.1%97.1%
+
97.1 %134 / 138100.0 %10 / 10
PathTools.cpp +
98.3%98.3%
+
98.3 %119 / 121100.0 %7 / 7
Path.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
PropertyMap.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
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.15
+
+ + + diff --git a/coverage/mapping/index.html b/coverage/mapping/index.html new file mode 100644 index 0000000000..60a34aad7f --- /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-06-10 08:19:14Functions:879888.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AdaptivePath.cpp +
96.2%96.2%
+
96.2 %100 / 10490.9 %10 / 11
Mapping.cpp +
78.1%78.1%
+
78.1 %82 / 10563.6 %7 / 11
Mapping.h +
92.3%92.3%
+
92.3 %12 / 1380.0 %4 / 5
PCAVars.cpp +
88.2%88.2%
+
88.2 %127 / 14483.3 %10 / 12
Path.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
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.3%98.3%
+
98.3 %119 / 121100.0 %7 / 7
PropertyMap.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
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.15
+
+ + + 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 0000000000..cebbf83e5d --- /dev/null +++ b/coverage/maze/Loss.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2424100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4LossC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe626createERKNS_13ActionOptionsE8
_ZN4PLMD4maze4LossC1ERKNS_13ActionOptionsE8
_ZN4PLMD4maze4Loss16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe62C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe62D2Ev3473
_ZN4PLMD4maze4Loss7pairingEd14974890
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Loss.cpp.func.html b/coverage/maze/Loss.cpp.func.html new file mode 100644 index 0000000000..390a999cf7 --- /dev/null +++ b/coverage/maze/Loss.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:2424100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe626createERKNS_13ActionOptionsE8
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe62C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe62D2Ev3473
_ZN4PLMD4maze4Loss16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4maze4Loss7pairingEd14974890
_ZN4PLMD4maze4LossC1ERKNS_13ActionOptionsE8
_ZN4PLMD4maze4LossC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Loss.cpp.gcov.html b/coverage/maze/Loss.cpp.gcov.html new file mode 100644 index 0000000000..d418cbd5fe --- /dev/null +++ b/coverage/maze/Loss.cpp.gcov.html @@ -0,0 +1,190 @@ + + + + + + + + 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:2424100.0 %
Date:2024-06-10 08:19:14Functions:6785.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             : 
+      23             : /**
+      24             :  * @file Loss.cpp
+      25             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      26             :  */
+      27             : 
+      28             : #include "Loss.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace maze {
+      32             : 
+      33             : //+PLUMEDOC MAZE_LOSS MAZE_LOSS
+      34             : /*
+      35             : 
+      36             : Define a coarse-grained loss function describing interactions in a
+      37             : ligand-protein complex, which is minimized during the simulation to
+      38             : obtain ligand unbinding pathways.
+      39             : 
+      40             : The loss function is the following:
+      41             : \f[
+      42             : \mathcal{L}=
+      43             : \sum_{i=1}^{N_p}
+      44             : r_i^{-\alpha}\text{e}^{-\beta r_i^{-\gamma}},
+      45             : \f]
+      46             : where \f$N_p\f$ is the number of ligand-protein atom pairs, \f$r\f$
+      47             : is a re-scaled distance between the \f$i\f$th pair, and \f$\alpha,
+      48             : \beta, \gamma\f$ are the positive parameters defined in that order by
+      49             : the PARAMS keyword.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : The loss function can be defined in the following way:
+      54             : \plumedfile
+      55             : l: MAZE_LOSS PARAMS=1,1,1
+      56             : \endplumedfile
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : // Registers the LOSS action.
+      62       10435 : PLUMED_REGISTER_ACTION(Loss, "MAZE_LOSS")
+      63             : 
+      64           9 : void Loss::registerKeywords(Keywords& keys) {
+      65           9 :   Colvar::registerKeywords(keys);
+      66             : 
+      67          18 :   keys.add(
+      68             :     "compulsory",
+      69             :     "PARAMS",
+      70             :     "Parameters for the loss function."
+      71             :   );
+      72           9 : }
+      73             : 
+      74           8 : Loss::Loss(const ActionOptions& ao)
+      75           8 :   : PLUMED_COLVAR_INIT(ao)
+      76             : {
+      77          16 :   if (keywords.exists("PARAMS")) {
+      78          16 :     parseVector("PARAMS", params_);
+      79             : 
+      80           8 :     plumed_massert(
+      81             :       params_.size() == 3,
+      82             :       "maze> PARAMS should be of size 3: alpha, beta, gamma\n"
+      83             :     );
+      84             : 
+      85           8 :     plumed_massert(
+      86             :       params_[0] > 0 && params_[1] > 0 && params_[2] > 0,
+      87             :       "maze> Each parameter should be positive\n"
+      88             :     );
+      89             : 
+      90           8 :     log.printf("maze> \t Loss parsed with parameters: ");
+      91          32 :     for (size_t i = 0; i < params_.size(); ++i) {
+      92          24 :       log.printf("%f ", params_[i]);
+      93             :     }
+      94           8 :     log.printf("\n");
+      95             :   }
+      96             : 
+      97           8 :   checkRead();
+      98           8 : }
+      99             : 
+     100    14974890 : double Loss::pairing(double distance) {
+     101    14974890 :   double alpha = params_[0];
+     102    14974890 :   double beta = params_[1];
+     103    14974890 :   double gamma = params_[2];
+     104             : 
+     105    14974890 :   if (atoms.getUnits().getLengthString() == "nm") {
+     106    14855760 :     distance *= 10.0;
+     107             :   }
+     108             : 
+     109    14974890 :   return pow(distance, -alpha) * exp(-beta * pow(distance, gamma));
+     110             : }
+     111             : 
+     112             : } // namespace maze
+     113             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..3cf4b2e84b --- /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-06-10 08:19:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss9calculateEv0
_ZN4PLMD4maze4LossD0Ev8
_ZN4PLMD4maze4LossD1Ev8
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Loss.h.func.html b/coverage/maze/Loss.h.func.html new file mode 100644 index 0000000000..d0a20d8499 --- /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-06-10 08:19:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss9calculateEv0
_ZN4PLMD4maze4LossD0Ev8
_ZN4PLMD4maze4LossD1Ev8
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Loss.h.gcov.html b/coverage/maze/Loss.h.gcov.html new file mode 100644 index 0000000000..b7738e40b6 --- /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-06-10 08:19:14Functions: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          24 :   ~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.15
+
+ + + 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 0000000000..2f8ef65ff9 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev324
_ZN4PLMD4maze7compareERNS0_6MemberES2_410
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Member.h.func.html b/coverage/maze/Member.h.func.html new file mode 100644 index 0000000000..3647d32320 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev324
_ZN4PLMD4maze7compareERNS0_6MemberES2_410
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Member.h.gcov.html b/coverage/maze/Member.h.gcov.html new file mode 100644 index 0000000000..f556ab9ba2 --- /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-06-10 08:19:14Functions: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         324 :   Member()
+      49         324 :     : score(-1),
+      50         324 :       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         410 : inline bool compare(Member& m, Member& n) {
+      60         410 :   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.15
+
+ + + 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 0000000000..e3e9b6f701 --- /dev/null +++ b/coverage/maze/Memetic.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:6464100.0 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7MemeticC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze7MemeticD2Ev0
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe836createERKNS_13ActionOptionsE2
_ZN4PLMD4maze7MemeticC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze7MemeticD0Ev2
_ZN4PLMD4maze7MemeticD1Ev2
_ZN4PLMD4maze7Memetic16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze7Memetic8optimizeEv6
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe83C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe83D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Memetic.cpp.func.html b/coverage/maze/Memetic.cpp.func.html new file mode 100644 index 0000000000..e5e5b4ee2d --- /dev/null +++ b/coverage/maze/Memetic.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:6464100.0 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe836createERKNS_13ActionOptionsE2
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe83C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe83D2Ev3473
_ZN4PLMD4maze7Memetic16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze7Memetic8optimizeEv6
_ZN4PLMD4maze7MemeticC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze7MemeticC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze7MemeticD0Ev2
_ZN4PLMD4maze7MemeticD1Ev2
_ZN4PLMD4maze7MemeticD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Memetic.cpp.gcov.html b/coverage/maze/Memetic.cpp.gcov.html new file mode 100644 index 0000000000..3c25061f5b --- /dev/null +++ b/coverage/maze/Memetic.cpp.gcov.html @@ -0,0 +1,365 @@ + + + + + + + + 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:6464100.0 %
Date:2024-06-10 08:19:14Functions:81080.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       10423 : PLUMED_REGISTER_ACTION(Memetic, "MAZE_MEMETIC_SAMPLING")
+      84             : 
+      85           3 : void Memetic::registerKeywords(Keywords& keys) {
+      86           3 :   Optimizer::registerKeywords(keys);
+      87             : 
+      88           6 :   keys.add(
+      89             :     "compulsory",
+      90             :     "CAPACITY",
+      91             :     "Sampling set size."
+      92             :   );
+      93             : 
+      94           6 :   keys.add(
+      95             :     "compulsory",
+      96             :     "MUTATION_RATE",
+      97             :     "Probability of mutation."
+      98             :   );
+      99             : 
+     100           6 :   keys.add(
+     101             :     "compulsory",
+     102             :     "MATING_RATE",
+     103             :     "Probability of mating."
+     104             :   );
+     105             : 
+     106           6 :   keys.add(
+     107             :     "compulsory",
+     108             :     "CAUCHY_ALPHA",
+     109             :     "Mean of Cauchy distribution for sampling."
+     110             :   );
+     111             : 
+     112           6 :   keys.add(
+     113             :     "compulsory",
+     114             :     "CAUCHY_BETA",
+     115             :     "Spread of Cauchy distribution for sampling."
+     116             :   );
+     117             : 
+     118           6 :   keys.addFlag(
+     119             :     "LOCAL_SEARCH_ON",
+     120             :     false,
+     121             :     "Turn local search on."
+     122             :   );
+     123             : 
+     124           6 :   keys.add(
+     125             :     "optional",
+     126             :     "N_LOCAL_ITER",
+     127             :     "Number of local search iterations."
+     128             :   );
+     129             : 
+     130           9 :   keys.add(
+     131             :     "optional",
+     132             :     "LOCAL_SEARCH_RATE",
+     133             :     "Rate of mutation in local search."
+     134             :   );
+     135             : 
+     136           9 :   keys.add(
+     137             :     "optional",
+     138             :     "LOCAL_SEARCH_TYPE",
+     139             :     "Type of local search."
+     140             :   );
+     141           3 : }
+     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           4 : Memetic::~Memetic() {
+     275           2 :   delete neighbor_list_;
+     276             : 
+     277             :   members_.clear();
+     278           4 : }
+     279             : 
+     280           6 : void Memetic::optimize() {
+     281           6 :   Vector t = solve();
+     282             : 
+     283             :   set_opt(t);
+     284           6 :   set_opt_value(score());
+     285           6 : }
+     286             : 
+     287             : } // namespace maze
+     288             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..6602b1f573 --- /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:11120155.2 %
Date:2024-06-10 08:19:14Functions:132065.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
_ZN4PLMD4maze7Memetic9crossoverERNS0_6MemberES3_0
_ZNK4PLMD4maze7Memetic12print_statusEv0
_ZN4PLMD4maze7Memetic18initialize_membersEv6
_ZN4PLMD4maze7Memetic5solveEv6
_ZN4PLMD4maze7Memetic24stochastic_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE7
_ZN4PLMD4maze7Memetic12local_searchERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic12sort_membersEv30
_ZN4PLMD4maze7Memetic13score_membersEv30
_ZN4PLMD4maze7Memetic18selection_rouletteEv30
_ZN4PLMD4maze7Memetic6matingERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic8mutationERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic13create_codingEv36
_ZN4PLMD4maze7Memetic13out_of_boundsEd79
_ZN4PLMD4maze7Memetic8mutationERNS0_6MemberE79
_ZN4PLMD4maze7Memetic12score_memberERKNS_13VectorGenericILj3EEE250
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Memetic.h.func.html b/coverage/maze/Memetic.h.func.html new file mode 100644 index 0000000000..34eb09b641 --- /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:11120155.2 %
Date:2024-06-10 08:19:14Functions:132065.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7Memetic10score_meanEv0
_ZN4PLMD4maze7Memetic12local_searchERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic12luus_jaakolaERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic12score_memberERKNS_13VectorGenericILj3EEE250
_ZN4PLMD4maze7Memetic12sort_membersEv30
_ZN4PLMD4maze7Memetic13create_codingEv36
_ZN4PLMD4maze7Memetic13out_of_boundsEd79
_ZN4PLMD4maze7Memetic13score_membersEv30
_ZN4PLMD4maze7Memetic18initialize_membersEv6
_ZN4PLMD4maze7Memetic18selection_rouletteEv30
_ZN4PLMD4maze7Memetic22adaptive_random_searchERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic24stochastic_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE7
_ZN4PLMD4maze7Memetic28random_restart_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic5solveEv6
_ZN4PLMD4maze7Memetic6matingERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic8mutationERNS0_6MemberE79
_ZN4PLMD4maze7Memetic8mutationERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic9annealingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic9crossoverERNS0_6MemberES3_0
_ZNK4PLMD4maze7Memetic12print_statusEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Memetic.h.gcov.html b/coverage/maze/Memetic.h.gcov.html new file mode 100644 index 0000000000..63ffcfd53a --- /dev/null +++ b/coverage/maze/Memetic.h.gcov.html @@ -0,0 +1,888 @@ + + + + + + + + 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:11120155.2 %
Date:2024-06-10 08:19:14Functions:132065.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             :    * Destructor required for deriving classes.
+      56             :    */
+      57             :   ~Memetic();
+      58             : 
+      59             :   /**
+      60             :    * Registers PLMD keywords.
+      61             :    *
+      62             :    * @param[in] keys Keywords.
+      63             :    */
+      64             :   static void registerKeywords(Keywords& keys);
+      65             : 
+      66             :   /**
+      67             :    * Each class deriving from Optimizer needs to override this function.
+      68             :    */
+      69             :   void optimize() override;
+      70             : 
+      71             : private:
+      72             :   /**
+      73             :    * Create a set of translations relative to the ligand, each translation
+      74             :    * encodes a probable biasing direction.
+      75             :    */
+      76             :   void initialize_members();
+      77             : 
+      78             :   /**
+      79             :    * Score each translation by the loss function.
+      80             :    */
+      81             :   void score_members();
+      82             : 
+      83             :   /**
+      84             :    * Calculate the mean score.
+      85             :    */
+      86             :   double score_mean();
+      87             : 
+      88             :   /**
+      89             :    * Sort the population using heaps, required for finding a minimum of the loss
+      90             :    * function.
+      91             :    */
+      92             :   void sort_members();
+      93             : 
+      94             :   /**
+      95             :    * Encode a ligand conformation.
+      96             :    */
+      97             :   Vector create_coding();
+      98             : 
+      99             :   /**
+     100             :    * Check if the vector length is out of bounds.
+     101             :    *
+     102             :    * @param[in] v Vector length.
+     103             :    */
+     104             :   bool out_of_bounds(double v);
+     105             : 
+     106             :   /**
+     107             :    * Score a single member.
+     108             :    *
+     109             :    * @param[in] v Member's translation.
+     110             :    */
+     111             :   double score_member(const Vector& v);
+     112             : 
+     113             :   /**
+     114             :    * Print a status.
+     115             :    */
+     116             :   void print_status() const;
+     117             : 
+     118             :   /**
+     119             :    * Select a new population using the roulette selection.
+     120             :    */
+     121             :   void selection_roulette();
+     122             : 
+     123             :   /**
+     124             :    * Perform mating in the population.
+     125             :    *
+     126             :    * @param[in,out] members Population.
+     127             :    */
+     128             :   void mating(std::vector<Member>& members);
+     129             : 
+     130             :   /**
+     131             :    * Mate two members.
+     132             :    *
+     133             :    * @param[in,out] m1 1st member.
+     134             :    * @param[in,out] m2 2nd member.
+     135             :    */
+     136             :   void crossover(Member& m1, Member& m2);
+     137             : 
+     138             :   /**
+     139             :    * Mutate a member.
+     140             :    *
+     141             :    * @param[in,out] m Member.
+     142             :    */
+     143             :   void mutation(Member& m);
+     144             : 
+     145             :   /**
+     146             :    * Mutate the population.
+     147             :    *
+     148             :    * @param[in,out] members Population.
+     149             :    */
+     150             :   void mutation(std::vector<Member>& members);
+     151             : 
+     152             : protected:
+     153             :   /**
+     154             :    * Local searches to improve global solutions.
+     155             :    */
+     156             : 
+     157             :   /**
+     158             :    * Stochastic hill climbing.
+     159             :    *
+     160             :    * Neighbors with better or equal cost should be accepted, allowing the
+     161             :    * technique to navigate across plateaus in the response surface.
+     162             :    *
+     163             :    * @param[in,out] m Member.
+     164             :    * @param[in] params None.
+     165             :    */
+     166             :   void stochastic_hill_climbing(
+     167             :     Member& m,
+     168             :     /* none */ const std::vector<double>& params = {}
+     169             :   );
+     170             : 
+     171             :   /**
+     172             :    * Random-restart hill climbing.
+     173             :    *
+     174             :    * The algorithm can be restarted and repeated a number of  times after it
+     175             :    * converges to provide an improved result.
+     176             :    *
+     177             :    * @param[in,out] m Member.
+     178             :    * @param[in] params Number of restarts.
+     179             :    */
+     180             :   void random_restart_hill_climbing(
+     181             :     Member& m,
+     182             :     /* n_restarts */ const std::vector<double>& params = {10}
+     183             :   );
+     184             : 
+     185             :   /**
+     186             :    * Solis-Wets random walk.
+     187             :    *
+     188             :    * Adaptive random search algorithm was designed to address the limitations of
+     189             :    * the fixed step size. The strategy for adaptive random search is to
+     190             :    * continually approximate the optimal step size required to reach the global
+     191             :    * optimum in the search space. This is achieved by trialling and adopting
+     192             :    * smaller or larger step sizes only if they result in an improvement in the
+     193             :    * search performance.
+     194             :    *
+     195             :    * Very large step sizes are trialled with a much lower frequency. This
+     196             :    * strategy of preferring large moves is intended to allow the technique to
+     197             :    * escape local optima. Smaller step sizes are adopted if no improvement is
+     198             :    * made for an extended period.
+     199             :    *
+     200             :    * @param[in,out] m Member.
+     201             :    * @param[in] params
+     202             :    */
+     203             :   void adaptive_random_search(
+     204             :     Member& m,
+     205             :     /* */ const std::vector<double>& params = {1.0, 1.e-5, 2.0, 2.0, 3.0, 3.0}
+     206             :   );
+     207             : 
+     208             :   /**
+     209             :    * Luus–Jaakola heuristics.
+     210             :    *
+     211             :    * @param[in,out] m Member.
+     212             :    * @param[in] params Bounds.
+     213             :    */
+     214             :   void luus_jaakola(
+     215             :     Member& m,
+     216             :     /* bounds */ const std::vector<double>& params
+     217             :   );
+     218             : 
+     219             :   /**
+     220             :    * Local annealing.
+     221             :    *
+     222             :    * @param[in,out] m Member.
+     223             :    * @param[in] params T, alpha.
+     224             :    */
+     225             :   void annealing(
+     226             :     Member& m,
+     227             :     /* T, alpha */const std::vector<double>& params = {300.0, 0.95}
+     228             :   );
+     229             : 
+     230             :   /**
+     231             :    * Apply local search to members.
+     232             :    *
+     233             :    * @param[in,out] members Population.
+     234             :    */
+     235             :   void local_search(std::vector<Member>& members);
+     236             : 
+     237             : protected:
+     238             :   /**
+     239             :    * Return an optimal biasing direction.
+     240             :    */
+     241             :   Vector solve();
+     242             : 
+     243             : public:
+     244             :   /**
+     245             :    * Setters and getters.
+     246             :    */
+     247             : 
+     248             :   unsigned int get_capacity() const;
+     249             :   void set_capacity(unsigned int);
+     250             : 
+     251             :   unsigned int get_coding_len() const;
+     252             :   void set_coding_len(unsigned int);
+     253             : 
+     254             :   unsigned int get_n_local_iterations() const;
+     255             :   void set_n_local_iterations(unsigned int);
+     256             : 
+     257             :   unsigned int get_n_global_iterations() const;
+     258             :   void set_n_global_iterations(unsigned int);
+     259             : 
+     260             :   double get_mutation_rate() const;
+     261             :   void set_mutation_rate(double);
+     262             : 
+     263             :   double get_mating_rate() const;
+     264             :   void set_mating_rate(double);
+     265             : 
+     266             :   double get_cauchy_mean() const;
+     267             :   void set_cauchy_mean(double);
+     268             : 
+     269             :   double get_cauchy_spread() const;
+     270             :   void set_cauchy_spread(double);
+     271             : 
+     272             :   bool is_local_search_on() const;
+     273             :   void local_search_on();
+     274             :   void local_search_off();
+     275             : 
+     276             :   double get_local_search_rate() const;
+     277             :   void set_local_search_rate(double);
+     278             : 
+     279             :   std::string get_local_search_type() const;
+     280             :   void set_local_search_type(const std::string&);
+     281             : 
+     282             : protected:
+     283             :   //! Population
+     284             :   std::vector<Member> members_;
+     285             : 
+     286             :   //! Bound
+     287             :   double bound_;
+     288             : 
+     289             :   //! Scores
+     290             :   double score_worst_;
+     291             :   double score_best_;
+     292             :   Member member_best_;
+     293             : 
+     294             :   //! If a local search is performed
+     295             :   bool adaptation_;
+     296             : 
+     297             : protected:
+     298             :   //! Size of population
+     299             :   unsigned int capacity_;
+     300             :   //! Length of coding
+     301             :   unsigned int coding_len_;
+     302             : 
+     303             :   //! Number of local search iterations
+     304             :   unsigned int n_local_iterations_;
+     305             :   //! Number of global search iterations, doomsday
+     306             :   unsigned int n_global_iterations_;
+     307             : 
+     308             :   //! Probability of mutation
+     309             :   double mutation_rate_;
+     310             :   //! Probability of mating
+     311             :   double mating_rate_;
+     312             : 
+     313             :   //! Mean and spread of cauchy sampler
+     314             :   double cauchy_mean_alpha_;
+     315             :   double cauchy_mean_beta_;
+     316             : 
+     317             :   //! If local search is employed in sampling
+     318             :   bool local_search_on_;
+     319             :   //! Rate of local mutation
+     320             :   double local_search_rate_;
+     321             :   //! Type of local search, stochastic_hill_climbing or adaptive_random_search
+     322             :   std::string local_search_type_;
+     323             : };
+     324             : 
+     325           6 : void Memetic::initialize_members() {
+     326           6 :   members_.clear();
+     327           6 :   members_.resize(capacity_);
+     328             : 
+     329          42 :   for (size_t i = 0; i < capacity_; ++i) {
+     330          36 :     Member m{};
+     331             : 
+     332          36 :     m.score=0;
+     333          36 :     m.translation=create_coding();
+     334             : 
+     335          36 :     members_.at(i) = m;
+     336             :   }
+     337           6 : }
+     338             : 
+     339          30 : void Memetic::score_members() {
+     340         210 :   for (size_t i = 0; i < members_.size(); ++i) {
+     341         180 :     double s = score_member(members_[i].translation);
+     342         180 :     members_[i].score=s;
+     343             :   }
+     344          30 : }
+     345             : 
+     346          30 : void Memetic::sort_members() {
+     347          30 :   std::make_heap(
+     348             :     members_.begin(),
+     349             :     members_.end(),
+     350             :     compare
+     351             :   );
+     352             : 
+     353          30 :   std::sort_heap(
+     354             :     members_.begin(),
+     355             :     members_.end(),
+     356             :     compare
+     357             :   );
+     358             : 
+     359          30 :   member_best_ = members_[capacity_ - 1];
+     360          30 :   score_best_ = members_[capacity_ - 1].score;
+     361          30 :   score_worst_ = members_[0].score;
+     362          30 : }
+     363             : 
+     364           0 : double Memetic::score_mean() {
+     365           0 :   auto acc = [](double s, const Member& m) { return s + m.score; };
+     366             : 
+     367             :   return std::accumulate(
+     368             :            members_.begin(),
+     369             :            members_.end(),
+     370             :            0.0,
+     371           0 :            acc) / capacity_;
+     372             : }
+     373             : 
+     374          30 : void Memetic::selection_roulette() {
+     375          30 :   std::vector<Member> sel(members_);
+     376          30 :   std::vector<double> rel_scores(capacity_, 0.0);
+     377             : 
+     378         210 :   for (std::size_t i = 0; i < capacity_; ++i) {
+     379         180 :     double r = 1.0 / (members_[i].score + 0.01);
+     380         180 :     rel_scores.at(i) = r;
+     381             :   }
+     382             : 
+     383          30 :   std::vector<double> cum_sum(capacity_, 0.0);
+     384          30 :   std::partial_sum(
+     385             :     rel_scores.begin(),
+     386             :     rel_scores.end(),
+     387             :     cum_sum.begin(),
+     388             :     std::plus<double>()
+     389             :   );
+     390             : 
+     391          30 :   double sum = cum_sum.back();
+     392             :   members_.clear();
+     393          30 :   members_.resize(capacity_);
+     394             :   int chosen = -1;
+     395             : 
+     396         210 :   for (size_t j = 0; j < capacity_; ++j) {
+     397             :     double probability=rnd::next_double(sum);
+     398         651 :     for (size_t i = 0; i < cum_sum.size(); ++i) {
+     399         651 :       if (cum_sum[i] > probability) {
+     400         180 :         chosen = i;
+     401             : 
+     402         360 :         members_.at(j).score = sel.at(chosen).score;
+     403         180 :         members_.at(j).translation = sel.at(chosen).translation;
+     404             : 
+     405         180 :         break;
+     406             :       }
+     407             :     }
+     408             :   }
+     409          30 : }
+     410             : 
+     411           0 : void Memetic::crossover(Member& s1, Member& s2) {
+     412           0 :   size_t i = rnd::next_int(1, coding_len_ - 1);
+     413             : 
+     414           0 :   Member z1(s1);
+     415           0 :   Member z2(s2);
+     416             : 
+     417           0 :   for (size_t j = i; j < coding_len_; ++j) {
+     418           0 :     z1.translation[j] = s2.translation[j];
+     419           0 :     z2.translation[j] = s1.translation[j];
+     420             :   }
+     421             : 
+     422           0 :   if (!out_of_bounds(z1.translation.modulo()) && !out_of_bounds(z2.translation.modulo())) {
+     423           0 :     s1 = z1;
+     424           0 :     s2 = z2;
+     425             :   }
+     426           0 : }
+     427             : 
+     428          79 : void Memetic::mutation(Member& m) {
+     429          79 :   int which = rnd::next_int(coding_len_);
+     430          79 :   double v = rnd::next_cauchy(cauchy_mean_alpha_, cauchy_mean_beta_);
+     431          79 :   m.translation[which] += v;
+     432          79 :   if (out_of_bounds(m.translation.modulo())) {
+     433          26 :     m.translation[which] -= v;
+     434             :   }
+     435          79 : }
+     436             : 
+     437          30 : void Memetic::mutation(std::vector<Member>& m) {
+     438         210 :   for (std::vector<Member>::iterator it = m.begin(), end = m.end(); it != end; ++it) {
+     439         180 :     double r = rnd::next_double();
+     440         180 :     if (r < mutation_rate_) {
+     441           9 :       mutation(*it);
+     442             :     }
+     443             :   }
+     444          30 : }
+     445             : 
+     446           7 : void Memetic::stochastic_hill_climbing(
+     447             :   Member& m,
+     448             :   const std::vector<double>& params)
+     449             : {
+     450          77 :   for (std::size_t i = 0; i < n_local_iterations_; ++i) {
+     451          70 :     Member n;
+     452          70 :     n.translation = m.translation;
+     453          70 :     mutation(n);
+     454          70 :     double score_n = score_member(n.translation);
+     455             : 
+     456          70 :     if (m.score > score_n) {
+     457          22 :       m.translation = n.translation;
+     458             :     }
+     459             :   }
+     460           7 : }
+     461             : 
+     462           0 : void Memetic::random_restart_hill_climbing(
+     463             :   Member& m,
+     464             :   const std::vector<double>& params)
+     465             : {
+     466           0 :   unsigned int n_restarts = static_cast<int>(params[0]);
+     467           0 :   std::vector<Member> s(n_restarts);
+     468             :   unsigned int ndx = 0;
+     469           0 :   double min = m.score;
+     470             : 
+     471           0 :   for (std::size_t r = 0; r < n_restarts; ++r) {
+     472           0 :     Member n = m;
+     473           0 :     stochastic_hill_climbing(n);
+     474           0 :     s[r] = n;
+     475             : 
+     476           0 :     if (min > n.score) {
+     477             :       min = n.score;
+     478           0 :       ndx = r;
+     479             :     }
+     480             :   }
+     481             : 
+     482           0 :   m = s[ndx];
+     483           0 : }
+     484             : 
+     485           0 : void Memetic::annealing(
+     486             :   Member& m,
+     487             :   const std::vector<double>& params)
+     488             : {
+     489           0 :   double T = params[0];
+     490           0 :   double alpha = params[1];
+     491             : 
+     492           0 :   for (std::size_t i = 0; i < n_local_iterations_; ++i) {
+     493           0 :     Member n = m;
+     494           0 :     mutation(n);
+     495           0 :     double score_n = score_member(n.translation);
+     496             : 
+     497             :     double probability = std::min(
+     498           0 :                            1.0,
+     499           0 :                            std::exp(-(score_n - m.score) / T)
+     500           0 :                          );
+     501             : 
+     502           0 :     double r = rnd::next_double();
+     503             : 
+     504           0 :     if (r < probability) {
+     505           0 :       m = n;
+     506             :     }
+     507             : 
+     508           0 :     T *= alpha;
+     509             :   }
+     510           0 : }
+     511             : 
+     512           0 : void Memetic::luus_jaakola(
+     513             :   Member& m,
+     514             :   const std::vector<double>& params)
+     515             : {
+     516             :   /* TODO */
+     517           0 : }
+     518             : 
+     519           0 : void Memetic::adaptive_random_search(
+     520             :   Member& m,
+     521             :   const std::vector<double>& params)
+     522             : {
+     523           0 :   double rho_start = params[0];
+     524           0 :   double rho_lower_bound = params[1];
+     525           0 :   double ex = params[2];
+     526           0 :   double ct = params[3];
+     527           0 :   int s_ex = static_cast<int>(params[4]);
+     528           0 :   int f_ct = static_cast<int>(params[5]);
+     529             : 
+     530             :   unsigned int k = 0;
+     531           0 :   Vector xk = m.translation;
+     532             :   int ns = 0;
+     533             :   int nf = 0;
+     534           0 :   Vector bk;
+     535           0 :   bk.zero();
+     536             :   double rho_k = rho_start;
+     537             : 
+     538           0 :   while (rho_k > rho_lower_bound && k < n_local_iterations_) {
+     539           0 :     if (ns >= s_ex) {
+     540           0 :       rho_k *= ex;
+     541             :     }
+     542           0 :     else if (nf >= f_ct) {
+     543           0 :       rho_k *= ct;
+     544             :     }
+     545             : 
+     546           0 :     std::vector<double> chiv = rnd::next_double(-rho_k, rho_k, 3);
+     547           0 :     Vector chi = tls::vector2Vector(chiv);
+     548           0 :     Vector tmp;
+     549             : 
+     550           0 :     for (unsigned int i = 0; i < 3; ++i) {
+     551           0 :       tmp[i] = 2.0 * (xk[i] - chi[i]);
+     552             :     }
+     553             : 
+     554           0 :     double score_chi = score_member(chi);
+     555           0 :     double score_xk = score_member(xk);
+     556           0 :     double score_tmp = score_member(tmp);
+     557             : 
+     558           0 :     if (score_chi < score_xk) {
+     559           0 :       ns++;
+     560             :       nf = 0;
+     561             : 
+     562           0 :       for (unsigned int i = 0; i < 3; i++) {
+     563           0 :         bk[i] = 0.2 * bk[i] + 0.4 * (chi[i] - xk[i]);
+     564           0 :         xk[i] = chi[i];
+     565             :       }
+     566             :     }
+     567           0 :     else if (score_tmp < score_xk && score_xk <= score_chi) {
+     568           0 :       ns++;
+     569             :       nf = 0;
+     570             : 
+     571           0 :       for (unsigned int i = 0; i < 3; i++) {
+     572           0 :         bk[i] = bk[i] - 0.4 * (chi[i] - xk[i]);
+     573           0 :         xk[i] = 2.0 * xk[i] - chi[i];
+     574             :       }
+     575             :     }
+     576             :     else {
+     577             :       ns = 0;
+     578           0 :       nf++;
+     579             : 
+     580           0 :       for (unsigned int i = 0; i < 3; i++) {
+     581           0 :         bk[i] = 0.5 * bk[i];
+     582             :       }
+     583             :     }
+     584             : 
+     585           0 :     k++;
+     586             :   }
+     587             : 
+     588           0 :   m.translation = xk;
+     589           0 : }
+     590             : 
+     591          30 : void Memetic::local_search(std::vector<Member>& m) {
+     592          30 :   adaptation_ = true;
+     593             : 
+     594          30 :   if (local_search_on_) {
+     595         105 :     for (std::size_t i = 0; i < capacity_; ++i) {
+     596          90 :       double probability = rnd::next_double();
+     597             : 
+     598          90 :       if (probability < local_search_rate_) {
+     599           7 :         if (local_search_type_ == "stochastic_hill_climbing")
+     600          14 :           stochastic_hill_climbing(m[i]);
+     601           0 :         else if (local_search_type_ == "adaptive_random_search")
+     602           0 :           adaptive_random_search(m[i]);
+     603           0 :         else if (local_search_type_ == "random_restart_hill_climbing")
+     604           0 :           random_restart_hill_climbing(m[i]);
+     605             :       }
+     606             :     }
+     607             :   }
+     608             : 
+     609          30 :   adaptation_ = false;
+     610          30 : }
+     611             : 
+     612          30 : void Memetic::mating(std::vector<Member>& m) {
+     613             :   std::vector<Member> offspring;
+     614             : 
+     615         120 :   while (m.size() != 0) {
+     616          90 :     int j = rnd::next_int(m.size());
+     617          90 :     int i = rnd::next_int(m.size());
+     618             : 
+     619         129 :     while (i == j) {
+     620          39 :       j=rnd::next_int(m.size());
+     621             :     }
+     622             : 
+     623          90 :     Member m1 = m[i];
+     624          90 :     Member m2 = m[j];
+     625             : 
+     626          90 :     if (i > j) {
+     627             :       m.erase(m.begin() + i);
+     628             :       m.erase(m.begin() + j);
+     629             :     }
+     630          39 :     else if (j > i) {
+     631             :       m.erase(m.begin() + j);
+     632             :       m.erase(m.begin() + i);
+     633             :     }
+     634             : 
+     635          90 :     double probability = rnd::next_double();
+     636          90 :     if (probability < mating_rate_) {
+     637           0 :       crossover(m1, m2);
+     638             :     }
+     639             : 
+     640          90 :     offspring.push_back(m1);
+     641          90 :     offspring.push_back(m2);
+     642             :   }
+     643             : 
+     644          30 :   m = offspring;
+     645             :   offspring.clear();
+     646          30 : }
+     647             : 
+     648          36 : Vector Memetic::create_coding() {
+     649          36 :   double s = sampling_radius();
+     650             :   double r = rnd::next_double(s);
+     651             : 
+     652          36 :   return rnd::next_plmd_vector(r);
+     653             : }
+     654             : 
+     655          79 : bool Memetic::out_of_bounds(double v) {
+     656          79 :   double s = sampling_radius();
+     657             : 
+     658          79 :   return v > s;
+     659             : }
+     660             : 
+     661         250 : double Memetic::score_member(const Vector& coding) {
+     662             :   double action = 0;
+     663         250 :   Vector distance;
+     664         250 :   const unsigned nl_size = neighbor_list_->size();
+     665         250 :   Vector dev = coding;
+     666             : 
+     667         250 :   #pragma omp parallel num_threads(get_n_threads_openmp())
+     668             :   {
+     669             :     #pragma omp for reduction(+:action)
+     670             :     for (unsigned int i = 0; i < nl_size; i++) {
+     671             :       unsigned i0 = neighbor_list_->getClosePair(i).first;
+     672             :       unsigned i1 = neighbor_list_->getClosePair(i).second;
+     673             : 
+     674             :       if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     675             :         continue;
+     676             :       }
+     677             : 
+     678             :       if (pbc_) {
+     679             :         distance = pbcDistance(getPosition(i0) + dev, getPosition(i1));
+     680             :       }
+     681             :       else {
+     682             :         distance = delta(getPosition(i0) + dev, getPosition(i1));
+     683             :       }
+     684             : 
+     685             :       action += pairing(distance.modulo());
+     686             :     }
+     687             :   }
+     688             : 
+     689         250 :   return action;
+     690             : }
+     691             : 
+     692           0 : void Memetic::print_status() const {
+     693           0 :   log.printf("Lowest score: %f \n", score_best_);
+     694           0 : }
+     695             : 
+     696           6 : Vector Memetic::solve() {
+     697           6 :   initialize_members();
+     698             : 
+     699             :   size_t epoch = 0;
+     700          36 :   while (epoch < n_global_iterations_) {
+     701          30 :     score_members();
+     702             : 
+     703          30 :     selection_roulette();
+     704          30 :     mating(members_);
+     705          30 :     mutation(members_);
+     706          30 :     local_search(members_);
+     707             : 
+     708          30 :     sort_members();
+     709             : 
+     710          30 :     epoch++;
+     711             :   }
+     712             : 
+     713           6 :   return member_best_.translation / member_best_.translation.modulo();
+     714             : }
+     715             : 
+     716             : inline unsigned int Memetic::get_capacity() const {
+     717             :   return capacity_;
+     718             : }
+     719             : 
+     720             : inline void Memetic::set_capacity(unsigned int capacity) {
+     721             :   capacity_ = capacity;
+     722             : }
+     723             : 
+     724             : inline unsigned int Memetic::get_coding_len() const {
+     725             :   return coding_len_;
+     726             : }
+     727             : 
+     728             : inline void Memetic::set_coding_len(unsigned int coding_len) {
+     729             :   coding_len_ = coding_len;
+     730             : }
+     731             : 
+     732             : inline unsigned int Memetic::get_n_global_iterations() const {
+     733             :   return n_global_iterations_;
+     734             : }
+     735             : 
+     736             : inline void Memetic::set_n_global_iterations(unsigned int n_global_iterations) {
+     737           2 :   n_global_iterations_ = n_global_iterations;
+     738             : }
+     739             : 
+     740             : inline unsigned int Memetic::get_n_local_iterations() const {
+     741             :   return n_local_iterations_;
+     742             : }
+     743             : 
+     744             : inline void Memetic::set_n_local_iterations(unsigned int n_local_iterations) {
+     745             :   n_local_iterations_ = n_local_iterations;
+     746             : }
+     747             : 
+     748             : inline double Memetic::get_mating_rate() const {
+     749             :   return mating_rate_;
+     750             : }
+     751             : 
+     752             : inline void Memetic::set_mating_rate(double mating_rate) {
+     753             :   mating_rate_ = mating_rate;
+     754             : }
+     755             : 
+     756             : inline double Memetic::get_mutation_rate() const {
+     757             :   return mutation_rate_;
+     758             : }
+     759             : 
+     760             : inline void Memetic::set_mutation_rate(double mutation_rate) {
+     761             :   mutation_rate_ = mutation_rate;
+     762             : }
+     763             : 
+     764             : inline double Memetic::get_cauchy_mean() const {
+     765             :   return cauchy_mean_alpha_;
+     766             : }
+     767             : 
+     768             : inline void Memetic::set_cauchy_mean(double cauchy_mean_alpha) {
+     769             :   cauchy_mean_alpha_ = cauchy_mean_alpha;
+     770             : }
+     771             : 
+     772             : inline double Memetic::get_cauchy_spread() const {
+     773             :   return cauchy_mean_beta_;
+     774             : }
+     775             : 
+     776             : inline void Memetic::set_cauchy_spread(double cauchy_mean_beta) {
+     777             :   cauchy_mean_beta_ = cauchy_mean_beta;
+     778             : }
+     779             : 
+     780             : inline bool Memetic::is_local_search_on() const {
+     781             :   return local_search_on_;
+     782             : }
+     783             : 
+     784             : inline void Memetic::local_search_on() {
+     785             :   local_search_on_ = true;
+     786             : }
+     787             : 
+     788             : inline void Memetic::local_search_off() {
+     789             :   local_search_on_ = false;
+     790             : }
+     791             : 
+     792             : inline double Memetic::get_local_search_rate() const {
+     793             :   return local_search_rate_;
+     794             : }
+     795             : 
+     796             : inline void Memetic::set_local_search_rate(double local_search_rate) {
+     797             :   local_search_rate_ = local_search_rate;
+     798             : }
+     799             : 
+     800             : inline std::string Memetic::get_local_search_type() const {
+     801             :   return local_search_type_;
+     802             : }
+     803             : 
+     804             : inline void Memetic::set_local_search_type(const std::string& local_search_type) {
+     805             :   local_search_type_ = local_search_type;
+     806             : }
+     807             : 
+     808             : } // namespace maze
+     809             : } // namespace PLMD
+     810             : 
+     811             : #endif // __PLUMED_maze_Memetic_h
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bb6e5987b3 --- /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:16318488.6 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9OptimizerC1ERKNS_13ActionOptionsE0
_ZNK4PLMD4maze9Optimizer14center_of_massEv6
_ZN4PLMD4maze9OptimizerC2ERKNS_13ActionOptionsE7
_ZN4PLMD4maze9Optimizer16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4maze9Optimizer7prepareEv210
_ZN4PLMD4maze9Optimizer9calculateEv210
_ZN4PLMD4maze9Optimizer9update_nlEv210
_ZN4PLMD4maze9Optimizer5scoreEv226
_ZN4PLMD4maze9Optimizer15sampling_radiusEv328
_ZNK4PLMD4maze9Optimizer7pairingEd14974890
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Optimizer.cpp.func.html b/coverage/maze/Optimizer.cpp.func.html new file mode 100644 index 0000000000..e948050eb9 --- /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:16318488.6 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9Optimizer15sampling_radiusEv328
_ZN4PLMD4maze9Optimizer16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4maze9Optimizer5scoreEv226
_ZN4PLMD4maze9Optimizer7prepareEv210
_ZN4PLMD4maze9Optimizer9calculateEv210
_ZN4PLMD4maze9Optimizer9update_nlEv210
_ZN4PLMD4maze9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD4maze9OptimizerC2ERKNS_13ActionOptionsE7
_ZNK4PLMD4maze9Optimizer14center_of_massEv6
_ZNK4PLMD4maze9Optimizer7pairingEd14974890
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Optimizer.cpp.gcov.html b/coverage/maze/Optimizer.cpp.gcov.html new file mode 100644 index 0000000000..5479e3a22c --- /dev/null +++ b/coverage/maze/Optimizer.cpp.gcov.html @@ -0,0 +1,586 @@ + + + + + + + + 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:16318488.6 %
Date:2024-06-10 08:19:14Functions: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             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35          12 : void Optimizer::registerKeywords(Keywords& keys) {
+      36          12 :   Colvar::registerKeywords(keys);
+      37             : 
+      38          24 :   keys.addFlag(
+      39             :     "SERIAL",
+      40             :     false,
+      41             :     "Perform the simulation in serial -- used only for debugging purposes, "
+      42             :     "should not be used otherwise."
+      43             :   );
+      44             : 
+      45          24 :   keys.addFlag(
+      46             :     "PAIR",
+      47             :     false,
+      48             :     "Pair only the 1st element of the 1st group with the 1st element in the "
+      49             :     "second, etc."
+      50             :   );
+      51             : 
+      52          24 :   keys.addFlag(
+      53             :     "NLIST",
+      54             :     false,
+      55             :     "Use a neighbor list of ligand-protein atom pairs to speed up the "
+      56             :     "calculating of the distances."
+      57             :   );
+      58             : 
+      59          24 :   keys.add(
+      60             :     "optional",
+      61             :     "NL_CUTOFF",
+      62             :     "Neighbor list cut-off for the distances of ligand-protein atom pairs."
+      63             :   );
+      64             : 
+      65          24 :   keys.add(
+      66             :     "optional",
+      67             :     "NL_STRIDE",
+      68             :     "Update stride for the ligand-protein atom pairs in the neighbor list."
+      69             :   );
+      70             : 
+      71          24 :   keys.add(
+      72             :     "compulsory",
+      73             :     "N_ITER",
+      74             :     "Number of optimization steps. Required only for optimizers, do not pass "
+      75             :     "this keyword to the fake optimizers (results in crash) , e.g., random "
+      76             :     "walk, steered MD, or random acceleration MD."
+      77             :   );
+      78             : 
+      79          24 :   keys.add(
+      80             :     "optional",
+      81             :     "LOSS",
+      82             :     "Loss function describing ligand-protein interactions required by every "
+      83             :     "optimizer."
+      84             :   );
+      85             : 
+      86          24 :   keys.add(
+      87             :     "atoms",
+      88             :     "LIGAND",
+      89             :     "Indices of ligand atoms."
+      90             :   );
+      91             : 
+      92          24 :   keys.add(
+      93             :     "atoms",
+      94             :     "PROTEIN",
+      95             :     "Indices of protein atoms."
+      96             :   );
+      97             : 
+      98          36 :   keys.add(
+      99             :     "compulsory",
+     100             :     "OPTIMIZER_STRIDE",
+     101             :     "Optimizer stride. Sets up a callback function that launches the "
+     102             :     "optimization process every OPTIMIZER_STRIDE."
+     103             :   );
+     104             : 
+     105          12 :   componentsAreNotOptional(keys);
+     106             : 
+     107          24 :   keys.addOutputComponent(
+     108             :     "x",
+     109             :     "default",
+     110             :     "Optimal biasing direction; x component."
+     111             :   );
+     112             : 
+     113          24 :   keys.addOutputComponent(
+     114             :     "y",
+     115             :     "default",
+     116             :     "Optimal biasing direction; y component."
+     117             :   );
+     118             : 
+     119          24 :   keys.addOutputComponent(
+     120             :     "z",
+     121             :     "default",
+     122             :     "Optimal biasing direction; z component."
+     123             :   );
+     124             : 
+     125          24 :   keys.addOutputComponent(
+     126             :     "loss",
+     127             :     "default",
+     128             :     "Loss function value defined by the provided pairing function."
+     129             :   );
+     130             : 
+     131          24 :   keys.addOutputComponent(
+     132             :     "sr",
+     133             :     "default",
+     134             :     "Sampling radius. Reduces sampling to the local proximity of the ligand "
+     135             :     "position."
+     136             :   );
+     137          12 : }
+     138             : 
+     139           7 : Optimizer::Optimizer(const ActionOptions& ao)
+     140             :   : PLUMED_COLVAR_INIT(ao),
+     141           7 :     first_step_(true),
+     142           7 :     opt_value_(0.0),
+     143           7 :     pbc_(true),
+     144           7 :     sampling_r_(0.0),
+     145           7 :     serial_(false),
+     146           7 :     validate_list_(true),
+     147           7 :     first_time_(true)
+     148             : {
+     149           7 :   parseFlag("SERIAL", serial_);
+     150             : 
+     151          14 :   if (keywords.exists("LOSS")) {
+     152           7 :     std::vector<std::string> loss_labels(0);
+     153          14 :     parseVector("LOSS", loss_labels);
+     154             : 
+     155           7 :     plumed_massert(
+     156             :       loss_labels.size() > 0,
+     157             :       "maze> Something went wrong with the LOSS keyword.\n"
+     158             :     );
+     159             : 
+     160           7 :     std::string error_msg = "";
+     161           7 :     vec_loss_ = tls::get_pointers_labels<Loss*>(
+     162             :                   loss_labels,
+     163           7 :                   plumed.getActionSet(),
+     164             :                   error_msg
+     165             :                 );
+     166             : 
+     167           7 :     if (error_msg.size() > 0) {
+     168           0 :       plumed_merror(
+     169             :         "maze> Error in the LOSS keyword " + getName() + ": " + error_msg
+     170             :       );
+     171             :     }
+     172             : 
+     173           7 :     loss_ = vec_loss_[0];
+     174           7 :     log.printf("maze> Loss function linked to the optimizer.\n");
+     175           7 :   }
+     176             : 
+     177          14 :   if (keywords.exists("N_ITER")) {
+     178           3 :     parse("N_ITER", n_iter_);
+     179             : 
+     180           3 :     plumed_massert(
+     181             :       n_iter_ > 0,
+     182             :       "maze> N_ITER should be explicitly specified and positive.\n"
+     183             :     );
+     184             : 
+     185           3 :     log.printf(
+     186             :       "maze> Optimizer will run %u iterations once launched.\n",
+     187             :       n_iter_
+     188             :     );
+     189             :   }
+     190             : 
+     191             :   std::vector<AtomNumber> ga_list, gb_list;
+     192           7 :   parseAtomList("LIGAND", ga_list);
+     193           7 :   parseAtomList("PROTEIN", gb_list);
+     194             : 
+     195           7 :   bool nopbc = !pbc_;
+     196           7 :   parseFlag("NOPBC", nopbc);
+     197             : 
+     198           7 :   bool do_pair = false;
+     199           7 :   parseFlag("PAIR", do_pair);
+     200             : 
+     201           7 :   nl_stride_ = 0;
+     202           7 :   bool do_neigh = false;
+     203           7 :   parseFlag("NLIST", do_neigh);
+     204             : 
+     205           7 :   if (do_neigh) {
+     206          14 :     if (keywords.exists("NL_CUTOFF")) {
+     207           7 :       parse("NL_CUTOFF", nl_cutoff_);
+     208             : 
+     209           7 :       plumed_massert(
+     210             :         nl_cutoff_ > 0,
+     211             :         "maze> NL_CUTOFF should be explicitly specified and positive.\n"
+     212             :       );
+     213             :     }
+     214             : 
+     215          14 :     if (keywords.exists("NL_STRIDE")) {
+     216           7 :       parse("NL_STRIDE", nl_stride_);
+     217             : 
+     218           7 :       plumed_massert(
+     219             :         nl_stride_ > 0,
+     220             :         "maze> NL_STRIDE should be explicitly specified and positive.\n"
+     221             :       );
+     222             :     }
+     223             :   }
+     224             : 
+     225           7 :   if (gb_list.size() > 0) {
+     226           7 :     if (do_neigh) {
+     227           7 :       neighbor_list_ = new NeighborList(
+     228             :         ga_list,
+     229             :         gb_list,
+     230             :         serial_,
+     231             :         do_pair,
+     232           7 :         pbc_,
+     233             :         getPbc(),
+     234             :         comm,
+     235           7 :         nl_cutoff_,
+     236           7 :         nl_stride_
+     237           7 :       );
+     238             :     }
+     239             :     else {
+     240           0 :       neighbor_list_=new NeighborList(
+     241             :         ga_list,
+     242             :         gb_list,
+     243             :         serial_,
+     244             :         do_pair,
+     245           0 :         pbc_,
+     246             :         getPbc(),
+     247             :         comm
+     248           0 :       );
+     249             :     }
+     250             :   }
+     251             :   else {
+     252           0 :     if (do_neigh) {
+     253           0 :       neighbor_list_ = new NeighborList(
+     254             :         ga_list,
+     255             :         serial_,
+     256           0 :         pbc_,
+     257             :         getPbc(),
+     258             :         comm,
+     259           0 :         nl_cutoff_,
+     260           0 :         nl_stride_
+     261           0 :       );
+     262             :     }
+     263             :     else {
+     264           0 :       neighbor_list_=new NeighborList(
+     265             :         ga_list,
+     266             :         serial_,
+     267           0 :         pbc_,
+     268             :         getPbc(),
+     269             :         comm
+     270           0 :       );
+     271             :     }
+     272             :   }
+     273             : 
+     274           7 :   requestAtoms(neighbor_list_->getFullAtomList());
+     275             : 
+     276           7 :   log.printf(
+     277             :     "maze> Loss will be calculated between two groups of %u and %u atoms.\n",
+     278             :     static_cast<unsigned>(ga_list.size()),
+     279             :     static_cast<unsigned>(gb_list.size())
+     280             :   );
+     281             : 
+     282           7 :   log.printf(
+     283             :     "maze> First group (LIGAND): from %d to %d.\n",
+     284             :     ga_list[0].serial(),
+     285             :     ga_list[ga_list.size()-1].serial()
+     286             :   );
+     287             : 
+     288           7 :   if (gb_list.size() > 0) {
+     289           7 :     log.printf(
+     290             :       "maze> Second group (PROTEIN): from %d to %d.\n",
+     291             :       gb_list[0].serial(),
+     292             :       gb_list[gb_list.size()-1].serial()
+     293             :     );
+     294             :   }
+     295             : 
+     296           7 :   if (pbc_) {
+     297           7 :     log.printf("maze> Using periodic boundary conditions.\n");
+     298             :   }
+     299             :   else {
+     300           0 :     log.printf("maze> Without periodic boundary conditions.\n");
+     301             :   }
+     302             : 
+     303           7 :   if (do_pair) {
+     304           0 :     log.printf("maze> With PAIR option.\n");
+     305             :   }
+     306             : 
+     307           7 :   if (do_neigh) {
+     308           7 :     log.printf(
+     309             :       "maze> Using neighbor lists updated every %d steps and cutoff %f.\n",
+     310             :       nl_stride_,
+     311             :       nl_cutoff_
+     312             :     );
+     313             :   }
+     314             : 
+     315             :   // OpenMP
+     316           7 :   stride_ = comm.Get_size();
+     317           7 :   rank_ = comm.Get_rank();
+     318             : 
+     319           7 :   n_threads_ = OpenMP::getNumThreads();
+     320           7 :   unsigned int nn = neighbor_list_->size();
+     321             : 
+     322           7 :   if (n_threads_ * stride_ * 10 > nn) {
+     323           0 :     n_threads_ = nn / stride_ / 10;
+     324             :   }
+     325             : 
+     326           7 :   if (n_threads_ == 0) {
+     327           0 :     n_threads_ = 1;
+     328             :   }
+     329             : 
+     330          14 :   if (keywords.exists("OPTIMIZER_STRIDE")) {
+     331           7 :     parse("OPTIMIZER_STRIDE", optimizer_stride_);
+     332             : 
+     333           7 :     plumed_massert(
+     334             :       optimizer_stride_,
+     335             :       "maze> OPTIMIZER_STRIDE should be explicitly specified and positive.\n"
+     336             :     );
+     337             : 
+     338           7 :     log.printf(
+     339             :       "maze> Launching optimization every %u steps.\n",
+     340             :       optimizer_stride_
+     341             :     );
+     342             :   }
+     343             : 
+     344           7 :   rnd::randomize();
+     345             : 
+     346           7 :   opt_.zero();
+     347             : 
+     348           7 :   addComponentWithDerivatives("x");
+     349           7 :   componentIsNotPeriodic("x");
+     350             : 
+     351           7 :   addComponentWithDerivatives("y");
+     352           7 :   componentIsNotPeriodic("y");
+     353             : 
+     354           7 :   addComponentWithDerivatives("z");
+     355           7 :   componentIsNotPeriodic("z");
+     356             : 
+     357           7 :   addComponent("loss");
+     358           7 :   componentIsNotPeriodic("loss");
+     359             : 
+     360           7 :   addComponent("sr");
+     361           7 :   componentIsNotPeriodic("sr");
+     362             : 
+     363           7 :   value_x_ = getPntrToComponent("x");
+     364           7 :   value_y_ = getPntrToComponent("y");
+     365           7 :   value_z_ = getPntrToComponent("z");
+     366           7 :   value_action_ = getPntrToComponent("loss");
+     367           7 :   value_sampling_radius_ = getPntrToComponent("sr");
+     368           7 : }
+     369             : 
+     370    14974890 : double Optimizer::pairing(double distance) const {
+     371    14974890 :   return loss_->pairing(distance);
+     372             : }
+     373             : 
+     374           6 : Vector Optimizer::center_of_mass() const {
+     375           6 :   const unsigned nl_size = neighbor_list_->size();
+     376             : 
+     377           6 :   Vector center_of_mass;
+     378           6 :   center_of_mass.zero();
+     379             :   double mass = 0;
+     380             : 
+     381      189654 :   for (unsigned int i = 0; i < nl_size; ++i) {
+     382      189648 :     unsigned int i0 = neighbor_list_->getClosePair(i).first;
+     383      189648 :     center_of_mass += getPosition(i0) * getMass(i0);
+     384      189648 :     mass += getMass(i0);
+     385             :   }
+     386             : 
+     387           6 :   return center_of_mass / mass;
+     388             : }
+     389             : 
+     390         210 : void Optimizer::prepare() {
+     391         210 :   if (neighbor_list_->getStride() > 0) {
+     392         210 :     if (first_time_ || (getStep() % neighbor_list_->getStride() == 0)) {
+     393           7 :       requestAtoms(neighbor_list_->getFullAtomList());
+     394             : 
+     395           7 :       validate_list_ = true;
+     396           7 :       first_time_ = false;
+     397             :     }
+     398             :     else {
+     399         203 :       requestAtoms(neighbor_list_->getReducedAtomList());
+     400             : 
+     401         203 :       validate_list_ = false;
+     402             : 
+     403         203 :       if (getExchangeStep()) {
+     404           0 :         plumed_merror(
+     405             :           "maze> Neighbor lists should be updated on exchange steps -- choose "
+     406             :           "an NL_STRIDE which divides the exchange stride.\n");
+     407             :       }
+     408             :     }
+     409             : 
+     410         210 :     if (getExchangeStep()) {
+     411           0 :       first_time_ = true;
+     412             :     }
+     413             :   }
+     414         210 : }
+     415             : 
+     416         226 : double Optimizer::score() {
+     417         226 :   const unsigned nl_size = neighbor_list_->size();
+     418         226 :   Vector distance;
+     419             :   double function = 0;
+     420             : 
+     421         226 :   #pragma omp parallel num_threads(n_threads_)
+     422             :   {
+     423             :     #pragma omp for reduction(+:function)
+     424             :     for(unsigned int i = 0; i < nl_size; i++) {
+     425             :       unsigned i0 = neighbor_list_->getClosePair(i).first;
+     426             :       unsigned i1 = neighbor_list_->getClosePair(i).second;
+     427             : 
+     428             :       if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     429             :         continue;
+     430             :       }
+     431             : 
+     432             :       if (pbc_) {
+     433             :         distance = pbcDistance(getPosition(i0), getPosition(i1));
+     434             :       }
+     435             :       else {
+     436             :         distance = delta(getPosition(i0), getPosition(i1));
+     437             :       }
+     438             : 
+     439             :       function += pairing(distance.modulo());
+     440             :     }
+     441             :   }
+     442             : 
+     443         226 :   return function;
+     444             : }
+     445             : 
+     446         210 : void Optimizer::update_nl() {
+     447         210 :   if (neighbor_list_->getStride() > 0 && validate_list_) {
+     448           7 :     neighbor_list_->update(getPositions());
+     449             :   }
+     450         210 : }
+     451             : 
+     452         328 : double Optimizer::sampling_radius()
+     453             : {
+     454         328 :   const unsigned nl_size=neighbor_list_->size();
+     455         328 :   Vector d;
+     456             :   double min=std::numeric_limits<int>::max();
+     457             : 
+     458     8579572 :   for (unsigned int i = 0; i < nl_size; ++i) {
+     459     8579244 :     unsigned i0 = neighbor_list_->getClosePair(i).first;
+     460     8579244 :     unsigned i1 = neighbor_list_->getClosePair(i).second;
+     461             : 
+     462     8579244 :     if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     463           0 :       continue;
+     464             :     }
+     465             : 
+     466     8579244 :     if (pbc_) {
+     467     8579244 :       d = pbcDistance(getPosition(i0), getPosition(i1));
+     468             :     }
+     469             :     else {
+     470           0 :       d = delta(getPosition(i0), getPosition(i1));
+     471             :     }
+     472             : 
+     473     8579244 :     double dist = d.modulo();
+     474             : 
+     475     8579244 :     if(dist < min) {
+     476             :       min = dist;
+     477             :     }
+     478             :   }
+     479             : 
+     480         328 :   return min;
+     481             : }
+     482             : 
+     483         210 : void Optimizer::calculate() {
+     484         210 :   update_nl();
+     485             : 
+     486         210 :   if (getStep() % optimizer_stride_ == 0 && !first_step_) {
+     487          19 :     optimize();
+     488             : 
+     489          19 :     value_x_->set(opt_[0]);
+     490          19 :     value_y_->set(opt_[1]);
+     491          19 :     value_z_->set(opt_[2]);
+     492             : 
+     493          19 :     value_action_->set(score());
+     494          19 :     value_sampling_radius_->set(sampling_radius());
+     495             :   }
+     496             :   else {
+     497         191 :     first_step_=false;
+     498             : 
+     499         191 :     value_x_->set(opt_[0]);
+     500         191 :     value_y_->set(opt_[1]);
+     501         191 :     value_z_->set(opt_[2]);
+     502             : 
+     503         191 :     value_action_->set(score());
+     504         191 :     value_sampling_radius_->set(sampling_radius());
+     505             :   }
+     506         210 : }
+     507             : 
+     508             : } // namespace maze
+     509             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..0e17ca12bd --- /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:1212100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9OptimizerD2Ev7
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Optimizer.h.func.html b/coverage/maze/Optimizer.h.func.html new file mode 100644 index 0000000000..0a1aa38ee2 --- /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:1212100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9OptimizerD2Ev7
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Optimizer.h.gcov.html b/coverage/maze/Optimizer.h.gcov.html new file mode 100644 index 0000000000..7250286f3e --- /dev/null +++ b/coverage/maze/Optimizer.h.gcov.html @@ -0,0 +1,431 @@ + + + + + + + + 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:1212100.0 %
Date:2024-06-10 08:19:14Functions: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             : #define PLUMED_OPT_INIT(ao) Action(ao), Optimizer(ao)
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace maze {
+      44             : 
+      45             : /**
+      46             :  * @ingroup INHERIT
+      47             :  *
+      48             :  * @class Optimizer Optimizer.h "maze/Optimizer.h"
+      49             :  *
+      50             :  * @brief Base class for implementing optimizers for ligand unbinding.
+      51             :  *
+      52             :  * An optimizer is defined as a colvar that can be passed to Optimizer_Bias.
+      53             :  */
+      54             : class Optimizer: public colvar::Colvar {
+      55             : public:
+      56             :   /**
+      57             :    * PLMD constructor.
+      58             :    *
+      59             :    * @param[in] ao PLMD::ActionOptions&
+      60             :    */
+      61             :   explicit Optimizer(const ActionOptions&);
+      62             : 
+      63             :   /**
+      64             :    * Destructor.
+      65             :    */
+      66          14 :   ~Optimizer() { /* Nothing to do. */ }
+      67             : 
+      68             :   /**
+      69             :    * Registers PLMD keywords.
+      70             :    *
+      71             :    * @param[in] keys PLMD keywords
+      72             :    */
+      73             :   static void registerKeywords(Keywords& keys);
+      74             : 
+      75             :   /**
+      76             :    * The pairing function needs to be overridden by a specific optimizer.
+      77             :    *
+      78             :    * @param[in] distance distance between a pair of atoms
+      79             :    */
+      80             :   virtual double pairing(double distance) const;
+      81             : 
+      82             :   /**
+      83             :    * Optimal values needed for biasing are computed by methods overridding the
+      84             :    * optimize function.
+      85             :    */
+      86             :   virtual void optimize() = 0;
+      87             : 
+      88             :   /**
+      89             :    * Calculate the optimal direction of pulling.
+      90             :    */
+      91             :   void calculate();
+      92             : 
+      93             :   /**
+      94             :    * Prepare the neighbor list.
+      95             :    */
+      96             :   void prepare();
+      97             : 
+      98             :   /**
+      99             :    * Score a ligand-protein configuration.
+     100             :    *
+     101             :    * @return score
+     102             :    */
+     103             :   double score();
+     104             : 
+     105             :   /**
+     106             :    * Calculate sampling radius as the minimal distance between two groups in
+     107             :    * neighbors list.
+     108             :    *
+     109             :    * @return minimal distance of ligand-protein atom pairs
+     110             :    */
+     111             :   double sampling_radius();
+     112             : 
+     113             :   /**
+     114             :    * Load new positions of atoms in the neighbor list.
+     115             :    */
+     116             :   void update_nl();
+     117             : 
+     118             :   /**
+     119             :    * Calculate the center of mass.
+     120             :    *
+     121             :    * @return center of mass
+     122             :    */
+     123             :   Vector center_of_mass() const;
+     124             : 
+     125             : public:
+     126             :   /**
+     127             :    * Getters and setters.
+     128             :    */
+     129             : 
+     130             :   std::string get_label() const;
+     131             :   void set_label(const std::string&);
+     132             : 
+     133             :   // Start optimizer at time = 0.
+     134             :   void start_step_0();
+     135             : 
+     136             :   // Start optimizer at time = optimizer stride.
+     137             :   void start_step_stride();
+     138             : 
+     139             :   Vector get_opt() const;
+     140             :   void set_opt(Vector);
+     141             : 
+     142             :   double get_opt_value() const;
+     143             :   void set_opt_value(double);
+     144             : 
+     145             :   unsigned int get_optimizer_stride() const;
+     146             :   void set_optimizer_stride(unsigned int);
+     147             : 
+     148             :   bool is_pbc_on() const;
+     149             :   void pbc_on();
+     150             :   void pbc_off();
+     151             : 
+     152             :   unsigned int get_n_iterations() const;
+     153             :   void set_n_iterations(unsigned int);
+     154             : 
+     155             :   double get_sampling_radius() const;
+     156             :   void set_sampling_radius(double);
+     157             : 
+     158             :   unsigned int get_rank_openmp() const;
+     159             :   void set_rank_openmp(unsigned int);
+     160             : 
+     161             :   unsigned int get_stride_openmp() const;
+     162             :   void set_stride_openmp(unsigned int);
+     163             : 
+     164             :   unsigned int get_n_threads_openmp() const;
+     165             :   void set_n_threads_openmp(unsigned int);
+     166             : 
+     167             :   unsigned int get_nl_stride() const;
+     168             :   void set_nl_stride(unsigned int);
+     169             : 
+     170             :   double get_nl_cutofff() const;
+     171             :   void set_nl_cutoff(double);
+     172             : 
+     173             : protected:
+     174             :   //! Optimizer label.
+     175             :   std::string label_;
+     176             : 
+     177             :   //! Start either at time =  0 or time = optimizer stride.
+     178             :   bool first_step_;
+     179             : 
+     180             :   //! Biasing direction.
+     181             :   Vector opt_;
+     182             : 
+     183             :   //! Current loss function value.
+     184             :   double opt_value_;
+     185             : 
+     186             :   //! Optimizer stride.
+     187             :   unsigned int optimizer_stride_;
+     188             : 
+     189             :   //! Periodic boundary conditions.
+     190             :   bool pbc_;
+     191             : 
+     192             :   //! Number of global iterations.
+     193             :   unsigned int n_iter_;
+     194             : 
+     195             :   //! Sampling radius.
+     196             :   double sampling_r_;
+     197             : 
+     198             :   /**
+     199             :    * OpenMP
+     200             :    */
+     201             :   unsigned int rank_;
+     202             :   unsigned int stride_;
+     203             :   unsigned int n_threads_;
+     204             : 
+     205             :   //! Neighbor list of ligand-protein atom pairs.
+     206             :   NeighborList *neighbor_list_;
+     207             : 
+     208             :   //! Neighbor list cut-off.
+     209             :   double nl_cutoff_;
+     210             : 
+     211             :   //! Neighbor list stride.
+     212             :   int nl_stride_;
+     213             : 
+     214             : private:
+     215             :   bool serial_;
+     216             :   bool validate_list_;
+     217             :   bool first_time_;
+     218             : 
+     219             :   //! Pointer to the loss function.
+     220             :   Loss* loss_;
+     221             :   std::vector<Loss*> vec_loss_;
+     222             : 
+     223             : public:
+     224             :   /*
+     225             :    * Pointers to PLMD components.
+     226             :    */
+     227             : 
+     228             :   //! Biased cv.
+     229             :   Value* value_x_;
+     230             :   Value* value_y_;
+     231             :   Value* value_z_;
+     232             : 
+     233             :   //! Loss value.
+     234             :   Value* value_action_;
+     235             :   //! Sampling radiues value.
+     236             :   Value* value_sampling_radius_;
+     237             : };
+     238             : 
+     239             : /*
+     240             :  * Getters and setters.
+     241             :  */
+     242             : 
+     243             : inline void Optimizer::set_nl_cutoff(double nl_cutoff) {
+     244             :   nl_cutoff_=nl_cutoff;
+     245             : }
+     246             : 
+     247             : inline double Optimizer::get_nl_cutofff() const {
+     248             :   return nl_cutoff_;
+     249             : }
+     250             : 
+     251             : inline void Optimizer::set_nl_stride(unsigned int nl_stride) {
+     252             :   nl_stride_=nl_stride;
+     253             : }
+     254             : 
+     255             : inline unsigned int Optimizer::get_nl_stride() const {
+     256             :   return nl_stride_;
+     257             : }
+     258             : 
+     259             : inline void Optimizer::set_n_threads_openmp(unsigned int n_threads) {
+     260             :   n_threads_=n_threads;
+     261             : }
+     262             : 
+     263             : inline unsigned int Optimizer::get_n_threads_openmp() const {
+     264         280 :   return n_threads_;
+     265             : }
+     266             : 
+     267             : inline void Optimizer::set_stride_openmp(unsigned int stride) {
+     268             :   stride_=stride;
+     269             : }
+     270             : 
+     271             : inline unsigned int Optimizer::get_stride_openmp() const {
+     272             :   return stride_;
+     273             : }
+     274             : 
+     275             : inline void Optimizer::set_rank_openmp(unsigned int rank) {
+     276             :   rank_=rank;
+     277             : }
+     278             : 
+     279             : inline unsigned int Optimizer::get_rank_openmp() const {
+     280             :   return rank_;
+     281             : }
+     282             : 
+     283             : inline void Optimizer::set_sampling_radius(double sampling_r) {
+     284             :   sampling_r_=sampling_r;
+     285             : }
+     286             : 
+     287             : inline double Optimizer::get_sampling_radius() const {
+     288             :   return sampling_r_;
+     289             : }
+     290             : 
+     291             : inline void Optimizer::set_n_iterations(unsigned int n_iter) {
+     292             :   n_iter_=n_iter;
+     293             : }
+     294             : 
+     295             : inline unsigned int Optimizer::get_n_iterations() const {
+     296          33 :   return n_iter_;
+     297             : }
+     298             : 
+     299             : inline void Optimizer::pbc_off() {
+     300             :   pbc_=false;
+     301             : }
+     302             : 
+     303             : inline void Optimizer::pbc_on() {
+     304             :   pbc_=true;
+     305             : }
+     306             : 
+     307             : inline bool Optimizer::is_pbc_on() const {
+     308             :   return pbc_==true;
+     309             : }
+     310             : 
+     311             : inline void Optimizer::set_optimizer_stride(unsigned int optimizer_stride) {
+     312             :   optimizer_stride_=optimizer_stride;
+     313             : }
+     314             : 
+     315             : inline unsigned int Optimizer::get_optimizer_stride() const {
+     316           1 :   return optimizer_stride_;
+     317             : }
+     318             : 
+     319             : inline void Optimizer::set_opt_value(double opt_value) {
+     320          46 :   opt_value_=opt_value;
+     321          30 : }
+     322             : 
+     323             : inline double Optimizer::get_opt_value() const {
+     324             :   return opt_value_;
+     325             : }
+     326             : 
+     327             : inline void Optimizer::set_opt(Vector opt) {
+     328          44 :   opt_=opt;
+     329             : }
+     330             : 
+     331             : inline Vector Optimizer::get_opt() const {
+     332           3 :   return opt_;
+     333             : }
+     334             : 
+     335             : inline void Optimizer::set_label(const std::string& label) {
+     336           7 :   label_=label;
+     337           7 : }
+     338             : 
+     339             : inline std::string Optimizer::get_label() const {
+     340             :   return label_;
+     341             : }
+     342             : 
+     343             : inline void Optimizer::start_step_0() {
+     344           5 :   first_step_=false;
+     345             : }
+     346             : 
+     347             : inline void Optimizer::start_step_stride() {
+     348           2 :   first_step_=true;
+     349             : }
+     350             : 
+     351             : } // namespace maze
+     352             : } // namespace PLMD
+     353             : 
+     354             : #endif // __PLUMED_maze_Optimizer_h
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..04f94ae1a1 --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:969898.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze13OptimizerBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze12_GLOBAL__N_126OptimizerBiasRegisterMe1986createERKNS_13ActionOptionsE1
_ZN4PLMD4maze13OptimizerBiasC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze13OptimizerBiasD0Ev1
_ZN4PLMD4maze13OptimizerBiasD1Ev1
_ZN4PLMD4maze13OptimizerBias16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4maze13OptimizerBias9calculateEv30
_ZN4PLMD4maze12_GLOBAL__N_126OptimizerBiasRegisterMe198C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_126OptimizerBiasRegisterMe198D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Optimizer_Bias.cpp.func.html b/coverage/maze/Optimizer_Bias.cpp.func.html new file mode 100644 index 0000000000..45a1c74c5b --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:969898.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_126OptimizerBiasRegisterMe1986createERKNS_13ActionOptionsE1
_ZN4PLMD4maze12_GLOBAL__N_126OptimizerBiasRegisterMe198C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_126OptimizerBiasRegisterMe198D2Ev3473
_ZN4PLMD4maze13OptimizerBias16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4maze13OptimizerBias9calculateEv30
_ZN4PLMD4maze13OptimizerBiasC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze13OptimizerBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze13OptimizerBiasD0Ev1
_ZN4PLMD4maze13OptimizerBiasD1Ev1
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Optimizer_Bias.cpp.gcov.html b/coverage/maze/Optimizer_Bias.cpp.gcov.html new file mode 100644 index 0000000000..dad6bd418c --- /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:969898.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ + + + + + + + +

+
          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       10421 : PLUMED_REGISTER_ACTION(OptimizerBias, "MAZE_OPTIMIZER_BIAS")
+     199             : 
+     200           2 : void OptimizerBias::registerKeywords(Keywords& keys) {
+     201           2 :   Bias::registerKeywords(keys);
+     202             : 
+     203           2 :   keys.use("ARG");
+     204             : 
+     205           4 :   keys.add(
+     206             :     "compulsory",
+     207             :     "BIASING_RATE",
+     208             :     "Biasing rate."
+     209             :   );
+     210             : 
+     211           4 :   keys.add(
+     212             :     "compulsory",
+     213             :     "ALPHA",
+     214             :     "Rescaled force constant."
+     215             :   );
+     216             : 
+     217           4 :   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           2 :   componentsAreNotOptional(keys);
+     229             : 
+     230           4 :   keys.addOutputComponent(
+     231             :     "force2",
+     232             :     "default",
+     233             :     "Square of the biasing force."
+     234             :   );
+     235             : 
+     236           4 :   keys.addOutputComponent(
+     237             :     "x",
+     238             :     "default",
+     239             :     "Optimal biasing direction: x component."
+     240             :   );
+     241             : 
+     242           4 :   keys.addOutputComponent(
+     243             :     "y",
+     244             :     "default",
+     245             :     "Optimal biasing direction: y component."
+     246             :   );
+     247             : 
+     248           4 :   keys.addOutputComponent(
+     249             :     "z",
+     250             :     "default",
+     251             :     "Optimal biasing direction: z component."
+     252             :   );
+     253             : 
+     254           4 :   keys.addOutputComponent(
+     255             :     "tdist",
+     256             :     "default",
+     257             :     "Total distance traveled by biased atoms."
+     258             :   );
+     259           2 : }
+     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           2 :     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           1 :   addComponent("force2");
+     351           1 :   componentIsNotPeriodic("force2");
+     352             : 
+     353           1 :   addComponent("x");
+     354           1 :   componentIsNotPeriodic("x");
+     355             : 
+     356           1 :   addComponent("y");
+     357           1 :   componentIsNotPeriodic("y");
+     358             : 
+     359           1 :   addComponent("z");
+     360           1 :   componentIsNotPeriodic("z");
+     361             : 
+     362           1 :   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.15
+
+ + + 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 0000000000..6d3cd16527 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:434595.6 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze22Random_Acceleration_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze22Random_Acceleration_MDD2Ev0
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe1176createERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MDD0Ev1
_ZN4PLMD4maze22Random_Acceleration_MDD1Ev1
_ZN4PLMD4maze22Random_Acceleration_MD16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4maze22Random_Acceleration_MD8optimizeEv2
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe117C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe117D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..18a04aae70 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:434595.6 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe1176createERKNS_13ActionOptionsE1
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe117C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe117D2Ev3473
_ZN4PLMD4maze22Random_Acceleration_MD16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4maze22Random_Acceleration_MD8optimizeEv2
_ZN4PLMD4maze22Random_Acceleration_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze22Random_Acceleration_MDD0Ev1
_ZN4PLMD4maze22Random_Acceleration_MDD1Ev1
_ZN4PLMD4maze22Random_Acceleration_MDD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..c745ee04df --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.gcov.html @@ -0,0 +1,289 @@ + + + + + + + + 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:434595.6 %
Date:2024-06-10 08:19:14Functions:81080.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             :    * Destructor.
+      81             :    */
+      82             :   ~Random_Acceleration_MD();
+      83             : 
+      84             :   /**
+      85             :    * Registers PLMD keywords.
+      86             :    *
+      87             :    * @param[in] keys PLMD keywords
+      88             :    */
+      89             :   static void registerKeywords(Keywords&);
+      90             : 
+      91             :   /**
+      92             :    * Each class deriving from Optimizer needs to override this function.
+      93             :    */
+      94             :   void optimize() override;
+      95             : 
+      96             : private:
+      97             :   //! Threshold distance that the ligand needs to pass.
+      98             :   double r_min_;
+      99             : 
+     100             :   //! Total distance.
+     101             :   double total_dist_;
+     102             : 
+     103             :   //! Distance.
+     104             :   double dist_;
+     105             : 
+     106             :   //! Ligand center of mass.
+     107             :   Vector com_;
+     108             : 
+     109             :   //! PLMD value for distance.
+     110             :   Value* value_dist_;
+     111             : 
+     112             :   //! PLMD value for total distance.
+     113             :   Value* value_total_dist_;
+     114             : };
+     115             : 
+     116             : // Register MAZE_RANDOM_ACCELERATION_MD.
+     117       10421 : PLUMED_REGISTER_ACTION(Random_Acceleration_MD, "MAZE_RANDOM_ACCELERATION_MD")
+     118             : 
+     119           2 : void Random_Acceleration_MD::registerKeywords(Keywords& keys) {
+     120           2 :   Optimizer::registerKeywords(keys);
+     121             : 
+     122           2 :   keys.remove("N_ITER");
+     123             : 
+     124           4 :   keys.add(
+     125             :     "compulsory",
+     126             :     "R_MIN",
+     127             :     "Minimal distance traveled before sampling a new direction of biasing."
+     128             :   );
+     129             : 
+     130           4 :   keys.addOutputComponent(
+     131             :     "dist",
+     132             :     "default",
+     133             :     "Distance traveled in one sampling interval."
+     134             :   );
+     135             : 
+     136           4 :   keys.addOutputComponent(
+     137             :     "tdist",
+     138             :     "default",
+     139             :     "Total distance traveled by biased atoms."
+     140             :   );
+     141           2 : }
+     142             : 
+     143           1 : Random_Acceleration_MD::Random_Acceleration_MD(const ActionOptions& ao)
+     144             :   : PLUMED_OPT_INIT(ao),
+     145           1 :     total_dist_(0.0),
+     146           1 :     dist_(0.0) {
+     147           1 :   log.printf("maze> Random accelerated molecular dynamics.\n");
+     148             : 
+     149           2 :   if(keywords.exists("R_MIN")) {
+     150           1 :     parse("R_MIN", r_min_);
+     151             : 
+     152           1 :     plumed_massert(
+     153             :       r_min_ > 0,
+     154             :       "maze> R_MIN should be explicitly specified and positive.\n"
+     155             :     );
+     156             : 
+     157           1 :     log.printf(
+     158             :       "maze> R_MIN read: %f [A].\n",
+     159             :       r_min_
+     160             :     );
+     161             :   }
+     162             : 
+     163           1 :   set_label("RANDOM_ACCELERATION_MD");
+     164           1 :   set_opt(rnd::next_plmd_vector());
+     165             :   set_opt_value(0.0);
+     166             : 
+     167             :   start_step_stride();
+     168             : 
+     169           1 :   checkRead();
+     170             : 
+     171           1 :   com_ = center_of_mass();
+     172             : 
+     173           1 :   addComponent("dist");
+     174           1 :   componentIsNotPeriodic("dist");
+     175           1 :   value_dist_ = getPntrToComponent("dist");
+     176             : 
+     177           1 :   addComponent("tdist");
+     178           1 :   componentIsNotPeriodic("tdist");
+     179           1 :   value_total_dist_ = getPntrToComponent("tdist");
+     180           1 : }
+     181             : 
+     182           2 : Random_Acceleration_MD::~Random_Acceleration_MD() {
+     183           1 :   delete neighbor_list_;
+     184           2 : }
+     185             : 
+     186           2 : void Random_Acceleration_MD::optimize() {
+     187           2 :   Vector c = center_of_mass();
+     188           2 :   Vector d;
+     189             : 
+     190           2 :   if (pbc_) {
+     191           2 :     d = pbcDistance(c, com_);
+     192             :   }
+     193             :   else {
+     194           0 :     d = delta(c, com_);
+     195             :   }
+     196             : 
+     197           2 :   dist_ = d.modulo();
+     198           2 :   total_dist_ += dist_;
+     199             : 
+     200           2 :   if(dist_ < r_min_) {
+     201           0 :     set_opt(rnd::next_plmd_vector());
+     202             :   }
+     203             : 
+     204           2 :   set_opt_value(score());
+     205           2 :   com_ = c;
+     206             : 
+     207           2 :   value_dist_->set(dist_);
+     208           2 :   value_total_dist_->set(total_dist_);
+     209           2 : }
+     210             : 
+     211             : } // namespace maze
+     212             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..35983837d4 --- /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:162080.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd8next_intEii0
_ZN4PLMD4maze3rnd11next_cauchyEdd79
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd8next_intEi298
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1166
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.func.html b/coverage/maze/Random_MT.cpp.func.html new file mode 100644 index 0000000000..62742b47ed --- /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:162080.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd11next_cauchyEdd79
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1166
_ZN4PLMD4maze3rnd8next_intEi298
_ZN4PLMD4maze3rnd8next_intEii0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.gcov.html b/coverage/maze/Random_MT.cpp.gcov.html new file mode 100644 index 0000000000..dba7cdcc62 --- /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:162080.0 %
Date:2024-06-10 08:19:14Functions: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 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        1166 : std::mt19937_64& rnd::mt_eng() {
+      37        1173 :   static std::mt19937_64 mt{};
+      38             : 
+      39        1166 :   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         298 : int rnd::next_int(int e) {
+      59         298 :   static std::uniform_int_distribution<int> dist_int(0, e-1);
+      60         298 :   std::uniform_int_distribution<int>::param_type p(0, e-1);
+      61             :   dist_int.param(p);
+      62             : 
+      63         298 :   return dist_int(mt_eng());
+      64             : }
+      65             : 
+      66           0 : int rnd::next_int(int f, int e) {
+      67           0 :   static std::uniform_int_distribution<int> dist_int(f, e-1);
+      68           0 :   std::uniform_int_distribution<int>::param_type p(f, e-1);
+      69             :   dist_int.param(p);
+      70             : 
+      71           0 :   return dist_int(mt_eng());
+      72             : }
+      73             : 
+      74          79 : double rnd::next_cauchy(double m, double s) {
+      75          79 :   static std::cauchy_distribution<double> dist_cauchy(m, s);
+      76             : 
+      77          79 :   return dist_cauchy(mt_eng());
+      78             : }
+      79             : 
+      80             : } // namespace maze
+      81             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..44531ee319 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/maze/Random_MT.h.func.html b/coverage/maze/Random_MT.h.func.html new file mode 100644 index 0000000000..3f5e9c8d3a --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/maze/Random_MT.h.gcov.html b/coverage/maze/Random_MT.h.gcov.html new file mode 100644 index 0000000000..bd6593b5b6 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..70dd6bc42b --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:1818100.0 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze11Random_WalkC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze11Random_WalkD2Ev0
_ZN4PLMD4maze11Random_WalkC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze11Random_WalkD0Ev2
_ZN4PLMD4maze11Random_WalkD1Ev2
_ZN4PLMD4maze12_GLOBAL__N_124Random_WalkRegisterMe1026createERKNS_13ActionOptionsE2
_ZN4PLMD4maze11Random_Walk16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze11Random_Walk8optimizeEv6
_ZN4PLMD4maze12_GLOBAL__N_124Random_WalkRegisterMe102C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_124Random_WalkRegisterMe102D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.func.html b/coverage/maze/Random_Walk.cpp.func.html new file mode 100644 index 0000000000..376433b5d6 --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:1818100.0 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze11Random_Walk16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze11Random_Walk8optimizeEv6
_ZN4PLMD4maze11Random_WalkC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze11Random_WalkC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze11Random_WalkD0Ev2
_ZN4PLMD4maze11Random_WalkD1Ev2
_ZN4PLMD4maze11Random_WalkD2Ev0
_ZN4PLMD4maze12_GLOBAL__N_124Random_WalkRegisterMe1026createERKNS_13ActionOptionsE2
_ZN4PLMD4maze12_GLOBAL__N_124Random_WalkRegisterMe102C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_124Random_WalkRegisterMe102D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.gcov.html b/coverage/maze/Random_Walk.cpp.gcov.html new file mode 100644 index 0000000000..f5c3dcbc3c --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.gcov.html @@ -0,0 +1,210 @@ + + + + + + + + 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:1818100.0 %
Date:2024-06-10 08:19:14Functions:81080.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             :    * Destructor.
+      85             :    */
+      86             :   ~Random_Walk();
+      87             : 
+      88             :   /**
+      89             :    * Registers PLMD keywords.
+      90             :    *
+      91             :    * @param[in] keys PLMD keywords
+      92             :    */
+      93             :   static void registerKeywords(Keywords&);
+      94             : 
+      95             :   /**
+      96             :    * Each class deriving from Optimizer needs to override this function.
+      97             :    */
+      98             :   void optimize() override;
+      99             : };
+     100             : 
+     101             : // Register MAZE_RANDOM_WALK.
+     102       10423 : PLUMED_REGISTER_ACTION(Random_Walk, "MAZE_RANDOM_WALK")
+     103             : 
+     104           3 : void Random_Walk::registerKeywords(Keywords& keys) {
+     105           3 :   Optimizer::registerKeywords(keys);
+     106             : 
+     107           3 :   keys.remove("N_ITER");
+     108           3 : }
+     109             : 
+     110           2 : Random_Walk::Random_Walk(const ActionOptions& ao)
+     111           2 :   : PLUMED_OPT_INIT(ao)
+     112             : {
+     113           2 :   log.printf("maze> Fake optimizer that returns a next step as random,\
+     114             :     can be used to monitor loss, and for debugging and regtests purposes.\n");
+     115             : 
+     116           4 :   set_label("RANDOM_WALK");
+     117             : 
+     118             :   start_step_0();
+     119             : 
+     120           2 :   checkRead();
+     121           2 : }
+     122             : 
+     123           4 : Random_Walk::~Random_Walk() {
+     124           2 :   delete neighbor_list_;
+     125           4 : }
+     126             : 
+     127           6 : void Random_Walk::optimize() {
+     128           6 :   set_opt(rnd::next_plmd_vector());
+     129           6 :   set_opt_value(score());
+     130           6 : }
+     131             : 
+     132             : } // namespace maze
+     133             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e17ae8e256 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:475388.7 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze19Simulated_AnnealingC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze19Simulated_AnnealingD2Ev0
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe1256createERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_AnnealingC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_AnnealingD0Ev1
_ZN4PLMD4maze19Simulated_AnnealingD1Ev1
_ZN4PLMD4maze19Simulated_Annealing16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4maze19Simulated_Annealing8optimizeEv3
_ZN4PLMD4maze19Simulated_Annealing20decrease_probabilityEj30
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe125C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe125D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.func.html b/coverage/maze/Simulated_Annealing.cpp.func.html new file mode 100644 index 0000000000..583b6ea106 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:475388.7 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe1256createERKNS_13ActionOptionsE1
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe125C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe125D2Ev3473
_ZN4PLMD4maze19Simulated_Annealing16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4maze19Simulated_Annealing20decrease_probabilityEj30
_ZN4PLMD4maze19Simulated_Annealing8optimizeEv3
_ZN4PLMD4maze19Simulated_AnnealingC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_AnnealingC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze19Simulated_AnnealingD0Ev1
_ZN4PLMD4maze19Simulated_AnnealingD1Ev1
_ZN4PLMD4maze19Simulated_AnnealingD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.gcov.html b/coverage/maze/Simulated_Annealing.cpp.gcov.html new file mode 100644 index 0000000000..db40f4ac21 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.gcov.html @@ -0,0 +1,361 @@ + + + + + + + + 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:475388.7 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ + + + + + + + +

+
          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             :    * Destructor.
+      93             :    */
+      94             :   ~Simulated_Annealing();
+      95             : 
+      96             :   /**
+      97             :    * Register PLMD keywords.
+      98             :    *
+      99             :    * @param[in] keys Keywords.
+     100             :    */
+     101             :   static void registerKeywords(Keywords& keys);
+     102             : 
+     103             :   /**
+     104             :    * Each class deriving from Optimizer needs to override this function.
+     105             :    */
+     106             :   void optimize() override;
+     107             : 
+     108             :   /**
+     109             :    * Reduce the temperature parameter.
+     110             :    */
+     111             :   void decrease_probability(unsigned int);
+     112             : 
+     113             : private:
+     114             :   //! Temperature parameter.
+     115             :   double probability_decreaser_;
+     116             : 
+     117             :   //! Cooling factor.
+     118             :   double cooling_factor_;
+     119             : 
+     120             :   //! Cooling scheme.
+     121             :   std::string cooling_scheme_;
+     122             : };
+     123             : 
+     124             : // Register MAZE_SIMULATED_ANNEALING.
+     125       10421 : PLUMED_REGISTER_ACTION(Simulated_Annealing, "MAZE_SIMULATED_ANNEALING")
+     126             : 
+     127           2 : void Simulated_Annealing::registerKeywords(Keywords& keys) {
+     128           2 :   Optimizer::registerKeywords(keys);
+     129             : 
+     130           6 :   keys.add(
+     131             :     "compulsory",
+     132             :     "PROBABILITY_DECREASER",
+     133             :     "Temperature-like parameter that is decreased during optimization to modify "
+     134             :     "the Metropolis-Hastings acceptance probability."
+     135             :   );
+     136             : 
+     137           4 :   keys.add(
+     138             :     "compulsory",
+     139             :     "COOLING",
+     140             :     "Reduction factor for PROBABILITY_DECREASER, should be in (0, 1]."
+     141             :   );
+     142             : 
+     143           4 :   keys.add(
+     144             :     "compulsory",
+     145             :     "COOLING_SCHEME",
+     146             :     "Cooling scheme: geometric."
+     147             :   );
+     148           2 : }
+     149             : 
+     150           1 : Simulated_Annealing::Simulated_Annealing(const ActionOptions& ao)
+     151           1 :   : PLUMED_OPT_INIT(ao)
+     152             : {
+     153           1 :   log.printf("maze> Simulated annealing optimizer.\n");
+     154             : 
+     155           2 :   if(keywords.exists("COOLING")) {
+     156           1 :     parse("COOLING", cooling_factor_);
+     157             : 
+     158           1 :     plumed_massert(
+     159             :       cooling_factor_ > 0 && cooling_factor_ <= 1,
+     160             :       "maze> COOLING should be in (0, 1]; preferably 0.95.\n"
+     161             :     );
+     162             :   }
+     163             : 
+     164           2 :   if(keywords.exists("PROBABILITY_DECREASER")) {
+     165           1 :     parse("PROBABILITY_DECREASER", probability_decreaser_);
+     166             : 
+     167           1 :     plumed_massert(
+     168             :       probability_decreaser_ > 0,
+     169             :       "maze> PROBABILITY_DECREASER should be explicitly specified and positive.\n");
+     170             :   }
+     171             : 
+     172           2 :   if(keywords.exists("COOLING_SCHEME")) {
+     173           1 :     parse("COOLING_SCHEME", cooling_scheme_);
+     174             : 
+     175           1 :     log.printf(
+     176             :       "maze> COOLING_SCHEME read: %s.\n",
+     177             :       cooling_scheme_.c_str()
+     178             :     );
+     179             :   }
+     180             : 
+     181           2 :   set_label("SIMULATED_ANNEALING");
+     182             : 
+     183             :   // Calculate an optimal direction at the beginning of the MD simulation.
+     184             :   start_step_0();
+     185             : 
+     186           1 :   checkRead();
+     187           1 : }
+     188             : 
+     189           2 : Simulated_Annealing::~Simulated_Annealing() {
+     190           1 :   delete neighbor_list_;
+     191           2 : }
+     192             : 
+     193          30 : void Simulated_Annealing::decrease_probability(unsigned int time) {
+     194          30 :   if (cooling_scheme_ == "linear") {
+     195           0 :     probability_decreaser_ -= time * cooling_factor_;
+     196             :   }
+     197          30 :   else if (cooling_scheme_ == "exponential") {
+     198           0 :     probability_decreaser_ *= pow(cooling_factor_, time);
+     199             :   }
+     200          30 :   else if (cooling_scheme_ == "geometric") {
+     201          30 :     probability_decreaser_ *= cooling_factor_;
+     202             :   }
+     203           0 :   else if (cooling_scheme_ == "logarithmic") {
+     204           0 :     probability_decreaser_ = cooling_factor_ / std::log(time + 1);
+     205             :   }
+     206           0 :   else if (cooling_scheme_ == "hoffman") {
+     207           0 :     probability_decreaser_ = (cooling_factor_ - 1) / std::log(time);
+     208             :   }
+     209          30 : }
+     210             : 
+     211           3 : void Simulated_Annealing::optimize() {
+     212           3 :   sampling_r_ = sampling_radius();
+     213             :   double rad_s;
+     214           3 :   const unsigned nl_size = neighbor_list_->size();
+     215             : 
+     216           3 :   Vector distance, distance_next;
+     217             : 
+     218          33 :   for (unsigned int iter=0; iter < get_n_iterations(); ++iter) {
+     219             :     double action = 0;
+     220             :     double action_next = 0;
+     221             : 
+     222          30 :     rad_s = rnd::next_double(sampling_r_);
+     223          30 :     Vector dev = rnd::next_plmd_vector(rad_s);
+     224             : 
+     225          30 :     #pragma omp parallel num_threads(get_n_threads_openmp())
+     226             :     {
+     227             :       #pragma omp for reduction(+:action_next, action)
+     228             :       for (unsigned int i=0; i < nl_size; i++) {
+     229             :         unsigned i0 = neighbor_list_->getClosePair(i).first;
+     230             :         unsigned i1 = neighbor_list_->getClosePair(i).second;
+     231             : 
+     232             :         if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     233             :           continue;
+     234             :         }
+     235             : 
+     236             :         if (pbc_) {
+     237             :           distance = pbcDistance(
+     238             :                        getPosition(i0) + get_opt(),
+     239             :                        getPosition(i1)
+     240             :                      );
+     241             : 
+     242             :           distance_next = pbcDistance(
+     243             :                             getPosition(i0) + dev,
+     244             :                             getPosition(i1)
+     245             :                           );
+     246             :         }
+     247             :         else {
+     248             :           distance = delta(
+     249             :                        getPosition(i0) + get_opt(),
+     250             :                        getPosition(i1)
+     251             :                      );
+     252             : 
+     253             :           distance_next = delta(
+     254             :                             getPosition(i0) + dev,
+     255             :                             getPosition(i1)
+     256             :                           );
+     257             :         }
+     258             : 
+     259             :         action += pairing(distance.modulo());
+     260             :         action_next += pairing(distance_next.modulo());
+     261             :       }
+     262             :     }
+     263             : 
+     264             :     double p = std::min(
+     265          60 :                  1.0,
+     266          30 :                  std::exp(-(action_next - action) / probability_decreaser_)
+     267          30 :                );
+     268             : 
+     269          30 :     double r = rnd::next_double();
+     270             : 
+     271          30 :     if (r < p) {
+     272             :       set_opt(dev);
+     273             :       set_opt_value(action_next);
+     274             :     }
+     275             : 
+     276          30 :     decrease_probability(iter);
+     277             :   }
+     278             : 
+     279           3 :   Vector s = get_opt() / modulo(get_opt());
+     280             :   set_opt(s);
+     281           3 : }
+     282             : 
+     283             : } // namespace maze
+     284             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b4ad724fe9 --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:353697.2 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze10Steered_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze10Steered_MDD2Ev0
_ZN4PLMD4maze10Steered_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze10Steered_MDD0Ev1
_ZN4PLMD4maze10Steered_MDD1Ev1
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe1106createERKNS_13ActionOptionsE1
_ZN4PLMD4maze10Steered_MD16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4maze10Steered_MD8optimizeEv2
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe110C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe110D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.func.html b/coverage/maze/Steered_MD.cpp.func.html new file mode 100644 index 0000000000..a2f5c7b6db --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:353697.2 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze10Steered_MD16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4maze10Steered_MD8optimizeEv2
_ZN4PLMD4maze10Steered_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze10Steered_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze10Steered_MDD0Ev1
_ZN4PLMD4maze10Steered_MDD1Ev1
_ZN4PLMD4maze10Steered_MDD2Ev0
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe1106createERKNS_13ActionOptionsE1
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe110C2Ev3473
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe110D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.gcov.html b/coverage/maze/Steered_MD.cpp.gcov.html new file mode 100644 index 0000000000..166457ac17 --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.gcov.html @@ -0,0 +1,262 @@ + + + + + + + + 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:353697.2 %
Date:2024-06-10 08:19:14Functions:81080.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             :    * Destructor.
+      80             :    */
+      81             :   ~Steered_MD();
+      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             : private:
+      96             :   //! Total distance traveled by the ligand.
+      97             :   double total_dist_;
+      98             : 
+      99             :   //! Ligand center of mass.
+     100             :   Vector com_;
+     101             : 
+     102             :   //! Constant direction of biasing.
+     103             :   Vector pulling_;
+     104             : 
+     105             :   //! PLMD::Value of total distance.
+     106             :   Value* value_total_dist_;
+     107             : };
+     108             : 
+     109             : // Register MAZE_STEERED_MD.
+     110       10421 : PLUMED_REGISTER_ACTION(Steered_MD, "MAZE_STEERED_MD")
+     111             : 
+     112           2 : void Steered_MD::registerKeywords(Keywords& keys) {
+     113           2 :   Optimizer::registerKeywords(keys);
+     114             : 
+     115           2 :   keys.remove("N_ITER");
+     116             : 
+     117           4 :   keys.add(
+     118             :     "compulsory",
+     119             :     "PULLING",
+     120             :     "Constant biasing direction."
+     121             :   );
+     122             : 
+     123           4 :   keys.addOutputComponent(
+     124             :     "tdist",
+     125             :     "default",
+     126             :     "Total distance traveled by biased atoms."
+     127             :   );
+     128           2 : }
+     129             : 
+     130           1 : Steered_MD::Steered_MD(const ActionOptions& ao)
+     131             :   : PLUMED_OPT_INIT(ao),
+     132           1 :     total_dist_(0.0)
+     133             : {
+     134           1 :   log.printf("maze> Steered MD.\n");
+     135             : 
+     136           2 :   if (keywords.exists("PULLING")) {
+     137             :     std::vector<double> v;
+     138           1 :     parseVector("PULLING", v);
+     139           1 :     pulling_ = tls::vector2Vector(v);
+     140             : 
+     141           1 :     log.printf("maze> PULLING read.\n");
+     142             :   }
+     143             : 
+     144           2 :   set_label("STEERED_MD");
+     145             :   set_opt(pulling_);
+     146             :   set_opt_value(0.0);
+     147             : 
+     148             :   start_step_stride();
+     149             : 
+     150           1 :   checkRead();
+     151             : 
+     152           1 :   com_ = center_of_mass();
+     153             : 
+     154           1 :   addComponent("tdist");
+     155           1 :   componentIsNotPeriodic("tdist");
+     156           1 :   value_total_dist_ = getPntrToComponent("tdist");
+     157           1 : }
+     158             : 
+     159           2 : Steered_MD::~Steered_MD() {
+     160           1 :   delete neighbor_list_;
+     161           2 : }
+     162             : 
+     163           2 : void Steered_MD::optimize() {
+     164           2 :   Vector c = center_of_mass();
+     165           2 :   Vector d;
+     166             : 
+     167           2 :   if (pbc_) {
+     168           2 :     d = pbcDistance(c, com_);
+     169             :   }
+     170             :   else {
+     171           0 :     d = delta(c, com_);
+     172             :   }
+     173             : 
+     174           2 :   double dist = d.modulo();
+     175           2 :   total_dist_ += dist;
+     176             : 
+     177             :   set_opt(pulling_);
+     178           2 :   set_opt_value(score());
+     179           2 :   com_ = c;
+     180             : 
+     181           2 :   value_total_dist_->set(total_dist_);
+     182           2 : }
+     183             : 
+     184             : } // namespace maze
+     185             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..77d51543ea --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/maze/Tools.h.func.html b/coverage/maze/Tools.h.func.html new file mode 100644 index 0000000000..506534ddf1 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/maze/Tools.h.gcov.html b/coverage/maze/Tools.h.gcov.html new file mode 100644 index 0000000000..4074eca9d6 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/maze/index-sort-f.html b/coverage/maze/index-sort-f.html new file mode 100644 index 0000000000..b21eec6acf --- /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:66079383.2 %
Date:2024-06-10 08:19:14Functions:9411780.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Memetic.h +
55.2%55.2%
+
55.2 %111 / 20165.0 %13 / 20
Loss.h +
50.0%50.0%
+
50.0 %1 / 266.7 %2 / 3
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Memetic.cpp +
100.0%
+
100.0 %64 / 6480.0 %8 / 10
Random_Walk.cpp +
100.0%
+
100.0 %18 / 1880.0 %8 / 10
Steered_MD.cpp +
97.2%97.2%
+
97.2 %35 / 3680.0 %8 / 10
Random_Acceleration_MD.cpp +
95.6%95.6%
+
95.6 %43 / 4580.0 %8 / 10
Simulated_Annealing.cpp +
88.7%88.7%
+
88.7 %47 / 5381.8 %9 / 11
Random_MT.cpp +
80.0%80.0%
+
80.0 %16 / 2083.3 %5 / 6
Loss.cpp +
100.0%
+
100.0 %24 / 2485.7 %6 / 7
Optimizer_Bias.cpp +
98.0%98.0%
+
98.0 %96 / 9888.9 %8 / 9
Optimizer.cpp +
88.6%88.6%
+
88.6 %163 / 18490.0 %9 / 10
Optimizer.h +
100.0%
+
100.0 %12 / 12100.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
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/index-sort-l.html b/coverage/maze/index-sort-l.html new file mode 100644 index 0000000000..dde80b9325 --- /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:66079383.2 %
Date:2024-06-10 08:19:14Functions:9411780.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
55.2%55.2%
+
55.2 %111 / 20165.0 %13 / 20
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Random_MT.cpp +
80.0%80.0%
+
80.0 %16 / 2083.3 %5 / 6
Optimizer.cpp +
88.6%88.6%
+
88.6 %163 / 18490.0 %9 / 10
Simulated_Annealing.cpp +
88.7%88.7%
+
88.7 %47 / 5381.8 %9 / 11
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
Random_Acceleration_MD.cpp +
95.6%95.6%
+
95.6 %43 / 4580.0 %8 / 10
Steered_MD.cpp +
97.2%97.2%
+
97.2 %35 / 3680.0 %8 / 10
Optimizer_Bias.cpp +
98.0%98.0%
+
98.0 %96 / 9888.9 %8 / 9
Member.h +
100.0%
+
100.0 %5 / 5100.0 %2 / 2
Optimizer.h +
100.0%
+
100.0 %12 / 12100.0 %1 / 1
Random_Walk.cpp +
100.0%
+
100.0 %18 / 1880.0 %8 / 10
Loss.cpp +
100.0%
+
100.0 %24 / 2485.7 %6 / 7
Memetic.cpp +
100.0%
+
100.0 %64 / 6480.0 %8 / 10
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/maze/index.html b/coverage/maze/index.html new file mode 100644 index 0000000000..10849064a9 --- /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:66079383.2 %
Date:2024-06-10 08:19:14Functions:9411780.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Loss.cpp +
100.0%
+
100.0 %24 / 2485.7 %6 / 7
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 %64 / 6480.0 %8 / 10
Memetic.h +
55.2%55.2%
+
55.2 %111 / 20165.0 %13 / 20
Optimizer.cpp +
88.6%88.6%
+
88.6 %163 / 18490.0 %9 / 10
Optimizer.h +
100.0%
+
100.0 %12 / 12100.0 %1 / 1
Optimizer_Bias.cpp +
98.0%98.0%
+
98.0 %96 / 9888.9 %8 / 9
Random_Acceleration_MD.cpp +
95.6%95.6%
+
95.6 %43 / 4580.0 %8 / 10
Random_MT.cpp +
80.0%80.0%
+
80.0 %16 / 2083.3 %5 / 6
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Random_Walk.cpp +
100.0%
+
100.0 %18 / 1880.0 %8 / 10
Simulated_Annealing.cpp +
88.7%88.7%
+
88.7 %47 / 5381.8 %9 / 11
Steered_MD.cpp +
97.2%97.2%
+
97.2 %35 / 3680.0 %8 / 10
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..1e6dbe71a0 --- /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-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12ActionVolumeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12ActionVolumeC2ERKNS_13ActionOptionsE28
_ZN4PLMD11multicolvar12ActionVolume16registerKeywordsERNS_8KeywordsE34
_ZNK4PLMD11multicolvar12ActionVolume19calculateAllVolumesERKjRNS_10MultiValueE69358
_ZNK4PLMD11multicolvar12ActionVolume18inVolumeOfInterestERKj148129
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.cpp.func.html b/coverage/multicolvar/ActionVolume.cpp.func.html new file mode 100644 index 0000000000..ea5f004112 --- /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-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12ActionVolume16registerKeywordsERNS_8KeywordsE34
_ZN4PLMD11multicolvar12ActionVolumeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12ActionVolumeC2ERKNS_13ActionOptionsE28
_ZNK4PLMD11multicolvar12ActionVolume18inVolumeOfInterestERKj148129
_ZNK4PLMD11multicolvar12ActionVolume19calculateAllVolumesERKjRNS_10MultiValueE69358
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.cpp.gcov.html b/coverage/multicolvar/ActionVolume.cpp.gcov.html new file mode 100644 index 0000000000..a3c7bfc3dc --- /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-06-10 08:19:14Functions: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          34 : void ActionVolume::registerKeywords( Keywords& keys ) {
+      28          34 :   VolumeGradientBase::registerKeywords( keys );
+      29         102 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+      30         102 :   keys.use("MEAN"); keys.use("LESS_THAN"); keys.use("MORE_THAN");
+      31         102 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("SUM");
+      32          68 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      33          68 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      34          68 :   keys.addFlag("OUTSIDE",false,"calculate quantities for colvars that are on atoms outside the region of interest");
+      35          34 : }
+      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.15
+
+ + + 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 0000000000..928876e75f --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar12ActionVolume21getNumberOfQuantitiesEv71213
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.h.func.html b/coverage/multicolvar/ActionVolume.h.func.html new file mode 100644 index 0000000000..672ea85ce7 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar12ActionVolume21getNumberOfQuantitiesEv71213
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.h.gcov.html b/coverage/multicolvar/ActionVolume.h.gcov.html new file mode 100644 index 0000000000..20d98a955f --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..b3cf4ff60b --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:515887.9 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9AlphaBeta10isPeriodicEv0
_ZN4PLMD11multicolvar9AlphaBetaC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe1066createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar9AlphaBetaC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar9AlphaBeta16registerKeywordsERNS_8KeywordsE2
_ZNK4PLMD11multicolvar9AlphaBeta7computeERKjRNS0_13AtomValuePackE40
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe106C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe106D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.func.html b/coverage/multicolvar/AlphaBeta.cpp.func.html new file mode 100644 index 0000000000..bac0e3cc35 --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:515887.9 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe1066createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe106C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe106D2Ev3473
_ZN4PLMD11multicolvar9AlphaBeta10isPeriodicEv0
_ZN4PLMD11multicolvar9AlphaBeta16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar9AlphaBetaC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar9AlphaBetaC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar9AlphaBeta7computeERKjRNS0_13AtomValuePackE40
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.gcov.html b/coverage/multicolvar/AlphaBeta.cpp.gcov.html new file mode 100644 index 0000000000..99cc2249cf --- /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:515887.9 %
Date:2024-06-10 08:19:14Functions:6875.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       10421 : PLUMED_REGISTER_ACTION(AlphaBeta,"ALPHABETA")
+     107             : 
+     108           2 : void AlphaBeta::registerKeywords( Keywords& keys ) {
+     109           2 :   MultiColvarBase::registerKeywords( keys );
+     110           4 :   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           4 :   keys.reset_style("ATOMS","atoms");
+     116           4 :   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           4 :   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           4 :   keys.reset_style("REFERENCE","compulsory");
+     121           4 :   keys.reset_style("COEFFICIENT","optional");
+     122           2 : }
+     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.15
+
+ + + 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 0000000000..305bfdd619 --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:637584.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6AnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe1016createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar6AnglesC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar6Angles16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar6Angles10isPeriodicEv6
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe101C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe101D2Ev3473
_ZNK4PLMD11multicolvar6Angles7computeERKjRNS0_13AtomValuePackE26964
_ZNK4PLMD11multicolvar6Angles15calculateWeightERKjRKdRNS0_13AtomValuePackE48510
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.func.html b/coverage/multicolvar/Angles.cpp.func.html new file mode 100644 index 0000000000..a289f74af1 --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:637584.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe1016createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe101C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe101D2Ev3473
_ZN4PLMD11multicolvar6Angles10isPeriodicEv6
_ZN4PLMD11multicolvar6Angles16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar6AnglesC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar6AnglesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar6Angles15calculateWeightERKjRKdRNS0_13AtomValuePackE48510
_ZNK4PLMD11multicolvar6Angles7computeERKjRNS0_13AtomValuePackE26964
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.gcov.html b/coverage/multicolvar/Angles.cpp.gcov.html new file mode 100644 index 0000000000..411c52a47c --- /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:637584.0 %
Date:2024-06-10 08:19:14Functions:8988.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 "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       10423 : PLUMED_REGISTER_ACTION(Angles,"ANGLES")
+     102             : 
+     103           3 : void Angles::registerKeywords( Keywords& keys ) {
+     104           3 :   MultiColvarBase::registerKeywords( keys );
+     105           6 :   keys.use("MEAN"); keys.use("LESS_THAN");
+     106           9 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MORE_THAN");
+     107             :   // Could also add Region here in theory
+     108           6 :   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           6 :   keys.reset_style("ATOMS","atoms");
+     114           6 :   keys.add("atoms-1","GROUP","Calculate angles for each distinct set of three atoms in the group");
+     115           6 :   keys.add("atoms-2","GROUPA","A group of central atoms about which angles should be calculated");
+     116           6 :   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           6 :   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           6 :   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           6 :   keys.add("optional","SWITCHA","A switching function on the distance between the atoms in group A and the atoms in "
+     127             :            "group B");
+     128           6 :   keys.add("optional","SWITCHB","A switching function on the distance between the atoms in group A and the atoms in "
+     129             :            "group B");
+     130           3 : }
+     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.15
+
+ + + 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 0000000000..1bad34436b --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack23setupAtomsFromLinkCellsERKSt6vectorIjSaIjEERKNS_13VectorGenericILj3EEERKNS_9LinkCellsE220567
_ZN4PLMD11multicolvar13AtomValuePackC2ERNS_10MultiValueEPKNS0_15MultiColvarBaseE447981
_ZN4PLMD11multicolvar13AtomValuePack18updateUsingIndicesEv516269
_ZN4PLMD11multicolvar13AtomValuePack17addComDerivativesERKiRKNS_13VectorGenericILj3EEERKNS0_9CatomPackE905762
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.cpp.func.html b/coverage/multicolvar/AtomValuePack.cpp.func.html new file mode 100644 index 0000000000..a3f1d9579f --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack17addComDerivativesERKiRKNS_13VectorGenericILj3EEERKNS0_9CatomPackE905762
_ZN4PLMD11multicolvar13AtomValuePack18updateUsingIndicesEv516269
_ZN4PLMD11multicolvar13AtomValuePack23setupAtomsFromLinkCellsERKSt6vectorIjSaIjEERKNS_13VectorGenericILj3EEERKNS_9LinkCellsE220567
_ZN4PLMD11multicolvar13AtomValuePackC2ERNS_10MultiValueEPKNS0_15MultiColvarBaseE447981
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.cpp.gcov.html b/coverage/multicolvar/AtomValuePack.cpp.gcov.html new file mode 100644 index 0000000000..9b719ca664 --- /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-06-10 08:19:14Functions: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      447981 : AtomValuePack::AtomValuePack( MultiValue& vals, MultiColvarBase const * mcolv ):
+      30      447981 :   myvals(vals),
+      31      447981 :   mycolv(mcolv),
+      32      447981 :   natoms(0),
+      33      447981 :   indices( vals.getIndices() ),
+      34      447981 :   sort_vector( vals.getSortIndices() ),
+      35      447981 :   myatoms( vals.getAtomVector() )
+      36             : {
+      37      447981 :   if( indices.size()!=mcolv->getNumberOfAtoms() ) {
+      38       23861 :     indices.resize( mcolv->getNumberOfAtoms() );
+      39       23861 :     sort_vector.resize( mcolv->getNumberOfAtoms() );
+      40       23861 :     myatoms.resize( mcolv->getNumberOfAtoms() );
+      41             :   }
+      42      447981 : }
+      43             : 
+      44      220567 : unsigned AtomValuePack::setupAtomsFromLinkCells( const std::vector<unsigned>& cind, const Vector& cpos, const LinkCells& linkcells ) {
+      45      220567 :   if( cells_required.size()!=linkcells.getNumberOfCells() ) cells_required.resize( linkcells.getNumberOfCells() );
+      46             :   // Build the list of cells that we need
+      47      220567 :   unsigned ncells_required=0; linkcells.addRequiredCells( linkcells.findMyCell( cpos ), ncells_required, cells_required );
+      48             :   // Now build the list of atoms we need
+      49      480950 :   natoms=cind.size(); for(unsigned i=0; i<natoms; ++i) indices[i]=cind[i];
+      50      220567 :   linkcells.retrieveAtomsInCells( ncells_required, cells_required, natoms, indices );
+      51             : //  linkcells.retrieveNeighboringAtoms( cpos, natoms, indices );
+      52   404317627 :   for(unsigned i=0; i<natoms; ++i) myatoms[i]=mycolv->getPositionOfAtomForLinkCells( indices[i] ) - cpos;
+      53      220567 :   if( mycolv->usesPbc() ) mycolv->applyPbc( myatoms, natoms );
+      54      220567 :   return natoms;
+      55             : }
+      56             : 
+      57      516269 : void AtomValuePack::updateUsingIndices() {
+      58      516269 :   if( myvals.updateComplete() ) return;
+      59             : 
+      60             :   unsigned jactive=0;
+      61   402779418 :   for(unsigned i=0; i<natoms; ++i) {
+      62   402464745 :     unsigned base=3*indices[i];
+      63   402464745 :     if( myvals.isActive( base ) ) { sort_vector[jactive]=indices[i]; jactive++; }
+      64             :   }
+      65      314673 :   std::sort( sort_vector.begin(), sort_vector.begin()+jactive );
+      66             : 
+      67      314673 :   myvals.emptyActiveMembers();
+      68     4413720 :   for(unsigned i=0; i<jactive; ++i) {
+      69     4099047 :     unsigned base=3*sort_vector[i]; // indices[i];
+      70     4099047 :     myvals.putIndexInActiveArray( base );
+      71     4099047 :     myvals.putIndexInActiveArray( base + 1 );
+      72     4099047 :     myvals.putIndexInActiveArray( base + 2 );
+      73             :   }
+      74      314673 :   unsigned nvir=3*mycolv->getNumberOfAtoms();
+      75      314673 :   if( myvals.isActive( nvir ) ) {
+      76     2060650 :     for(unsigned i=0; i<9; ++i) myvals.putIndexInActiveArray( nvir + i );
+      77             :   }
+      78      314673 :   myvals.completeUpdate();
+      79             : }
+      80             : 
+      81      905762 : void AtomValuePack::addComDerivatives( const int& ind, const Vector& der, const CatomPack& catom_der ) {
+      82      905762 :   if( ind<0 ) {
+      83      104392 :     for(unsigned ider=0; ider<catom_der.getNumberOfAtomsWithDerivatives(); ++ider) {
+      84       54660 :       unsigned jder=3*catom_der.getIndex(ider);
+      85       54660 :       myvals.addTemporyDerivative( jder+0, catom_der.getDerivative(ider,0,der) );
+      86       54660 :       myvals.addTemporyDerivative( jder+1, catom_der.getDerivative(ider,1,der) );
+      87       54660 :       myvals.addTemporyDerivative( jder+2, catom_der.getDerivative(ider,2,der) );
+      88             :     }
+      89             :   } else {
+      90     1716988 :     for(unsigned ider=0; ider<catom_der.getNumberOfAtomsWithDerivatives(); ++ider) {
+      91      860958 :       unsigned jder=3*catom_der.getIndex(ider);
+      92      860958 :       myvals.addDerivative( ind, jder+0, catom_der.getDerivative(ider,0,der) );
+      93      860958 :       myvals.addDerivative( ind, jder+1, catom_der.getDerivative(ider,1,der) );
+      94      860958 :       myvals.addDerivative( ind, jder+2, catom_der.getDerivative(ider,2,der) );
+      95             :     }
+      96             :   }
+      97      905762 : }
+      98             : 
+      99             : }
+     100             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b884f49f21 --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack17updateDynamicListEv141871
_ZN4PLMD11multicolvar13AtomValuePack7setAtomERKjS3_571749
_ZN4PLMD11multicolvar13AtomValuePack24addTemporyBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE2283013
_ZN4PLMD11multicolvar13AtomValuePack26addTemporyAtomsDerivativesERKjRKNS_13VectorGenericILj3EEE4516294
_ZN4PLMD11multicolvar13AtomValuePack17addBoxDerivativesERKjRKNS_13TensorGenericILj3ELj3EEE56357934
_ZN4PLMD11multicolvar13AtomValuePack19addAtomsDerivativesERKjS3_RKNS_13VectorGenericILj3EEE111743475
_ZNK4PLMD11multicolvar13AtomValuePack16getAbsoluteIndexERKj117937031
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.h.func.html b/coverage/multicolvar/AtomValuePack.h.func.html new file mode 100644 index 0000000000..765f075975 --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack17addBoxDerivativesERKjRKNS_13TensorGenericILj3ELj3EEE56357934
_ZN4PLMD11multicolvar13AtomValuePack17updateDynamicListEv141871
_ZN4PLMD11multicolvar13AtomValuePack19addAtomsDerivativesERKjS3_RKNS_13VectorGenericILj3EEE111743475
_ZN4PLMD11multicolvar13AtomValuePack24addTemporyBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE2283013
_ZN4PLMD11multicolvar13AtomValuePack26addTemporyAtomsDerivativesERKjRKNS_13VectorGenericILj3EEE4516294
_ZN4PLMD11multicolvar13AtomValuePack7setAtomERKjS3_571749
_ZNK4PLMD11multicolvar13AtomValuePack16getAbsoluteIndexERKj117937031
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.h.gcov.html b/coverage/multicolvar/AtomValuePack.h.gcov.html new file mode 100644 index 0000000000..9aa4967e12 --- /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-06-10 08:19:14Functions: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      447927 : 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      230894 :   natoms=nat;
+     105             : }
+     106             : 
+     107             : inline
+     108             : unsigned AtomValuePack::getNumberOfAtoms() const {
+     109   524895430 :   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      605398 :   plumed_dbg_assert( j<natoms ); indices[j]=ind;
+     125             : }
+     126             : 
+     127             : inline
+     128      571749 : void AtomValuePack::setAtom( const unsigned& j, const unsigned& ind ) {
+     129      571749 :   setAtomIndex( j, ind ); myatoms[j]=mycolv->getPositionOfAtomForLinkCells( ind );
+     130      571749 : }
+     131             : 
+     132             : inline
+     133             : unsigned AtomValuePack::getIndex( const unsigned& j ) const {
+     134   679760090 :   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   142032386 :   return myatoms[iatom];
+     151             : }
+     152             : 
+     153             : inline
+     154             : void AtomValuePack::setValue( const unsigned& ival, const double& vv ) {
+     155      695539 :   myvals.setValue( ival, vv );
+     156             : }
+     157             : 
+     158             : inline
+     159             : void AtomValuePack::addValue( const unsigned& ival, const double& vv ) {
+     160    62229581 :   myvals.addValue( ival, vv );
+     161             : }
+     162             : 
+     163             : inline
+     164             : double AtomValuePack::getValue( const unsigned& ival ) const {
+     165     3392234 :   return myvals.get( ival );
+     166             : }
+     167             : 
+     168             : inline
+     169             : void AtomValuePack::addDerivative( const unsigned& ival, const unsigned& jder, const double& der ) {
+     170    37930230 :   myvals.addDerivative( ival, jder, der );
+     171             : }
+     172             : 
+     173             : inline
+     174   111743475 : void AtomValuePack::addAtomsDerivatives( const unsigned& ival, const unsigned& jder, const Vector& der ) {
+     175             :   plumed_dbg_assert( jder<natoms );
+     176   111743475 :   myvals.addDerivative( ival, 3*indices[jder] + 0, der[0] );
+     177   111743475 :   myvals.addDerivative( ival, 3*indices[jder] + 1, der[1] );
+     178   111743475 :   myvals.addDerivative( ival, 3*indices[jder] + 2, der[2] );
+     179   111743475 : }
+     180             : 
+     181             : inline
+     182     4516294 : void AtomValuePack::addTemporyAtomsDerivatives( const unsigned& jder, const Vector& der ) {
+     183             :   plumed_dbg_assert( jder<natoms );
+     184     4516294 :   myvals.addTemporyDerivative( 3*indices[jder] + 0, der[0] );
+     185     4516294 :   myvals.addTemporyDerivative( 3*indices[jder] + 1, der[1] );
+     186     4516294 :   myvals.addTemporyDerivative( 3*indices[jder] + 2, der[2] );
+     187     4516294 : }
+     188             : 
+     189             : inline
+     190     2283013 : void AtomValuePack::addTemporyBoxDerivatives( const Tensor& vir ) {
+     191     2283013 :   unsigned nvir=3*mycolv->getNumberOfAtoms();
+     192    29679169 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) myvals.addTemporyDerivative( nvir + 3*i+j, vir(i,j) );
+     193     2283013 : }
+     194             : 
+     195             : inline
+     196    56357934 : void AtomValuePack::addBoxDerivatives( const unsigned& ival, const Tensor& vir ) {
+     197    56357934 :   unsigned nvir=3*mycolv->getNumberOfAtoms();
+     198   732653142 :   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    56357934 : }
+     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     4742586 :   return myvals;
+     210             : }
+     211             : 
+     212             : }
+     213             : }
+     214             : #endif
+     215             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e9ac82eabc --- /dev/null +++ b/coverage/multicolvar/Bridge.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:425379.2 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6Bridge10isPeriodicEv0
_ZN4PLMD11multicolvar6BridgeC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe736createERKNS_13ActionOptionsE8
_ZN4PLMD11multicolvar6BridgeC1ERKNS_13ActionOptionsE8
_ZN4PLMD11multicolvar6Bridge16registerKeywordsERNS_8KeywordsE9
_ZNK4PLMD11multicolvar6Bridge7computeERKjRNS0_13AtomValuePackE537
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe73C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe73D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Bridge.cpp.func.html b/coverage/multicolvar/Bridge.cpp.func.html new file mode 100644 index 0000000000..a05434a753 --- /dev/null +++ b/coverage/multicolvar/Bridge.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:425379.2 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe736createERKNS_13ActionOptionsE8
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe73C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe73D2Ev3473
_ZN4PLMD11multicolvar6Bridge10isPeriodicEv0
_ZN4PLMD11multicolvar6Bridge16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD11multicolvar6BridgeC1ERKNS_13ActionOptionsE8
_ZN4PLMD11multicolvar6BridgeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar6Bridge7computeERKjRNS0_13AtomValuePackE537
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Bridge.cpp.gcov.html b/coverage/multicolvar/Bridge.cpp.gcov.html new file mode 100644 index 0000000000..7b103e6460 --- /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:425379.2 %
Date:2024-06-10 08:19:14Functions:6875.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       10435 : PLUMED_REGISTER_ACTION(Bridge,"BRIDGE")
+      74             : 
+      75           9 : void Bridge::registerKeywords( Keywords& keys ) {
+      76           9 :   MultiColvarBase::registerKeywords( keys );
+      77          18 :   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          18 :   keys.add("atoms-2","GROUPA","The list of atoms that are in the first interesting part of the structure");
+      80          18 :   keys.add("atoms-2","GROUPB","The list of atoms that are in the second interesting part of the structure");
+      81          18 :   keys.add("optional","SWITCH","The parameters of the two \\ref switchingfunction in the above formula");
+      82          18 :   keys.add("optional","SWITCHA","The \\ref switchingfunction on the distance between bridging atoms and the atoms in "
+      83             :            "group A");
+      84          18 :   keys.add("optional","SWITCHB","The \\ref switchingfunction on the distance between the bridging atoms and the atoms in "
+      85             :            "group B");
+      86           9 : }
+      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.15
+
+ + + 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 0000000000..be6edc8a8b --- /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-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction15deactivate_taskERKj0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17applyBridgeForcesERKSt6vectorIdSaIdEE21
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction10isPeriodicEv34
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC2ERKNS_13ActionOptionsE44
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17turnOnDerivativesEv45
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction29calculateNumericalDerivativesEPNS_15ActionWithValueE60
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction18getCentralAtomPackERKjS3_RNS0_9CatomPackE11462
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction11performTaskERKjS3_RNS_10MultiValueE13042
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction27transformBridgedDerivativesERKjRNS_10MultiValueES5_100985
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html new file mode 100644 index 0000000000..855219ca8f --- /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-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction10isPeriodicEv34
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction15deactivate_taskERKj0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17applyBridgeForcesERKSt6vectorIdSaIdEE21
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17turnOnDerivativesEv45
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction18getCentralAtomPackERKjS3_RNS0_9CatomPackE11462
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction29calculateNumericalDerivativesEPNS_15ActionWithValueE60
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC2ERKNS_13ActionOptionsE44
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction11performTaskERKjS3_RNS_10MultiValueE13042
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction27transformBridgedDerivativesERKjRNS_10MultiValueES5_100985
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html new file mode 100644 index 0000000000..7e13c043fd --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + + 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-06-10 08:19:14Functions: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          57 : void BridgedMultiColvarFunction::registerKeywords( Keywords& keys ) {
+      31          57 :   MultiColvarBase::registerKeywords( keys );
+      32         114 :   keys.add("compulsory","DATA","The multicolvar that calculates the set of base quantities that we are interested in");
+      33          57 : }
+      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          45 : void BridgedMultiColvarFunction::turnOnDerivatives() {
+      54          45 :   BridgedMultiColvarFunction* check = dynamic_cast<BridgedMultiColvarFunction*>( mycolv );
+      55          45 :   if( check ) {
+      56           0 :     if( check->getNumberOfAtoms()>0 ) error("cannot calculate required derivatives of this quantity");
+      57             :   }
+      58          45 :   MultiColvarBase::turnOnDerivatives();
+      59          45 : }
+      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             :   std::vector<Vector>& f( modifyForces() );
+     105          42 :   for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     106          21 :     f[i][0]+=bb[3*i+0]; f[i][1]+=bb[3*i+1]; f[i][2]+=bb[3*i+2];
+     107             :   }
+     108          21 :   applyForces();
+     109             : }
+     110             : 
+     111          34 : bool BridgedMultiColvarFunction::isPeriodic() {
+     112          34 :   return mycolv->isPeriodic();
+     113             : }
+     114             : 
+     115           0 : void BridgedMultiColvarFunction::deactivate_task( const unsigned& taskno ) {
+     116           0 :   plumed_merror("This should never be called");
+     117             : }
+     118             : 
+     119       11462 : void BridgedMultiColvarFunction::getCentralAtomPack( const unsigned& basn, const unsigned& curr, CatomPack& mypack ) {
+     120       11462 :   return mycolv->getCentralAtomPack( basn, curr, mypack );
+     121             : }
+     122             : 
+     123             : }
+     124             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..14129636c7 --- /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-06-10 08:19:14Functions: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
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction22getNumberOfDerivativesEv128406
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.h.func.html b/coverage/multicolvar/BridgedMultiColvarFunction.h.func.html new file mode 100644 index 0000000000..76e33d6be1 --- /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-06-10 08:19:14Functions:71258.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction16clearDerivativesEv785
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17getCentralAtomPosERKj78336
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17isCurrentlyActiveERKj0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction22getNumberOfDerivativesEv128406
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction5applyEv785
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction9calculateEv725
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction18getAbsoluteIndexesEv5
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction26normalizeVectorDerivativesERNS_10MultiValueE0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction29getAbsoluteIndexOfCentralAtomERKj156
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction29getPositionOfAtomForLinkCellsERKj0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html b/coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html new file mode 100644 index 0000000000..79453581e2 --- /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-06-10 08:19:14Functions: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      889857 :   return mycolv;
+     103             : }
+     104             : 
+     105             : inline
+     106      128406 : unsigned BridgedMultiColvarFunction::getNumberOfDerivatives() {
+     107      128406 :   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.15
+
+ + + 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 0000000000..659cda1577 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack6resizeERKj114577
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/CatomPack.cpp.func.html b/coverage/multicolvar/CatomPack.cpp.func.html new file mode 100644 index 0000000000..2ba75071c0 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack6resizeERKj114577
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/CatomPack.cpp.gcov.html b/coverage/multicolvar/CatomPack.cpp.gcov.html new file mode 100644 index 0000000000..d308f42353 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..5223971d61 --- /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:8988.9 %
Date:2024-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack13setDerivativeERKjRKNS_13TensorGenericILj3ELj3EEE638690
_ZNK4PLMD11multicolvar9CatomPack13getDerivativeERKjS3_RKNS_13VectorGenericILj3EEE3179913
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/CatomPack.h.func.html b/coverage/multicolvar/CatomPack.h.func.html new file mode 100644 index 0000000000..4ad5c3fc97 --- /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:8988.9 %
Date:2024-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack13setDerivativeERKjRKNS_13TensorGenericILj3ELj3EEE638690
_ZNK4PLMD11multicolvar9CatomPack13getDerivativeERKjS3_RKNS_13VectorGenericILj3EEE3179913
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/CatomPack.h.gcov.html b/coverage/multicolvar/CatomPack.h.gcov.html new file mode 100644 index 0000000000..21add3cfe8 --- /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:8988.9 %
Date:2024-06-10 08:19:14Functions: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           0 : 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      638690 :   indices[jind]=ind;
+      50             : }
+      51             : 
+      52             : inline
+      53      638690 : void CatomPack::setDerivative( const unsigned& jind, const Tensor& der ) {
+      54             :   plumed_dbg_assert( jind<indices.size() );
+      55      638690 :   derivs[jind]=der;
+      56      638690 : }
+      57             : 
+      58             : inline
+      59             : unsigned CatomPack::getNumberOfAtomsWithDerivatives() const {
+      60     2683868 :   return indices.size();
+      61             : }
+      62             : 
+      63             : inline
+      64             : unsigned CatomPack::getIndex( const unsigned& jind ) const {
+      65             :   plumed_dbg_assert( jind<indices.size() );
+      66     1058157 :   return indices[jind];
+      67             : }
+      68             : 
+      69             : inline
+      70     3179913 : double CatomPack::getDerivative( const unsigned& iatom, const unsigned& jcomp, const Vector& df ) const {
+      71             :   plumed_dbg_assert( iatom<indices.size() );
+      72     3179913 :   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.15
+
+ + + 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 0000000000..3e46b12a88 --- /dev/null +++ b/coverage/multicolvar/CenterOfMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19CenterOfMultiColvarC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe966createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar19CenterOfMultiColvarC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar19CenterOfMultiColvar16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar19CenterOfMultiColvar9calculateEv4
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe96C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe96D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/CenterOfMultiColvar.cpp.func.html b/coverage/multicolvar/CenterOfMultiColvar.cpp.func.html new file mode 100644 index 0000000000..f80015d961 --- /dev/null +++ b/coverage/multicolvar/CenterOfMultiColvar.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe966createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe96C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe96D2Ev3473
_ZN4PLMD11multicolvar19CenterOfMultiColvar16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar19CenterOfMultiColvar9calculateEv4
_ZN4PLMD11multicolvar19CenterOfMultiColvarC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar19CenterOfMultiColvarC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html b/coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html new file mode 100644 index 0000000000..6cc9d181af --- /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-06-10 08:19:14Functions: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 "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       10425 : PLUMED_REGISTER_ACTION(CenterOfMultiColvar,"CENTER_OF_MULTICOLVAR")
+      97             : 
+      98           4 : void CenterOfMultiColvar::registerKeywords(Keywords& keys) {
+      99           4 :   ActionWithVirtualAtom::registerKeywords(keys);
+     100           8 :   keys.add("compulsory","DATA","find the average value for a multicolvar");
+     101           8 :   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           4 : }
+     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        1814 :   }
+     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             :   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             :   setAtomsDerivatives( fderiv );
+     217             :   // Box derivatives?
+     218           4 : }
+     219             : 
+     220             : }
+     221             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..fc02015e18 --- /dev/null +++ b/coverage/multicolvar/CoordinationNumbers.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:5050100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19CoordinationNumbersC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe956createERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar19CoordinationNumbersC1ERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar19CoordinationNumbers16registerKeywordsERNS_8KeywordsE53
_ZN4PLMD11multicolvar19CoordinationNumbers10isPeriodicEv856
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe95C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe95D2Ev3473
_ZNK4PLMD11multicolvar19CoordinationNumbers7computeERKjRNS0_13AtomValuePackE37088
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/CoordinationNumbers.cpp.func.html b/coverage/multicolvar/CoordinationNumbers.cpp.func.html new file mode 100644 index 0000000000..96cc3e43cc --- /dev/null +++ b/coverage/multicolvar/CoordinationNumbers.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:5050100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe956createERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe95C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe95D2Ev3473
_ZN4PLMD11multicolvar19CoordinationNumbers10isPeriodicEv856
_ZN4PLMD11multicolvar19CoordinationNumbers16registerKeywordsERNS_8KeywordsE53
_ZN4PLMD11multicolvar19CoordinationNumbersC1ERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar19CoordinationNumbersC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar19CoordinationNumbers7computeERKjRNS0_13AtomValuePackE37088
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/CoordinationNumbers.cpp.gcov.html b/coverage/multicolvar/CoordinationNumbers.cpp.gcov.html new file mode 100644 index 0000000000..a8c36a2853 --- /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:5050100.0 %
Date:2024-06-10 08:19:14Functions:7887.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 "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       10523 : PLUMED_REGISTER_ACTION(CoordinationNumbers,"COORDINATIONNUMBER")
+      96             : 
+      97          53 : void CoordinationNumbers::registerKeywords( Keywords& keys ) {
+      98          53 :   MultiColvarBase::registerKeywords( keys );
+      99         159 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+     100         106 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     101         106 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     102         106 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     103         106 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     104         106 :   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         106 :   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         212 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+     111         212 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     112         159 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     113          53 : }
+     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.15
+
+ + + 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 0000000000..16789f627e --- /dev/null +++ b/coverage/multicolvar/Density.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:172470.8 %
Date:2024-06-10 08:19:14Functions:81266.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar7Density12getIndexListERKjS3_S3_RSt6vectorIjSaIjEE0
_ZN4PLMD11multicolvar7Density15getValueForTaskERKjRSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar7DensityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar7Density28hasDifferentiableOrientationEv0
_ZN4PLMD11multicolvar7Density10isPeriodicEv4
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe686createERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar7DensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar7Density16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe68C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe68D2Ev3473
_ZNK4PLMD11multicolvar7Density7computeERKjRNS0_13AtomValuePackE15955
_ZNK4PLMD11multicolvar7Density9isDensityEv200727
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Density.cpp.func.html b/coverage/multicolvar/Density.cpp.func.html new file mode 100644 index 0000000000..adfcc8370b --- /dev/null +++ b/coverage/multicolvar/Density.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:172470.8 %
Date:2024-06-10 08:19:14Functions:81266.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe686createERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe68C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe68D2Ev3473
_ZN4PLMD11multicolvar7Density10isPeriodicEv4
_ZN4PLMD11multicolvar7Density12getIndexListERKjS3_S3_RSt6vectorIjSaIjEE0
_ZN4PLMD11multicolvar7Density15getValueForTaskERKjRSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar7Density16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD11multicolvar7DensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar7DensityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar7Density28hasDifferentiableOrientationEv0
_ZNK4PLMD11multicolvar7Density7computeERKjRNS0_13AtomValuePackE15955
_ZNK4PLMD11multicolvar7Density9isDensityEv200727
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Density.cpp.gcov.html b/coverage/multicolvar/Density.cpp.gcov.html new file mode 100644 index 0000000000..78cbb595d8 --- /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:172470.8 %
Date:2024-06-10 08:19:14Functions:81266.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 "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       10441 : PLUMED_REGISTER_ACTION(Density,"DENSITY")
+      69             : 
+      70          12 : void Density::registerKeywords( Keywords& keys ) {
+      71          12 :   MultiColvarBase::registerKeywords( keys );
+      72          12 :   keys.use("SPECIES");
+      73          12 : }
+      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.15
+
+ + + 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 0000000000..876906e0d5 --- /dev/null +++ b/coverage/multicolvar/DihedralCorrelation.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:495098.0 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19DihedralCorrelation10isPeriodicEv0
_ZN4PLMD11multicolvar19DihedralCorrelationC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe926createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar19DihedralCorrelationC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar19DihedralCorrelation16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD11multicolvar19DihedralCorrelation7computeERKjRNS0_13AtomValuePackE590
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe92C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe92D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/DihedralCorrelation.cpp.func.html b/coverage/multicolvar/DihedralCorrelation.cpp.func.html new file mode 100644 index 0000000000..72b91c7b7d --- /dev/null +++ b/coverage/multicolvar/DihedralCorrelation.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:495098.0 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe926createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe92C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe92D2Ev3473
_ZN4PLMD11multicolvar19DihedralCorrelation10isPeriodicEv0
_ZN4PLMD11multicolvar19DihedralCorrelation16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar19DihedralCorrelationC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar19DihedralCorrelationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar19DihedralCorrelation7computeERKjRNS0_13AtomValuePackE590
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/DihedralCorrelation.cpp.gcov.html b/coverage/multicolvar/DihedralCorrelation.cpp.gcov.html new file mode 100644 index 0000000000..41c6b7264e --- /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:495098.0 %
Date:2024-06-10 08:19:14Functions:6875.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       10423 : PLUMED_REGISTER_ACTION(DihedralCorrelation,"DIHCOR")
+      93             : 
+      94           3 : void DihedralCorrelation::registerKeywords( Keywords& keys ) {
+      95           3 :   MultiColvarBase::registerKeywords( keys );
+      96           6 :   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           6 :   keys.reset_style("ATOMS","atoms");
+     102           3 : }
+     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.15
+
+ + + 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 0000000000..793d97d4b6 --- /dev/null +++ b/coverage/multicolvar/DistanceFromContour.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:13215386.3 %
Date:2024-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19DistanceFromContour10isPeriodicEv0
_ZN4PLMD11multicolvar19DistanceFromContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe1006createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar19DistanceFromContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar19DistanceFromContour16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar19DistanceFromContour5applyEv137
_ZN4PLMD11multicolvar19DistanceFromContour9calculateEv137
_ZN4PLMD11multicolvar19DistanceFromContour24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_3115
_ZNK4PLMD11multicolvar19DistanceFromContour7computeERKjRNS0_13AtomValuePackE3115
_ZNK4PLMD11multicolvar19DistanceFromContour9isDensityEv3115
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe100C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe100D2Ev3473
_ZNK4PLMD11multicolvar19DistanceFromContour21getNumberOfQuantitiesEv6230
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/DistanceFromContour.cpp.func.html b/coverage/multicolvar/DistanceFromContour.cpp.func.html new file mode 100644 index 0000000000..a3359d9a97 --- /dev/null +++ b/coverage/multicolvar/DistanceFromContour.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:13215386.3 %
Date:2024-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe1006createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe100C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe100D2Ev3473
_ZN4PLMD11multicolvar19DistanceFromContour10isPeriodicEv0
_ZN4PLMD11multicolvar19DistanceFromContour16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar19DistanceFromContour24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_3115
_ZN4PLMD11multicolvar19DistanceFromContour5applyEv137
_ZN4PLMD11multicolvar19DistanceFromContour9calculateEv137
_ZN4PLMD11multicolvar19DistanceFromContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar19DistanceFromContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar19DistanceFromContour21getNumberOfQuantitiesEv6230
_ZNK4PLMD11multicolvar19DistanceFromContour7computeERKjRNS0_13AtomValuePackE3115
_ZNK4PLMD11multicolvar19DistanceFromContour9isDensityEv3115
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/DistanceFromContour.cpp.gcov.html b/coverage/multicolvar/DistanceFromContour.cpp.gcov.html new file mode 100644 index 0000000000..69162eea16 --- /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:13215386.3 %
Date:2024-06-10 08:19:14Functions:111384.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 "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       10421 : PLUMED_REGISTER_ACTION(DistanceFromContour,"DISTANCE_FROM_CONTOUR")
+     101             : 
+     102           2 : void DistanceFromContour::registerKeywords( Keywords& keys ) {
+     103           2 :   MultiColvarBase::registerKeywords( keys );
+     104           4 :   keys.addOutputComponent("dist1","default","the distance between the reference atom and the nearest contour");
+     105           4 :   keys.addOutputComponent("dist2","default","the distance between the reference atom and the other contour");
+     106           4 :   keys.addOutputComponent("qdist","default","the differentiable (squared) distance between the two contours (see above)");
+     107           4 :   keys.addOutputComponent("thickness","default","the distance between the two contours on the line from the reference atom");
+     108           4 :   keys.add("compulsory","DATA","The input base multicolvar which is being used to calculate the contour");
+     109           4 :   keys.add("atoms","ATOM","The atom whose perpendicular distance we are calculating from the contour");
+     110           4 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density estimation");
+     111           4 :   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           4 :   keys.add("compulsory","DIR","the direction perpendicular to the contour that you are looking for");
+     114           4 :   keys.add("compulsory","CONTOUR","the value we would like for the contour");
+     115           4 :   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           2 : }
+     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           2 :   addComponent("thickness"); componentIsNotPeriodic("thickness");
+     171           2 :   addComponent("dist1"); componentIsNotPeriodic("dist1");
+     172           2 :   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           2 : }
+     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             :     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        3115 : }
+     336             : 
+     337         137 : void DistanceFromContour::apply() {
+     338         274 :   if( getPntrToComponent("qdist")->applyForce( forces ) ) setForcesOnAtoms( forces );
+     339         137 : }
+     340             : 
+     341             : }
+     342             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..c073793655 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:434595.6 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9DistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe1356createERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE52
_ZN4PLMD11multicolvar9Distances10isPeriodicEv111
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe135C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe135D2Ev3473
_ZNK4PLMD11multicolvar9Distances7computeERKjRNS0_13AtomValuePackE15275
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.func.html b/coverage/multicolvar/Distances.cpp.func.html new file mode 100644 index 0000000000..0a7152d949 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:434595.6 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe1356createERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe135C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe135D2Ev3473
_ZN4PLMD11multicolvar9Distances10isPeriodicEv111
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE52
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar9DistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar9Distances7computeERKjRNS0_13AtomValuePackE15275
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.gcov.html b/coverage/multicolvar/Distances.cpp.gcov.html new file mode 100644 index 0000000000..c22a1e6ed8 --- /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:434595.6 %
Date:2024-06-10 08:19:14Functions:7887.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 "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       10521 : PLUMED_REGISTER_ACTION(Distances,"DISTANCES")
+     136             : 
+     137          52 : void Distances::registerKeywords( Keywords& keys ) {
+     138          52 :   MultiColvarBase::registerKeywords( keys );
+     139         156 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     140         208 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN"); // keys.use("DHENERGY");
+     141         208 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     142         104 :   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         104 :   keys.reset_style("ATOMS","atoms");
+     148         104 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     149         104 :   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         104 :   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          52 : }
+     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.15
+
+ + + 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 0000000000..65fc774294 --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:677293.1 %
Date:2024-06-10 08:19:14Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15DumpMultiColvar29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD11multicolvar15DumpMultiColvarC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15DumpMultiColvarD2Ev0
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe836createERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar15DumpMultiColvarC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar15DumpMultiColvarD0Ev22
_ZN4PLMD11multicolvar15DumpMultiColvarD1Ev22
_ZN4PLMD11multicolvar15DumpMultiColvar16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD11multicolvar15DumpMultiColvar5applyEv74
_ZN4PLMD11multicolvar15DumpMultiColvar6updateEv74
_ZN4PLMD11multicolvar15DumpMultiColvar9calculateEv74
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe83C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe83D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.func.html b/coverage/multicolvar/DumpMultiColvar.cpp.func.html new file mode 100644 index 0000000000..0d5723e792 --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:677293.1 %
Date:2024-06-10 08:19:14Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe836createERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe83C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe83D2Ev3473
_ZN4PLMD11multicolvar15DumpMultiColvar16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD11multicolvar15DumpMultiColvar29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD11multicolvar15DumpMultiColvar5applyEv74
_ZN4PLMD11multicolvar15DumpMultiColvar6updateEv74
_ZN4PLMD11multicolvar15DumpMultiColvar9calculateEv74
_ZN4PLMD11multicolvar15DumpMultiColvarC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar15DumpMultiColvarC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15DumpMultiColvarD0Ev22
_ZN4PLMD11multicolvar15DumpMultiColvarD1Ev22
_ZN4PLMD11multicolvar15DumpMultiColvarD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html b/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html new file mode 100644 index 0000000000..f356b51472 --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html @@ -0,0 +1,260 @@ + + + + + + + + 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:677293.1 %
Date:2024-06-10 08:19:14Functions:101376.9 %
+
+ + + + + + + + +

+
          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 "core/PlumedMain.h"
+      28             : #include "core/Atoms.h"
+      29             : #include "tools/Units.h"
+      30             : #include <cstdio>
+      31             : #include "core/GenericMolInfo.h"
+      32             : #include "core/ActionSet.h"
+      33             : #include "MultiColvarBase.h"
+      34             : #include "vesselbase/ActionWithInputVessel.h"
+      35             : #include "vesselbase/StoreDataVessel.h"
+      36             : 
+      37             : namespace PLMD
+      38             : {
+      39             : namespace multicolvar {
+      40             : 
+      41             : //+PLUMEDOC PRINTANALYSIS DUMPMULTICOLVAR
+      42             : /*
+      43             : Dump atom positions and multicolvar on a file.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : In this examples we calculate the distances between the  atoms of the first and the second
+      48             : group and we write them in the file MULTICOLVAR.xyz. For each couple it writes the
+      49             : coordinates of their geometric center and their distance.
+      50             : 
+      51             : \plumedfile
+      52             : pos:   GROUP ATOMS=220,221,235,236,247,248,438,439,450,451,534,535
+      53             : neg:   GROUP ATOMS=65,68,138,182,185,267,270,291,313,316,489,583,621,711
+      54             : DISTANCES GROUPA=pos GROUPB=neg LABEL=slt
+      55             : 
+      56             : DUMPMULTICOLVAR DATA=slt FILE=MULTICOLVAR.xyz
+      57             : \endplumedfile
+      58             : 
+      59             : (see also \ref DISTANCES)
+      60             : 
+      61             : */
+      62             : //+ENDPLUMEDOC
+      63             : 
+      64             : class DumpMultiColvar:
+      65             :   public ActionPilot,
+      66             :   public ActionAtomistic,
+      67             :   public vesselbase::ActionWithInputVessel
+      68             : {
+      69             :   OFile of;
+      70             :   double lenunit;
+      71             :   MultiColvarBase* mycolv;
+      72             :   std::string fmt_xyz;
+      73             : public:
+      74             :   explicit DumpMultiColvar(const ActionOptions&);
+      75             :   ~DumpMultiColvar();
+      76             :   static void registerKeywords( Keywords& keys );
+      77          74 :   void calculate() override {}
+      78           0 :   void calculateNumericalDerivatives( ActionWithValue* vv ) override { plumed_error(); }
+      79          74 :   void apply() override {}
+      80             :   void update() override;
+      81             : };
+      82             : 
+      83       10463 : PLUMED_REGISTER_ACTION(DumpMultiColvar,"DUMPMULTICOLVAR")
+      84             : 
+      85          23 : void DumpMultiColvar::registerKeywords( Keywords& keys ) {
+      86          23 :   Action::registerKeywords( keys );
+      87          23 :   ActionAtomistic::registerKeywords( keys );
+      88          23 :   ActionPilot::registerKeywords( keys );
+      89          23 :   ActionWithInputVessel::registerKeywords( keys );
+      90          46 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+      91          46 :   keys.add("compulsory", "FILE", "file on which to output coordinates");
+      92          46 :   keys.add("compulsory", "UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+      93          46 :   keys.add("optional","PRECISION","The number of digits in trajectory file");
+      94          46 :   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");
+      95          23 : }
+      96             : 
+      97          22 : DumpMultiColvar::DumpMultiColvar(const ActionOptions&ao):
+      98             :   Action(ao),
+      99             :   ActionPilot(ao),
+     100             :   ActionAtomistic(ao),
+     101          22 :   ActionWithInputVessel(ao)
+     102             : {
+     103          44 :   readArgument("store");
+     104          22 :   mycolv = dynamic_cast<MultiColvarBase*>( getDependencies()[0] );
+     105          22 :   plumed_assert( getDependencies().size()==1 );
+     106          22 :   if(!mycolv) error("action labeled " + getDependencies()[0]->getLabel() + " is not a multicolvar");
+     107          22 :   log.printf("  printing colvars calculated by action %s \n",mycolv->getLabel().c_str() );
+     108             : 
+     109             :   std::vector<AtomNumber> atom;
+     110          44 :   parseAtomList("ORIGIN",atom);
+     111          22 :   if( atom.size()>1 ) error("should only be one atom specified");
+     112          22 :   if( atom.size()==1 ) log.printf("  origin is at position of atom : %d\n",atom[0].serial() );
+     113             : 
+     114          44 :   std::string file; parse("FILE",file);
+     115          22 :   if(file.length()==0) error("name out output file was not specified");
+     116          22 :   std::string type=Tools::extension(file);
+     117          22 :   log<<"  file name "<<file<<"\n";
+     118          22 :   if(type!="xyz") error("can only print xyz file type with DUMPMULTICOLVAR");
+     119             : 
+     120             :   fmt_xyz="%f";
+     121             : 
+     122          44 :   std::string precision; parse("PRECISION",precision);
+     123          22 :   if(precision.length()>0) {
+     124          11 :     int p; Tools::convert(precision,p);
+     125          11 :     log<<"  with precision "<<p<<"\n";
+     126             :     std::string a,b;
+     127          11 :     Tools::convert(p+5,a);
+     128          11 :     Tools::convert(p,b);
+     129          22 :     fmt_xyz="%"+a+"."+b+"f";
+     130             :   }
+     131             : 
+     132          44 :   std::string unitname; parse("UNITS",unitname);
+     133          22 :   if(unitname!="PLUMED") {
+     134           1 :     Units myunit; myunit.setLength(unitname);
+     135           1 :     lenunit=plumed.getAtoms().getUnits().getLength()/myunit.getLength();
+     136           1 :   }
+     137          21 :   else lenunit=1.0;
+     138             : 
+     139          22 :   checkRead();
+     140          22 :   of.link(*this);
+     141          22 :   of.open(file);
+     142          22 :   log.printf("  printing atom positions in %s units \n", unitname.c_str() );
+     143          22 :   requestAtoms(atom); addDependency( mycolv );
+     144          22 : }
+     145             : 
+     146          74 : void DumpMultiColvar::update() {
+     147          74 :   of.printf("%u\n",mycolv->getCurrentNumberOfActiveTasks());
+     148          74 :   const Tensor & t(mycolv->getPbc().getBox());
+     149          74 :   if(mycolv->getPbc().isOrthorombic()) {
+     150         148 :     of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     151             :   } else {
+     152           0 :     of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),
+     153           0 :               lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     154           0 :               lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     155           0 :               lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     156             :              );
+     157             :   }
+     158          74 :   vesselbase::StoreDataVessel* stash=dynamic_cast<vesselbase::StoreDataVessel*>( getPntrToArgument() );
+     159             :   plumed_dbg_assert( stash );
+     160          74 :   std::vector<double> cvals( mycolv->getNumberOfQuantities() );
+     161       13974 :   for(unsigned i=0; i<mycolv->getCurrentNumberOfActiveTasks(); ++i) {
+     162             :     const char* defname="X";
+     163             :     const char* name=defname;
+     164             : 
+     165       13900 :     Vector apos = mycolv->getCentralAtomPos( mycolv->getPositionInFullTaskList(i) );
+     166       13900 :     if( getNumberOfAtoms()>0 ) apos=pbcDistance( getPosition(0), apos );
+     167       27800 :     of.printf(("%s "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz).c_str(),name,lenunit*apos[0],lenunit*apos[1],lenunit*apos[2]);
+     168       13900 :     stash->retrieveSequentialValue( i, true, cvals );
+     169       13900 :     if( mycolv->weightWithDerivatives() ) {
+     170        2370 :       for(unsigned j=0; j<cvals.size(); ++j) of.printf((" "+fmt_xyz).c_str(),cvals[j]);
+     171             :     } else {
+     172       27884 :       for(unsigned j=1; j<cvals.size(); ++j) of.printf((" "+fmt_xyz).c_str(),cvals[j]);
+     173             :     }
+     174       13900 :     of.printf("\n");
+     175             :   }
+     176          74 : }
+     177             : 
+     178          44 : DumpMultiColvar::~DumpMultiColvar() {
+     179          44 : }
+     180             : 
+     181             : 
+     182             : }
+     183             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..2af67282e9 --- /dev/null +++ b/coverage/multicolvar/FilterBetween.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:242982.8 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe1486createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar13FilterBetweenC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe1476createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar13FilterBetweenC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar13FilterBetween16registerKeywordsERNS_8KeywordsE5
_ZNK4PLMD11multicolvar13FilterBetween11applyFilterERKdRd735
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe147C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe147D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe148C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe148D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/FilterBetween.cpp.func.html b/coverage/multicolvar/FilterBetween.cpp.func.html new file mode 100644 index 0000000000..d4e2049cb0 --- /dev/null +++ b/coverage/multicolvar/FilterBetween.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:242982.8 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe1476createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe147C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe147D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe1486createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe148C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe148D2Ev3473
_ZN4PLMD11multicolvar13FilterBetween16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar13FilterBetweenC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar13FilterBetweenC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar13FilterBetween11applyFilterERKdRd735
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/FilterBetween.cpp.gcov.html b/coverage/multicolvar/FilterBetween.cpp.gcov.html new file mode 100644 index 0000000000..006979127b --- /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:242982.8 %
Date:2024-06-10 08:19:14Functions: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/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 \ref histogrambead
+      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       10425 : PLUMED_REGISTER_ACTION(FilterBetween,"MFILTER_BETWEEN")
+     148       10419 : PLUMED_REGISTER_ACTION(FilterBetween,"MTRANSFORM_BETWEEN")
+     149             : 
+     150           5 : void FilterBetween::registerKeywords( Keywords& keys ) {
+     151           5 :   MultiColvarFilter::registerKeywords( keys );
+     152          10 :   keys.add("compulsory","LOWER","the lower boundary for the range of interest");
+     153          10 :   keys.add("compulsory","UPPER","the upper boundary for the range of interest");
+     154          10 :   keys.add("compulsory","SMEAR","0.5","the amount by which to smear the value for kernel density estimation");
+     155          10 :   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           5 : }
+     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.15
+
+ + + 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 0000000000..d9848badb2 --- /dev/null +++ b/coverage/multicolvar/FilterLessThan.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:222781.5 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterLessC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe1236createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar10FilterLessC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe1226createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar10FilterLess16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD11multicolvar10FilterLess11applyFilterERKdRd2486
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe122C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe122D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe123C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe123D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/FilterLessThan.cpp.func.html b/coverage/multicolvar/FilterLessThan.cpp.func.html new file mode 100644 index 0000000000..0d3228b503 --- /dev/null +++ b/coverage/multicolvar/FilterLessThan.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:222781.5 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterLess16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar10FilterLessC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar10FilterLessC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe1226createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe122C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe122D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe1236createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe123C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe123D2Ev3473
_ZNK4PLMD11multicolvar10FilterLess11applyFilterERKdRd2486
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/FilterLessThan.cpp.gcov.html b/coverage/multicolvar/FilterLessThan.cpp.gcov.html new file mode 100644 index 0000000000..95c73c067b --- /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:222781.5 %
Date:2024-06-10 08:19:14Functions: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/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 \ref mcolv using a \ref switchingfunction
+      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       10427 : PLUMED_REGISTER_ACTION(FilterLess,"MFILTER_LESS")
+     123       10419 : PLUMED_REGISTER_ACTION(FilterLess,"MTRANSFORM_LESS")
+     124             : 
+     125           6 : void FilterLess::registerKeywords( Keywords& keys ) {
+     126           6 :   MultiColvarFilter::registerKeywords( keys );
+     127          12 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     128          12 :   keys.add("compulsory","MM","0","The m parameter of the switching function ");
+     129          12 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     130          12 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     131          12 :   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           6 : }
+     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.15
+
+ + + 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 0000000000..8cd90fcb0e --- /dev/null +++ b/coverage/multicolvar/FilterMoreThan.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:222781.5 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterMoreC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe1406createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe1396createERKNS_13ActionOptionsE6
_ZN4PLMD11multicolvar10FilterMoreC1ERKNS_13ActionOptionsE7
_ZN4PLMD11multicolvar10FilterMore16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe139C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe139D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe140C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe140D2Ev3473
_ZNK4PLMD11multicolvar10FilterMore11applyFilterERKdRd16806
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/FilterMoreThan.cpp.func.html b/coverage/multicolvar/FilterMoreThan.cpp.func.html new file mode 100644 index 0000000000..8b234615b9 --- /dev/null +++ b/coverage/multicolvar/FilterMoreThan.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:222781.5 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterMore16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD11multicolvar10FilterMoreC1ERKNS_13ActionOptionsE7
_ZN4PLMD11multicolvar10FilterMoreC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe1396createERKNS_13ActionOptionsE6
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe139C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe139D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe1406createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe140C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe140D2Ev3473
_ZNK4PLMD11multicolvar10FilterMore11applyFilterERKdRd16806
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/FilterMoreThan.cpp.gcov.html b/coverage/multicolvar/FilterMoreThan.cpp.gcov.html new file mode 100644 index 0000000000..aa715c704e --- /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:222781.5 %
Date:2024-06-10 08:19:14Functions:91090.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 \ref mcolv using one minus a \ref switchingfunction
+      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       10431 : PLUMED_REGISTER_ACTION(FilterMore,"MFILTER_MORE")
+     140       10421 : PLUMED_REGISTER_ACTION(FilterMore,"MTRANSFORM_MORE")
+     141             : 
+     142           9 : void FilterMore::registerKeywords( Keywords& keys ) {
+     143           9 :   MultiColvarFilter::registerKeywords( keys );
+     144          18 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     145          18 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     146          18 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     147          18 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     148          18 :   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           9 : }
+     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.15
+
+ + + 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 0000000000..47db58e8ec --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:104721.3 %
Date:2024-06-10 08:19:14Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe726createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16InPlaneDistances10isPeriodicEv0
_ZN4PLMD11multicolvar16InPlaneDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16InPlaneDistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16InPlaneDistances7computeERKjRNS0_13AtomValuePackE0
_ZN4PLMD11multicolvar16InPlaneDistances16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe72C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe72D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.func.html b/coverage/multicolvar/InPlaneDistances.cpp.func.html new file mode 100644 index 0000000000..5d4f6a4ac4 --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:104721.3 %
Date:2024-06-10 08:19:14Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe726createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe72C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe72D2Ev3473
_ZN4PLMD11multicolvar16InPlaneDistances10isPeriodicEv0
_ZN4PLMD11multicolvar16InPlaneDistances16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD11multicolvar16InPlaneDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16InPlaneDistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16InPlaneDistances7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.gcov.html b/coverage/multicolvar/InPlaneDistances.cpp.gcov.html new file mode 100644 index 0000000000..a033d32a65 --- /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:104721.3 %
Date:2024-06-10 08:19:14Functions:3837.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 "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       10419 : PLUMED_REGISTER_ACTION(InPlaneDistances,"INPLANEDISTANCES")
+      73             : 
+      74           1 : void InPlaneDistances::registerKeywords( Keywords& keys ) {
+      75           1 :   MultiColvarBase::registerKeywords( keys );
+      76           3 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      77           4 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN");
+      78           4 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      79           2 :   keys.add("atoms","VECTORSTART","The first atom position that is used to define the normal to the plane of interest");
+      80           2 :   keys.add("atoms","VECTOREND","The second atom position that is used to define the normal to the plane of interest");
+      81           2 :   keys.add("atoms-2","GROUP","The set of atoms for which you wish to calculate the in plane distance ");
+      82           1 : }
+      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.15
+
+ + + 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 0000000000..71114bcab9 --- /dev/null +++ b/coverage/multicolvar/LocalAverage.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:10713579.3 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12LocalAverageC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar12LocalAverage15normalizeVectorERSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar12LocalAverage10isPeriodicEv3
_ZN4PLMD11multicolvar12LocalAverageC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe1036createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12LocalAverage16registerKeywordsERNS_8KeywordsE5
_ZNK4PLMD11multicolvar12LocalAverage21getNumberOfQuantitiesEv71
_ZNK4PLMD11multicolvar12LocalAverage7computeERKjRNS0_13AtomValuePackE1004
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe103C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe103D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/LocalAverage.cpp.func.html b/coverage/multicolvar/LocalAverage.cpp.func.html new file mode 100644 index 0000000000..335acdc5e5 --- /dev/null +++ b/coverage/multicolvar/LocalAverage.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:10713579.3 %
Date:2024-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12LocalAverage10isPeriodicEv3
_ZN4PLMD11multicolvar12LocalAverage16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar12LocalAverageC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12LocalAverageC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe1036createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe103C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe103D2Ev3473
_ZNK4PLMD11multicolvar12LocalAverage15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD11multicolvar12LocalAverage21getNumberOfQuantitiesEv71
_ZNK4PLMD11multicolvar12LocalAverage7computeERKjRNS0_13AtomValuePackE1004
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/LocalAverage.cpp.gcov.html b/coverage/multicolvar/LocalAverage.cpp.gcov.html new file mode 100644 index 0000000000..a6737c5af9 --- /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:10713579.3 %
Date:2024-06-10 08:19:14Functions: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             : #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       10427 : PLUMED_REGISTER_ACTION(LocalAverage,"LOCAL_AVERAGE")
+     104             : 
+     105           5 : void LocalAverage::registerKeywords( Keywords& keys ) {
+     106           5 :   MultiColvarBase::registerKeywords( keys );
+     107          10 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     108          10 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     109          10 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     110          10 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     111          10 :   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          15 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+     116          20 :   keys.remove("LOWMEM"); keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
+     117          15 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     118          10 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+     119          15 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+     120          15 :   if( keys.reserved("VSUM") ) keys.use("VSUM");
+     121           5 : }
+     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       49505 :       for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     175             :         unsigned jder=myder.getActiveIndex(j);
+     176       48501 :         if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     177       39465 :           unsigned kder=basen+jder;
+     178     1065555 :           for(unsigned k=2; k<values.size(); ++k) {
+     179     1026090 :             myatoms.addDerivative( k, kder, values[0]*myder.getDerivative(k,jder) );
+     180     1026090 :             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       49505 :     for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     205             :       unsigned jder=myder.getActiveIndex(j);
+     206       48501 :       if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     207       39465 :         unsigned kder=basen+jder;
+     208       39465 :         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      274074 :   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      363595 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+     221       90525 :          (d2+=distance[1]*distance[1])<rcut2 &&
+     222      305390 :          (d2+=distance[2]*distance[2])<rcut2 &&
+     223             :          d2>epsilon) {
+     224             : 
+     225       14639 :       sw = switchingFunction.calculateSqr( d2, dfunc );
+     226             : 
+     227       14639 :       getInputData( i, false, myatoms, values );
+     228       14639 :       if( values.size()>2 ) {
+     229      395253 :         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       14639 :       if( !doNotCalculateDerivatives() ) {
+     236       14639 :         Tensor vir(distance,distance);
+     237       14639 :         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       14639 :         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       19559 :         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       14639 :         unsigned virbas = myvals.getNumberOfDerivatives()-9;
+     248       14639 :         if( values.size()>2 ) {
+     249     1424993 :           for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     250             :             unsigned jder=myder.getActiveIndex(j);
+     251     1410354 :             if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     252     1278603 :               unsigned kder=basen+jder;
+     253    34522281 :               for(unsigned k=2; k<values.size(); ++k) {
+     254    33243678 :                 myatoms.addDerivative( k, kder, sw*values[0]*myder.getDerivative(k,jder) );
+     255    33243678 :                 myatoms.addDerivative( k, kder, sw*values[k]*myder.getDerivative(0,jder) );
+     256             :               }
+     257             :             } else {
+     258      131751 :               unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     259     3557277 :               for(unsigned k=2; k<values.size(); ++k) {
+     260     3425526 :                 myatoms.addDerivative( k, kder, sw*values[0]*myder.getDerivative(k,jder) );
+     261     3425526 :                 myatoms.addDerivative( k, kder, sw*values[k]*myder.getDerivative(0,jder) );
+     262             :               }
+     263             :             }
+     264             :           }
+     265      395253 :           for(unsigned k=2; k<values.size(); ++k) {
+     266      380614 :             addAtomDerivatives( k, 0, (-dfunc)*values[0]*values[k]*distance, myatoms );
+     267      380614 :             addAtomDerivatives( k, i, (+dfunc)*values[0]*values[k]*distance, myatoms );
+     268      380614 :             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       14639 :         addAtomDerivatives( -1, 0, (-dfunc)*values[0]*distance, myatoms );
+     289       14639 :         addAtomDerivatives( -1, i, (+dfunc)*values[0]*distance, myatoms );
+     290     1424993 :         for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     291             :           unsigned jder=myder.getActiveIndex(j);
+     292     1410354 :           if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     293     1278603 :             unsigned kder=basen+jder;
+     294     1278603 :             myvals.addTemporyDerivative( kder, sw*myder.getDerivative(0, jder) );
+     295             :           } else {
+     296      131751 :             unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     297      131751 :             myvals.addTemporyDerivative( kder, sw*myder.getDerivative(0, jder) );
+     298             :           }
+     299             :         }
+     300       14639 :         myatoms.addTemporyBoxDerivatives( (-dfunc)*values[0]*vir );
+     301       14639 :         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      132755 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+     317      131751 :       unsigned jder=myvals.getActiveIndex(j);
+     318     3557277 :       for(unsigned i=2; i<values.size(); ++i) {
+     319     3425526 :         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.15
+
+ + + 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 0000000000..8eae949dc9 --- /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-06-10 08:19:14Functions: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_EE48
_ZN4PLMD11multicolvar15MultiColvarBase13readTwoGroupsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RSt6vectorINS_10AtomNumberESaISB_EE76
_ZN4PLMD11multicolvar15MultiColvarBase21resizeBookeepingArrayERKjS3_96
_ZNK4PLMD11multicolvar15MultiColvarBase21splitInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE106
_ZN4PLMD11multicolvar15MultiColvarBase17setLinkCellCutoffERKdd191
_ZN4PLMD11multicolvar15MultiColvarBase29calculateNumericalDerivativesEPNS_15ActionWithValueE213
_ZN4PLMD11multicolvar15MultiColvarBase20setupMultiColvarBaseERKSt6vectorINS_10AtomNumberESaIS3_EE308
_ZN4PLMD11multicolvar15MultiColvarBaseC2ERKNS_13ActionOptionsE350
_ZN4PLMD11multicolvar15MultiColvarBase16registerKeywordsERNS_8KeywordsE425
_ZN4PLMD11multicolvar15MultiColvarBase17turnOnDerivativesEv429
_ZN4PLMD11multicolvar15MultiColvarBase18filtersUsedAsInputEv467
_ZN4PLMD11multicolvar15MultiColvarBase24parseMultiColvarAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE468
_ZN4PLMD11multicolvar15MultiColvarBase14setupLinkCellsEv1938
_ZN4PLMD11multicolvar15MultiColvarBase5applyEv1994
_ZN4PLMD11multicolvar15MultiColvarBase7prepareEv2959
_ZN4PLMD11multicolvar15MultiColvarBase27setupNonUseSpeciesLinkCellsERKj4628
_ZN4PLMD11multicolvar15MultiColvarBase13retrieveAtomsEv6548
_ZN4PLMD11multicolvar15MultiColvarBase9calculateEv9024
_ZN4PLMD11multicolvar15MultiColvarBase18setupActiveTaskSetERSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9073
_ZNK4PLMD11multicolvar15MultiColvarBase21mergeInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE38245
_ZNK4PLMD11multicolvar15MultiColvarBase19getInputDerivativesERKjRKbRKNS0_13AtomValuePackE53063
_ZNK4PLMD11multicolvar15MultiColvarBase8applyPbcERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEj220567
_ZNK4PLMD11multicolvar15MultiColvarBase15calculateWeightERKjRKdRNS0_13AtomValuePackE242764
_ZNK4PLMD11multicolvar15MultiColvarBase18decodeIndexToAtomsERKjRSt6vectorIjSaIjEE245988
_ZNK4PLMD11multicolvar15MultiColvarBase11performTaskERKjS3_RNS_10MultiValueE447878
_ZNK4PLMD11multicolvar15MultiColvarBase20setupCurrentAtomListERKjRNS0_13AtomValuePackE451407
_ZN4PLMD11multicolvar15MultiColvarBase18getCentralAtomPackERKjS3_RNS0_9CatomPackE605410
_ZNK4PLMD11multicolvar15MultiColvarBase17updateActiveAtomsERNS0_13AtomValuePackE658140
_ZNK4PLMD11multicolvar15MultiColvarBase17addComDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE905762
_ZNK4PLMD11multicolvar15MultiColvarBase12getInputDataERKjRKbRKNS0_13AtomValuePackERSt6vectorIdSaIdEE1122658
_ZNK4PLMD11multicolvar15MultiColvarBase18addAtomDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE1428471
_ZN4PLMD11multicolvar15MultiColvarBase17getCentralAtomPosERKj2753935
_ZN4PLMD11multicolvar15MultiColvarBase13addTaskToListERKj12512606
_ZNK4PLMD11multicolvar15MultiColvarBase26accumulateSymmetryFunctionERKiRKjRKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERNS0_13AtomValuePackE64359697
_ZNK4PLMD11multicolvar15MultiColvarBase13getSeparationERKNS_13VectorGenericILj3EEES5_121150993
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.cpp.func.html b/coverage/multicolvar/MultiColvarBase.cpp.func.html new file mode 100644 index 0000000000..92a5b43238 --- /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-06-10 08:19:14Functions:404197.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBase13addTaskToListERKj12512606
_ZN4PLMD11multicolvar15MultiColvarBase13readTwoGroupsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RSt6vectorINS_10AtomNumberESaISB_EE76
_ZN4PLMD11multicolvar15MultiColvarBase13retrieveAtomsEv6548
_ZN4PLMD11multicolvar15MultiColvarBase14setupLinkCellsEv1938
_ZN4PLMD11multicolvar15MultiColvarBase15readThreeGroupsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKbSB_RSt6vectorINS_10AtomNumberESaISD_EE10
_ZN4PLMD11multicolvar15MultiColvarBase16registerKeywordsERNS_8KeywordsE425
_ZN4PLMD11multicolvar15MultiColvarBase17getCentralAtomPosERKj2753935
_ZN4PLMD11multicolvar15MultiColvarBase17readGroupKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_S9_RKbSB_RSt6vectorINS_10AtomNumberESaISD_EE12
_ZN4PLMD11multicolvar15MultiColvarBase17setLinkCellCutoffERKdd191
_ZN4PLMD11multicolvar15MultiColvarBase17turnOnDerivativesEv429
_ZN4PLMD11multicolvar15MultiColvarBase18filtersUsedAsInputEv467
_ZN4PLMD11multicolvar15MultiColvarBase18getCentralAtomPackERKjS3_RNS0_9CatomPackE605410
_ZN4PLMD11multicolvar15MultiColvarBase18setupActiveTaskSetERSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9073
_ZN4PLMD11multicolvar15MultiColvarBase20readAtomsLikeKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE48
_ZN4PLMD11multicolvar15MultiColvarBase20setupMultiColvarBaseERKSt6vectorINS_10AtomNumberESaIS3_EE308
_ZN4PLMD11multicolvar15MultiColvarBase21resizeBookeepingArrayERKjS3_96
_ZN4PLMD11multicolvar15MultiColvarBase22setAtomsForCentralAtomERKSt6vectorIbSaIbEE19
_ZN4PLMD11multicolvar15MultiColvarBase24parseMultiColvarAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE468
_ZN4PLMD11multicolvar15MultiColvarBase27setupNonUseSpeciesLinkCellsERKj4628
_ZN4PLMD11multicolvar15MultiColvarBase29calculateNumericalDerivativesEPNS_15ActionWithValueE213
_ZN4PLMD11multicolvar15MultiColvarBase5applyEv1994
_ZN4PLMD11multicolvar15MultiColvarBase7prepareEv2959
_ZN4PLMD11multicolvar15MultiColvarBase9buildSetsEv4
_ZN4PLMD11multicolvar15MultiColvarBase9calculateEv9024
_ZN4PLMD11multicolvar15MultiColvarBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15MultiColvarBaseC2ERKNS_13ActionOptionsE350
_ZNK4PLMD11multicolvar15MultiColvarBase11performTaskERKjS3_RNS_10MultiValueE447878
_ZNK4PLMD11multicolvar15MultiColvarBase12getInputDataERKjRKbRKNS0_13AtomValuePackERSt6vectorIdSaIdEE1122658
_ZNK4PLMD11multicolvar15MultiColvarBase13getSeparationERKNS_13VectorGenericILj3EEES5_121150993
_ZNK4PLMD11multicolvar15MultiColvarBase15calculateWeightERKjRKdRNS0_13AtomValuePackE242764
_ZNK4PLMD11multicolvar15MultiColvarBase17addComDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE905762
_ZNK4PLMD11multicolvar15MultiColvarBase17getLinkCellCutoffEv8
_ZNK4PLMD11multicolvar15MultiColvarBase17updateActiveAtomsERNS0_13AtomValuePackE658140
_ZNK4PLMD11multicolvar15MultiColvarBase18addAtomDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE1428471
_ZNK4PLMD11multicolvar15MultiColvarBase18decodeIndexToAtomsERKjRSt6vectorIjSaIjEE245988
_ZNK4PLMD11multicolvar15MultiColvarBase19getInputDerivativesERKjRKbRKNS0_13AtomValuePackE53063
_ZNK4PLMD11multicolvar15MultiColvarBase20setupCurrentAtomListERKjRNS0_13AtomValuePackE451407
_ZNK4PLMD11multicolvar15MultiColvarBase21mergeInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE38245
_ZNK4PLMD11multicolvar15MultiColvarBase21splitInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE106
_ZNK4PLMD11multicolvar15MultiColvarBase26accumulateSymmetryFunctionERKiRKjRKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERNS0_13AtomValuePackE64359697
_ZNK4PLMD11multicolvar15MultiColvarBase8applyPbcERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEj220567
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.cpp.gcov.html b/coverage/multicolvar/MultiColvarBase.cpp.gcov.html new file mode 100644 index 0000000000..7d690e79c3 --- /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-06-10 08:19:14Functions: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         425 : void MultiColvarBase::registerKeywords( Keywords& keys ) {
+      39         425 :   Action::registerKeywords( keys );
+      40         425 :   ActionWithValue::registerKeywords( keys );
+      41         425 :   ActionAtomistic::registerKeywords( keys );
+      42         850 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      43         425 :   ActionWithVessel::registerKeywords( keys );
+      44         850 :   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         425 :   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         850 :   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         850 :   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         850 :   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        1275 :   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         425 : }
+      73             : 
+      74         350 : MultiColvarBase::MultiColvarBase(const ActionOptions&ao):
+      75             :   Action(ao),
+      76             :   ActionAtomistic(ao),
+      77             :   ActionWithValue(ao),
+      78             :   ActionWithVessel(ao),
+      79         350 :   usepbc(false),
+      80         350 :   allthirdblockintasks(false),
+      81         350 :   uselinkforthree(false),
+      82         350 :   linkcells(comm),
+      83         350 :   threecells(comm),
+      84         350 :   setup_completed(false),
+      85         350 :   atomsWereRetrieved(false),
+      86         350 :   matsums(false),
+      87         350 :   usespecies(false),
+      88         700 :   nblock(0)
+      89             : {
+      90         700 :   if( keywords.exists("NOPBC") ) {
+      91         350 :     bool nopbc=!usepbc; parseFlag("NOPBC",nopbc);
+      92         350 :     usepbc=!nopbc;
+      93             :   }
+      94         700 :   if( keywords.exists("SPECIESA") ) { matsums=usespecies=true; }
+      95         350 : }
+      96             : 
+      97          48 : void MultiColvarBase::readAtomsLikeKeyword( const std::string & key, const int& natoms, std::vector<AtomNumber>& all_atoms ) {
+      98          48 :   plumed_assert( !usespecies );
+      99          48 :   if( all_atoms.size()>0 ) return;
+     100             : 
+     101             :   std::vector<AtomNumber> t;
+     102          48 :   for(int i=1;; ++i ) {
+     103         970 :     parseAtomList(key, i, t );
+     104         970 :     if( t.empty() ) break;
+     105             : 
+     106         922 :     log.printf("  Colvar %d is calculated from atoms : ", i);
+     107        3450 :     for(unsigned j=0; j<t.size(); ++j) log.printf("%d ",t[j].serial() );
+     108         922 :     log.printf("\n");
+     109             : 
+     110         922 :     if( i==1 && natoms<0 ) { ablocks.resize(t.size()); }
+     111         916 :     else if( i==1 ) ablocks.resize(natoms);
+     112         922 :     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        3450 :     for(unsigned j=0; j<ablocks.size(); ++j) {
+     117        2528 :       ablocks[j].push_back( ablocks.size()*(i-1)+j ); all_atoms.push_back( t[j] );
+     118        2528 :       atom_lab.push_back( std::pair<unsigned,unsigned>( 0, ablocks.size()*(i-1)+j ) );
+     119             :     }
+     120         922 :     t.resize(0);
+     121         922 :   }
+     122          48 :   if( all_atoms.size()>0 ) {
+     123          48 :     nblock=0;
+     124         970 :     for(unsigned i=0; i<ablocks[0].size(); ++i) addTaskToList( i );
+     125             :   }
+     126             : }
+     127             : 
+     128         468 : bool MultiColvarBase::parseMultiColvarAtomList(const std::string& key, const int& num, std::vector<AtomNumber>& t) {
+     129             :   std::vector<std::string> mlabs;
+     130         468 :   if( num<0 ) parseVector(key,mlabs);
+     131           0 :   else parseNumberedVector(key,num,mlabs);
+     132             : 
+     133         468 :   if( mlabs.size()==0 ) return false;
+     134             : 
+     135         321 :   std::string mname; unsigned found_mcolv=mlabs.size();
+     136         448 :   for(unsigned i=0; i<mlabs.size(); ++i) {
+     137         326 :     MultiColvarBase* mycolv = plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlabs[i]);
+     138         326 :     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         321 :   if( found_mcolv==0 ) {
+     158         199 :     std::vector<AtomNumber> tt; ActionAtomistic::interpretAtomList( mlabs, tt );
+     159       89460 :     for(unsigned i=0; i<tt.size(); ++i) { atom_lab.push_back( std::pair<unsigned,unsigned>( 0, t.size() + i ) ); }
+     160         199 :     log.printf("  keyword %s takes atoms : ", key.c_str() );
+     161       89460 :     for(unsigned i=0; i<tt.size(); ++i) { t.push_back( tt[i] ); log.printf("%d ",tt[i].serial() ); }
+     162         199 :     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         468 : }
+     173             : 
+     174          76 : void MultiColvarBase::readTwoGroups( const std::string& key0, const std::string& key1, const std::string& key2, std::vector<AtomNumber>& all_atoms ) {
+     175          76 :   plumed_dbg_assert( keywords.exists(key0) && keywords.exists(key1) && keywords.exists(key2) ); ablocks.resize( 2 );
+     176             : 
+     177          76 :   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          50 :     parseMultiColvarAtomList(key1,-1,all_atoms);
+     190          67 :     ablocks[0].resize( atom_lab.size() ); for(unsigned i=0; i<ablocks[0].size(); ++i) ablocks[0][i]=i;
+     191          50 :     parseMultiColvarAtomList(key2,-1,all_atoms);
+     192        1119 :     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          50 :     if( ablocks[0].size()>ablocks[1].size() ) nblock = ablocks[0].size();
+     195          50 :     else nblock=ablocks[1].size();
+     196             : 
+     197          50 :     resizeBookeepingArray( ablocks[0].size(), ablocks[1].size() );
+     198          67 :     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          76 : }
+     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    12512606 : void MultiColvarBase::addTaskToList( const unsigned& taskCode ) {
+     371    12512606 :   plumed_assert( getNumberOfVessels()==0 );
+     372    12512606 :   ActionWithVessel::addTaskToList( taskCode );
+     373    12512606 : }
+     374             : 
+     375          96 : void MultiColvarBase::resizeBookeepingArray( const unsigned& num1, const unsigned& num2 ) {
+     376          96 :   bookeeping.resize( num1, num2 );
+     377        7065 :   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          96 : }
+     381             : 
+     382         308 : void MultiColvarBase::setupMultiColvarBase( const std::vector<AtomNumber>& atoms ) {
+     383         308 :   if( !matsums && atom_lab.size()==0 ) error("No atoms have been read in");
+     384             :   std::vector<AtomNumber> all_atoms;
+     385             :   // Setup decoder array
+     386         308 :   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         245 :   } else if( !usespecies ) {
+     419          87 :     ncentral=ablocks.size(); use_for_central_atom.resize( ablocks.size(), true );
+     420          87 :     numberForCentralAtom = 1.0 / static_cast<double>( ablocks.size() );
+     421         316 :   } else if( keywords.exists("SPECIESA") ) {
+     422         100 :     plumed_assert( atom_lab.size()==0 && all_atoms.size()==0 );
+     423         100 :     ablocks.resize( 1 ); bool readspecies=parseMultiColvarAtomList("SPECIES", -1, all_atoms);
+     424         100 :     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          38 :       if( !parseMultiColvarAtomList("SPECIESA", -1, all_atoms) ) error("missing SPECIES/SPECIESA keyword");
+     428          19 :       unsigned nat1=atom_lab.size();
+     429          38 :       if( !parseMultiColvarAtomList("SPECIESB", -1, all_atoms) ) error("missing SPECIESB keyword");
+     430          19 :       unsigned nat2=atom_lab.size() - nat1;
+     431             : 
+     432         662 :       for(unsigned i=0; i<nat1; ++i) addTaskToList(i);
+     433          19 :       ablocks[0].resize( nat2 );
+     434        3437 :       for(unsigned i=0; i<nat2; ++i) {
+     435             :         bool found=false; unsigned inum=0;
+     436      265449 :         for(unsigned j=0; j<nat1; ++j) {
+     437      262113 :           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        9393 :           } 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        9393 :           } 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        9393 :           } 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          82 :         if( found ) { ablocks[0][i]=inum; }
+     451        3336 :         else { ablocks[0][i]=nat1 + i; }
+     452             :       }
+     453             :     }
+     454             :   }
+     455         308 :   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         435 :   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       59575 :   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         308 :   ActionAtomistic::requestAtoms( all_atoms );
+     472             :   // And setup dependencies
+     473         435 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) addDependency( mybasemulticolvars[i] );
+     474             : 
+     475             :   // Setup underlying ActionWithVessel
+     476         308 :   readVesselKeywords();
+     477         308 : }
+     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         429 : void MultiColvarBase::turnOnDerivatives() {
+     490         429 :   ActionWithValue::turnOnDerivatives();
+     491         429 :   needsDerivatives();
+     492         429 :   forcesToApply.resize( getNumberOfDerivatives() );
+     493         429 : }
+     494             : 
+     495         191 : void MultiColvarBase::setLinkCellCutoff( const double& lcut, double tcut ) {
+     496         191 :   plumed_assert( usespecies || ablocks.size()<4 );
+     497         191 :   if( tcut<0 ) tcut=lcut;
+     498             : 
+     499         191 :   if( !linkcells.enabled() ) {
+     500         191 :     linkcells.setCutoff( lcut );
+     501         191 :     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         191 : }
+     507             : 
+     508           8 : double MultiColvarBase::getLinkCellCutoff()  const {
+     509           8 :   return linkcells.getCutoff();
+     510             : }
+     511             : 
+     512        1938 : void MultiColvarBase::setupLinkCells() {
+     513        1938 :   if( (!usespecies && nblock==0) || !linkcells.enabled() ) return ;
+     514             :   // Retrieve any atoms that haven't already been retrieved
+     515        1318 :   for(std::vector<MultiColvarBase*>::iterator p=mybasemulticolvars.begin(); p!=mybasemulticolvars.end(); ++p) {
+     516         203 :     (*p)->retrieveAtoms();
+     517             :   }
+     518        1115 :   retrieveAtoms();
+     519             : 
+     520             :   unsigned iblock;
+     521        1115 :   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        1115 :   nactive_atoms=0;
+     531      387665 :   for(unsigned i=0; i<ablocks[iblock].size(); ++i) {
+     532      386550 :     if( isCurrentlyActive( ablocks[iblock][i] ) ) nactive_atoms++;
+     533             :   }
+     534             : 
+     535        1115 :   if( nactive_atoms>0 ) {
+     536        1115 :     std::vector<Vector> ltmp_pos( nactive_atoms );
+     537        1115 :     std::vector<unsigned> ltmp_ind( nactive_atoms );
+     538             : 
+     539        1115 :     nactive_atoms=0;
+     540        1115 :     if( usespecies ) {
+     541      366350 :       for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     542      365452 :         if( !isCurrentlyActive( ablocks[0][i] ) ) continue;
+     543      365356 :         ltmp_ind[nactive_atoms]=ablocks[0][i];
+     544      365356 :         ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ltmp_ind[nactive_atoms] );
+     545      365356 :         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        1115 :     linkcells.buildCellLists( ltmp_pos, ltmp_ind, getPbc() );
+     558             :   }
+     559             : }
+     560             : 
+     561        4628 : void MultiColvarBase::setupNonUseSpeciesLinkCells( const unsigned& my_always_active ) {
+     562        4628 :   plumed_assert( !usespecies );
+     563        4628 :   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      451407 : bool MultiColvarBase::setupCurrentAtomList( const unsigned& taskCode, AtomValuePack& myatoms ) const {
+     653      451407 :   if( isDensity() ) {
+     654       19070 :     myatoms.setNumberOfAtoms( 1 ); myatoms.setAtom( 0, taskCode ); return true;
+     655      432337 :   } else if( usespecies ) {
+     656      180751 :     std::vector<unsigned> task_atoms(1); task_atoms[0]=taskCode;
+     657      180751 :     unsigned natomsper=myatoms.setupAtomsFromLinkCells( task_atoms, getPositionOfAtomForLinkCells( taskCode ), linkcells );
+     658      180751 :     return natomsper>1;
+     659      251586 :   } else if( matsums ) {
+     660             :     myatoms.setNumberOfAtoms( getNumberOfAtoms() );
+     661       52798 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) myatoms.setAtom( i, i );
+     662      251145 :   } 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      211329 :   } 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       31778 :     myatoms.setNumberOfAtoms( ablocks.size() );
+     671      124498 :     for(unsigned i=0; i<ablocks.size(); ++i) myatoms.setAtom( i, ablocks[i][taskCode] );
+     672             :   }
+     673             :   return true;
+     674             : }
+     675             : 
+     676        9073 : void MultiColvarBase::setupActiveTaskSet( std::vector<unsigned>& active_tasks, const std::string& input_label ) {
+     677        9073 :   if( !setup_completed ) {
+     678             :     bool justVolumes=false;
+     679        1930 :     if( usespecies ) {
+     680             :       justVolumes=true;
+     681        1437 :       for(unsigned i=0; i<getNumberOfVessels(); ++i) {
+     682        1317 :         vesselbase::StoreDataVessel* mys=dynamic_cast<vesselbase::StoreDataVessel*>( getPntrToVessel(i) );
+     683        1317 :         if( mys ) continue;
+     684         809 :         vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(i) );
+     685         809 :         if( !myb ) { justVolumes=false; break; }
+     686          38 :         ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() );
+     687          38 :         if( !myv ) { justVolumes=false; break; }
+     688             :       }
+     689             :     }
+     690        1930 :     deactivateAllTasks();
+     691        1930 :     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        1930 :     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     4886605 :       for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     717             :     }
+     718             : 
+     719             :     // Now activate all this class
+     720        1930 :     lockContributors();
+     721             :     // Setup the link cells
+     722        1930 :     setupLinkCells();
+     723             :     // Ensures that setup is not performed multiple times during one cycle
+     724        1930 :     setup_completed=true;
+     725             :   }
+     726             : 
+     727             :   // And activate the tasks in input action
+     728        9073 :   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        9073 : }
+     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        9024 : void MultiColvarBase::calculate() {
+     757             :   // Recursive function that sets up tasks
+     758        9024 :   setupActiveTaskSet( taskFlags, getLabel() );
+     759             : 
+     760             :   // Check for filters and rerun setup of link cells if there are any
+     761        9024 :   if( mybasemulticolvars.size()>0 && filtersUsedAsInput() ) setupLinkCells();
+     762             : 
+     763             :   //  Setup the link cells if we are not using species
+     764        9024 :   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        4628 :     unsigned first_active=std::numeric_limits<unsigned>::max();
+     768        4762 :     for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     769        4762 :       if( !isCurrentlyActive( ablocks[1][i] ) ) continue;
+     770             :       else {
+     771        4628 :         first_active=i; break;
+     772             :       }
+     773             :     }
+     774        4628 :     setupNonUseSpeciesLinkCells( first_active );
+     775             :   }
+     776             :   // And run all tasks
+     777        9024 :   runAllTasks();
+     778        9024 : }
+     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        2959 : void MultiColvarBase::prepare() {
+     786        2959 :   setup_completed=false; atomsWereRetrieved=false;
+     787        2959 : }
+     788             : 
+     789        6548 : void MultiColvarBase::retrieveAtoms() {
+     790        6548 :   if( !atomsWereRetrieved ) { ActionAtomistic::retrieveAtoms(); atomsWereRetrieved=true; }
+     791        6548 : }
+     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      905762 : 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      905762 :   unsigned mmc = atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     861      905762 :   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      646526 :   unsigned basen=0; for(unsigned i=0; i<mmc; ++i) basen+=(mybasemulticolvars[i]->getNumberOfDerivatives() - 9) / 3;
+     865      489261 :   mybasemulticolvars[mmc]->getCentralAtomPack( basen, atom_lab[katom].second, mybasemulticolvars[mmc]->my_tmp_capacks[1] );
+     866      489261 :   myatoms.addComDerivatives( ival, der, mybasemulticolvars[mmc]->my_tmp_capacks[1] );
+     867             : }
+     868             : 
+     869     1122658 : 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     1122658 :   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     1122658 :   if( orient.size()!=mybasemulticolvars[mmc]->getNumberOfQuantities() ) orient.resize( mybasemulticolvars[mmc]->getNumberOfQuantities() );
+     878             :   // Retrieve the value
+     879     1122658 :   mybasedata[mmc]->retrieveValueWithIndex( atom_lab[katom].second, normed, orient );
+     880     1122658 : }
+     881             : 
+     882       53063 : 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       53063 :   unsigned mmc = atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     887       53063 :   if( usespecies && !normed && iatom==0 ) return mybasedata[mmc]->getTemporyMultiValue(0);
+     888             : 
+     889       51265 :   unsigned oval=0; if( iatom>0 ) oval=1;
+     890       51265 :   MultiValue& myder=mybasedata[mmc]->getTemporyMultiValue(oval);
+     891      102491 :   if( myder.getNumberOfValues()!=mybasemulticolvars[mmc]->getNumberOfQuantities() ||
+     892       51226 :       myder.getNumberOfDerivatives()!=mybasemulticolvars[mmc]->getNumberOfDerivatives() ) {
+     893          39 :     myder.resize( mybasemulticolvars[mmc]->getNumberOfQuantities(), mybasemulticolvars[mmc]->getNumberOfDerivatives() );
+     894             :   }
+     895       51265 :   mybasedata[mmc]->retrieveDerivatives( atom_lab[katom].second, normed, myder );
+     896             :   return myder;
+     897             : }
+     898             : 
+     899    64359697 : 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    64359697 :   double weight0=1.0; if( atom_lab[katom].first>0 ) weight0=mybasedata[atom_lab[katom].first-1]->retrieveWeightWithIndex( atom_lab[katom].second );
+     902    64359697 :   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    64359697 :   if( ival<0 ) myatoms.getUnderlyingMultiValue().addTemporyValue( weight0*weighti*val );
+     905    61622797 :   else myatoms.addValue( ival, weight0*weighti*val );
+     906             : 
+     907             :   // Return if we don't need derivatives
+     908    64359697 :   if( doNotCalculateDerivatives() ) return ;
+     909             :   // And virial
+     910    57992318 :   if( ival<0 ) myatoms.addTemporyBoxDerivatives( weight0*weighti*vir );
+     911    55734171 :   else myatoms.addBoxDerivatives( ival, weight0*weighti*vir );
+     912             : 
+     913             :   // Add derivatives of central atom
+     914    57992318 :   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    57991524 :     if( ival<0 ) myatoms.addTemporyAtomsDerivatives( 0, -der );
+     920    55733377 :     else myatoms.addAtomsDerivatives( ival, 0, -der );
+     921             :   }
+     922             :   // Add derivatives of atom in coordination sphere
+     923    57992318 :   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    57991524 :     if( ival<0 ) myatoms.addTemporyAtomsDerivatives( iatom, der );
+     929    55733377 :     else myatoms.addAtomsDerivatives( ival, iatom, der );
+     930             :   }
+     931             : }
+     932             : 
+     933     1428471 : void MultiColvarBase::addAtomDerivatives( const int& ival, const unsigned& iatom, const Vector& der, multicolvar::AtomValuePack& myatoms ) const {
+     934     1428471 :   if( doNotCalculateDerivatives() ) return ;
+     935             :   unsigned jatom=myatoms.getIndex(iatom);
+     936             : 
+     937     1180895 :   if( atom_lab[jatom].first>0 ) {
+     938      904174 :     addComDerivatives( ival, iatom, der, myatoms );
+     939             :   } else {
+     940      276721 :     if( ival<0 ) myatoms.addTemporyAtomsDerivatives( iatom, der );
+     941      276721 :     else myatoms.addAtomsDerivatives( ival, iatom, der );
+     942             :   }
+     943             : }
+     944             : 
+     945      242764 : double MultiColvarBase::calculateWeight( const unsigned& current, const double& weight, AtomValuePack& myvals ) const {
+     946      242764 :   return 1.0;
+     947             : }
+     948             : 
+     949      447878 : void MultiColvarBase::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     950      447878 :   AtomValuePack myatoms( myvals, this );
+     951             :   // Retrieve the atom list
+     952      447878 :   if( !setupCurrentAtomList( current, myatoms ) ) return;
+     953             :   // Get weight due to dynamic groups
+     954      447758 :   double weight = 1.0;
+     955      447758 :   if( !matsums ) {
+     956   386210280 :     for(unsigned i=0; i<myatoms.getNumberOfAtoms(); ++i) {
+     957   385940036 :       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      177514 :   } else if( usespecies ) {
+     964      177073 :     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      447758 :   double multweight = calculateWeight( current, weight, myatoms );
+     970      447758 :   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      326222 :   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      326222 :   if( !doNotCalculateDerivatives() ) {
+     998      206915 :     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      326222 :   double vv=compute( task_index, myatoms ); updateActiveAtoms( myatoms );
+    1012             :   myatoms.setValue( 1, vv );
+    1013      326222 :   return;
+    1014             : }
+    1015             : 
+    1016      658140 : void MultiColvarBase::updateActiveAtoms( AtomValuePack& myatoms ) const {
+    1017      658140 :   if( mybasemulticolvars.size()==0 ) myatoms.updateUsingIndices();
+    1018      141871 :   else myatoms.updateDynamicList();
+    1019      658140 : }
+    1020             : 
+    1021     2753935 : Vector MultiColvarBase::getCentralAtomPos( const unsigned& taskIndex ) {
+    1022     2753935 :   unsigned curr=getTaskCode( taskIndex );
+    1023             : 
+    1024     2753935 :   if( usespecies || isDensity() ) {
+    1025     1459946 :     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      605410 : void MultiColvarBase::getCentralAtomPack( const unsigned& basn, const unsigned& taskIndex, CatomPack& mypack ) {
+    1044      605410 :   unsigned curr=getTaskCode( taskIndex );
+    1045             : 
+    1046      605410 :   if(usespecies) {
+    1047      464996 :     if( mypack.getNumberOfAtomsWithDerivatives()!=1 ) mypack.resize(1);
+    1048      464996 :     mypack.setIndex( 0, basn + curr );
+    1049      464996 :     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      605410 : }
+    1073             : 
+    1074   121150993 : Vector MultiColvarBase::getSeparation( const Vector& vec1, const Vector& vec2 ) const {
+    1075   121150993 :   if(usepbc) { return pbcDistance( vec1, vec2 ); }
+    1076           0 :   else { return delta( vec1, vec2 ); }
+    1077             : }
+    1078             : 
+    1079      220567 : void MultiColvarBase::applyPbc(std::vector<Vector>& dlist, unsigned int max_index) const {
+    1080      220567 :   if (usepbc) pbcApply(dlist, max_index);
+    1081      220567 : }
+    1082             : 
+    1083        1994 : void MultiColvarBase::apply() {
+    1084        1994 :   if( getForcesFromVessels( forcesToApply ) ) setForcesOnAtoms( forcesToApply );
+    1085        1994 : }
+    1086             : 
+    1087             : }
+    1088             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..10cd9a6da1 --- /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-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBase22doNotCalculateDirectorEv0
_ZNK4PLMD11multicolvar15MultiColvarBase28hasDifferentiableOrientationEv0
_ZNK4PLMD11multicolvar15MultiColvarBase29getAbsoluteIndexOfCentralAtomERKj156
_ZN4PLMD11multicolvar15MultiColvarBaseD2Ev350
_ZNK4PLMD11multicolvar15MultiColvarBase10threadSafeEv4461
_ZN4PLMD11multicolvar15MultiColvarBase17isCurrentlyActiveERKj917133
_ZNK4PLMD11multicolvar15MultiColvarBase9isDensityEv1814585
_ZN4PLMD11multicolvar15MultiColvarBase22getNumberOfDerivativesEv8911885
_ZNK4PLMD11multicolvar15MultiColvarBase25doNotCalculateDerivativesEv69055090
_ZNK4PLMD11multicolvar15MultiColvarBase29getPositionOfAtomForLinkCellsERKj408128313
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.h.func.html b/coverage/multicolvar/MultiColvarBase.h.func.html new file mode 100644 index 0000000000..93cebf23c0 --- /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-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBase17isCurrentlyActiveERKj917133
_ZN4PLMD11multicolvar15MultiColvarBase22doNotCalculateDirectorEv0
_ZN4PLMD11multicolvar15MultiColvarBase22getNumberOfDerivativesEv8911885
_ZN4PLMD11multicolvar15MultiColvarBaseD2Ev350
_ZNK4PLMD11multicolvar15MultiColvarBase10threadSafeEv4461
_ZNK4PLMD11multicolvar15MultiColvarBase25doNotCalculateDerivativesEv69055090
_ZNK4PLMD11multicolvar15MultiColvarBase28hasDifferentiableOrientationEv0
_ZNK4PLMD11multicolvar15MultiColvarBase29getAbsoluteIndexOfCentralAtomERKj156
_ZNK4PLMD11multicolvar15MultiColvarBase29getPositionOfAtomForLinkCellsERKj408128313
_ZNK4PLMD11multicolvar15MultiColvarBase9isDensityEv1814585
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.h.gcov.html b/coverage/multicolvar/MultiColvarBase.h.gcov.html new file mode 100644 index 0000000000..f553601047 --- /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-06-10 08:19:14Functions: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        1400 :   ~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        4461 :   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     1814585 :   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      917133 : bool MultiColvarBase::isCurrentlyActive( const unsigned& code ) {
+     216      917133 :   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   408128313 : Vector MultiColvarBase::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+     236             :   plumed_dbg_assert( iatom<atom_lab.size() );
+     237   408128313 :   if( atom_lab[iatom].first>0  ) {
+     238     2487982 :     unsigned mmc=atom_lab[iatom].first - 1;
+     239     2487982 :     return mybasemulticolvars[mmc]->getCentralAtomPos( atom_lab[iatom].second );
+     240             :   }
+     241   405640331 :   return ActionAtomistic::getPosition( atom_lab[iatom].second );
+     242             : }
+     243             : 
+     244             : inline
+     245     8911885 : unsigned MultiColvarBase::getNumberOfDerivatives() {
+     246     8911885 :   return 3*getNumberOfAtoms()+9;
+     247             : }
+     248             : 
+     249             : inline
+     250             : bool MultiColvarBase::usesPbc() const {
+     251      220567 :   return usepbc;
+     252             : }
+     253             : 
+     254             : inline
+     255    69055090 : bool MultiColvarBase::doNotCalculateDerivatives() const {
+     256    69055090 :   if( !dertime ) return true;
+     257    68367370 :   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.15
+
+ + + 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 0000000000..0317a4da88 --- /dev/null +++ b/coverage/multicolvar/MultiColvarCombine.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3131100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18MultiColvarCombineC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe536createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarCombine10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarCombineC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarCombine16registerKeywordsERNS_8KeywordsE2
_ZNK4PLMD11multicolvar18MultiColvarCombine7computeERKjRNS0_13AtomValuePackE15
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe53C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe53D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarCombine.cpp.func.html b/coverage/multicolvar/MultiColvarCombine.cpp.func.html new file mode 100644 index 0000000000..2a30c4f274 --- /dev/null +++ b/coverage/multicolvar/MultiColvarCombine.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3131100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe536createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe53C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe53D2Ev3473
_ZN4PLMD11multicolvar18MultiColvarCombine10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarCombine16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar18MultiColvarCombineC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarCombineC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar18MultiColvarCombine7computeERKjRNS0_13AtomValuePackE15
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarCombine.cpp.gcov.html b/coverage/multicolvar/MultiColvarCombine.cpp.gcov.html new file mode 100644 index 0000000000..39f7bce9bc --- /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:3131100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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       10421 : PLUMED_REGISTER_ACTION(MultiColvarCombine,"MCOLV_COMBINE")
+      54             : 
+      55           2 : void MultiColvarCombine::registerKeywords( Keywords& keys ) {
+      56           2 :   MultiColvarBase::registerKeywords( keys );
+      57           4 :   keys.add("compulsory","DATA","the multicolvars you are calculating linear combinations for");
+      58           4 :   keys.add("compulsory","COEFFICIENTS","1.0","the coefficients to use for the various multicolvars");
+      59          10 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("SUM"); keys.use("LESS_THAN"); keys.use("HISTOGRAM");
+      60          14 :   keys.use("MIN"); keys.use("MAX"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("ALT_MIN"); keys.use("BETWEEN"); keys.use("MOMENTS");
+      61           2 : }
+      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.15
+
+ + + 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 0000000000..8cc6952082 --- /dev/null +++ b/coverage/multicolvar/MultiColvarDensity.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:11613983.5 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18MultiColvarDensity10isPeriodicEv0
_ZN4PLMD11multicolvar18MultiColvarDensityC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe1076createERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar18MultiColvarDensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar18MultiColvarDensity16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD11multicolvar18MultiColvarDensity12clearAverageEv18
_ZN4PLMD11multicolvar18MultiColvarDensity19prepareForAveragingEv26
_ZN4PLMD11multicolvar18MultiColvarDensity5applyEv34
_ZNK4PLMD11multicolvar18MultiColvarDensity21getNumberOfQuantitiesEv62
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe107C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe107D2Ev3473
_ZNK4PLMD11multicolvar18MultiColvarDensity7computeERKjRNS_10MultiValueE21152
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarDensity.cpp.func.html b/coverage/multicolvar/MultiColvarDensity.cpp.func.html new file mode 100644 index 0000000000..6011143073 --- /dev/null +++ b/coverage/multicolvar/MultiColvarDensity.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:11613983.5 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe1076createERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe107C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe107D2Ev3473
_ZN4PLMD11multicolvar18MultiColvarDensity10isPeriodicEv0
_ZN4PLMD11multicolvar18MultiColvarDensity12clearAverageEv18
_ZN4PLMD11multicolvar18MultiColvarDensity16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD11multicolvar18MultiColvarDensity19prepareForAveragingEv26
_ZN4PLMD11multicolvar18MultiColvarDensity5applyEv34
_ZN4PLMD11multicolvar18MultiColvarDensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar18MultiColvarDensityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar18MultiColvarDensity21getNumberOfQuantitiesEv62
_ZNK4PLMD11multicolvar18MultiColvarDensity7computeERKjRNS_10MultiValueE21152
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarDensity.cpp.gcov.html b/coverage/multicolvar/MultiColvarDensity.cpp.gcov.html new file mode 100644 index 0000000000..5cb4e1424e --- /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:11613983.5 %
Date:2024-06-10 08:19:14Functions: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 "tools/Pbc.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/Atoms.h"
+      26             : #include "tools/Units.h"
+      27             : #include <cstdio>
+      28             : #include "core/ActionSet.h"
+      29             : #include "MultiColvarBase.h"
+      30             : #include "gridtools/ActionWithGrid.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace multicolvar {
+      34             : 
+      35             : //+PLUMEDOC GRIDCALC MULTICOLVARDENS
+      36             : /*
+      37             : Evaluate the average value of a multicolvar on a grid.
+      38             : 
+      39             : This keyword allows one to construct a phase field representation for a symmetry function from
+      40             : an atomistic description.  If each atom has an associated order parameter, \f$\phi_i\f$ then a
+      41             : smooth phase field function \f$\phi(r)\f$ can be computed using:
+      42             : 
+      43             : \f[
+      44             : \phi(\mathbf{r}) = \frac{\sum_i K(\mathbf{r}-\mathbf{r}_i) \phi_i }{ \sum_i K(\mathbf{r} - \mathbf{r}_i )}
+      45             : \f]
+      46             : 
+      47             : where \f$\mathbf{r}_i\f$ is the position of atom \f$i\f$, the sums run over all the atoms input
+      48             : and \f$K(\mathbf{r} - \mathbf{r}_i)\f$ is one of the \ref kernelfunctions implemented in plumed.
+      49             : This action calculates the above function on a grid, which can then be used in the input to further
+      50             : actions.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The following example shows perhaps the simplest way in which this action can be used.  The following
+      55             : input computes the density of atoms at each point on the grid and outputs this quantity to a file.  In
+      56             : other words this input instructs plumed to calculate \f$\rho(\mathbf{r}) = \sum_i K(\mathbf{r} - \mathbf{r}_i )\f$
+      57             : 
+      58             : \plumedfile
+      59             : dens: DENSITY SPECIES=1-100
+      60             : grid: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=xyz NBINS=100,100,100 BANDWIDTH=0.05,0.05,0.05 STRIDE=1
+      61             : DUMPGRID GRID=grid STRIDE=500 FILE=density
+      62             : \endplumedfile
+      63             : 
+      64             : In the above example density is added to the grid on every step.  The PRINT_GRID instruction thus tells PLUMED to
+      65             : output the average density at each point on the grid every 500 steps of simulation.  Notice that the that grid output
+      66             : on step 1000 is an average over all 1000 frames of the trajectory.  If you would like to analyze these two blocks
+      67             : of data separately you must use the CLEAR flag.
+      68             : 
+      69             : This second example computes an order parameter (in this case \ref FCCUBIC) and constructs a phase field model
+      70             : for this order parameter using the equation above.
+      71             : 
+      72             : \plumedfile
+      73             : fcc: FCCUBIC SPECIES=1-5184 SWITCH={CUBIC D_0=1.2 D_MAX=1.5} ALPHA=27
+      74             : dens: MULTICOLVARDENS DATA=fcc ORIGIN=1 DIR=xyz NBINS=14,14,28 BANDWIDTH=1.0,1.0,1.0 STRIDE=1 CLEAR=1
+      75             : DUMPCUBE GRID=dens STRIDE=1 FILE=dens.cube
+      76             : \endplumedfile
+      77             : 
+      78             : In this example the phase field model is computed and output to a file on every step of the simulation.  Furthermore,
+      79             : because the CLEAR=1 keyword is set on the MULTICOLVARDENS line each Gaussian cube file output is a phase field
+      80             : model for a particular trajectory frame. The average value accumulated thus far is cleared at the start of every single
+      81             : timestep and there is no averaging over trajectory frames in this case.
+      82             : 
+      83             : */
+      84             : //+ENDPLUMEDOC
+      85             : 
+      86             : class MultiColvarDensity : public gridtools::ActionWithGrid {
+      87             :   bool fractional;
+      88             :   MultiColvarBase* mycolv;
+      89             :   std::vector<unsigned> nbins;
+      90             :   std::vector<double> gspacing;
+      91             :   std::vector<bool> confined;
+      92             :   std::vector<double> cmin, cmax;
+      93             :   vesselbase::StoreDataVessel* stash;
+      94             :   Vector origin;
+      95             :   std::vector<unsigned> directions;
+      96             : public:
+      97             :   explicit MultiColvarDensity(const ActionOptions&);
+      98             :   static void registerKeywords( Keywords& keys );
+      99             :   unsigned getNumberOfQuantities() const override;
+     100           0 :   bool isPeriodic() override { return false; }
+     101             :   void clearAverage() override;
+     102             :   void prepareForAveraging() override;
+     103             :   void compute( const unsigned&, MultiValue& ) const override;
+     104          34 :   void apply() override {}
+     105             : };
+     106             : 
+     107       10441 : PLUMED_REGISTER_ACTION(MultiColvarDensity,"MULTICOLVARDENS")
+     108             : 
+     109          12 : void MultiColvarDensity::registerKeywords( Keywords& keys ) {
+     110          12 :   gridtools::ActionWithGrid::registerKeywords( keys );
+     111          24 :   keys.add("atoms","ORIGIN","we will use the position of this atom as the origin");
+     112          24 :   keys.add("compulsory","DATA","the multicolvar which you would like to calculate the density profile for");
+     113          24 :   keys.add("compulsory","DIR","the direction in which to calculate the density profile");
+     114          24 :   keys.add("optional","NBINS","the number of bins to use to represent the density profile");
+     115          24 :   keys.add("optional","SPACING","the approximate grid spacing (to be used as an alternative or together with NBINS)");
+     116          24 :   keys.addFlag("FRACTIONAL",false,"use fractional coordinates for the various axes");
+     117          24 :   keys.addFlag("XREDUCED",false,"limit the calculation of the density/average to a portion of the z-axis only");
+     118          24 :   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 "
+     119             :            "which you are calculating the density/average");
+     120          24 :   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 "
+     121             :            "which you are calculating the density/average");
+     122          24 :   keys.addFlag("YREDUCED",false,"limit the calculation of the density/average to a portion of the y-axis only");
+     123          24 :   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 "
+     124             :            "which you are calculating the density/average");
+     125          24 :   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 "
+     126             :            "which you are calculating the density/average");
+     127          24 :   keys.addFlag("ZREDUCED",false,"limit the calculation of the density/average to a portion of the z-axis only");
+     128          24 :   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 "
+     129             :            "which you are calculating the density/average");
+     130          24 :   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 "
+     131             :            "which you are calculating the density/average");
+     132          12 : }
+     133             : 
+     134          11 : MultiColvarDensity::MultiColvarDensity(const ActionOptions&ao):
+     135             :   Action(ao),
+     136          11 :   ActionWithGrid(ao)
+     137             : {
+     138             :   std::vector<AtomNumber> atom;
+     139          22 :   parseAtomList("ORIGIN",atom);
+     140          11 :   if( atom.size()!=1 ) error("should only be one atom specified");
+     141          11 :   log.printf("  origin is at position of atom : %d\n",atom[0].serial() );
+     142             : 
+     143          11 :   std::string mlab; parse("DATA",mlab);
+     144          11 :   mycolv = plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlab);
+     145          11 :   if(!mycolv) error("action labelled " +  mlab + " does not exist or is not a MultiColvar");
+     146          11 :   stash = mycolv->buildDataStashes( NULL );
+     147             : 
+     148          22 :   parseFlag("FRACTIONAL",fractional);
+     149          11 :   std::string direction; parse("DIR",direction);
+     150          11 :   log.printf("  calculating for %s density profile along ", mycolv->getLabel().c_str() );
+     151          11 :   if( direction=="x" ) {
+     152           8 :     log.printf("x axis");
+     153           8 :     directions.resize(1); directions[0]=0;
+     154           3 :   } else if( direction=="y" ) {
+     155           0 :     log.printf("y axis");
+     156           0 :     directions.resize(1); directions[0]=1;
+     157           3 :   } else if( direction=="z" ) {
+     158           0 :     log.printf("z axis");
+     159           0 :     directions.resize(1); directions[0]=2;
+     160           3 :   } else if( direction=="xy" ) {
+     161           0 :     log.printf("x and y axes");
+     162           0 :     directions.resize(2); directions[0]=0; directions[1]=1;
+     163           3 :   } else if( direction=="xz" ) {
+     164           0 :     log.printf("x and z axes");
+     165           0 :     directions.resize(2); directions[0]=0; directions[1]=2;
+     166           3 :   } else if( direction=="yz" ) {
+     167           0 :     log.printf("y and z axis");
+     168           0 :     directions.resize(2); directions[0]=1; directions[1]=2;
+     169           3 :   } else if( direction=="xyz" ) {
+     170           3 :     log.printf("x, y and z axes");
+     171           3 :     directions.resize(3); directions[0]=0; directions[1]=1; directions[2]=2;
+     172             :   } else {
+     173           0 :     error( direction + " is not valid gradient direction");
+     174             :   }
+     175          11 :   log.printf(" for colvars calculated by action %s \n",mycolv->getLabel().c_str() );
+     176          33 :   parseVector("NBINS",nbins); parseVector("SPACING",gspacing);
+     177          11 :   if( nbins.size()!=directions.size() && gspacing.size()!=directions.size() ) error("NBINS or SPACING must be set");
+     178             : 
+     179          11 :   confined.resize( directions.size() ); cmin.resize( directions.size(), 0 ); cmax.resize( directions.size(), 0 );
+     180          28 :   for(unsigned i=0; i<directions.size(); ++i) {
+     181          17 :     if( directions[i]==0 ) {
+     182          22 :       bool tflag; parseFlag("XREDUCED",tflag); confined[i]=tflag;
+     183          11 :       if( confined[i] ) {
+     184           0 :         cmin[i]=cmax[i]=0.0; parse("XLOWER",cmin[i]); parse("XUPPER",cmax[i]);
+     185           0 :         if( fractional ) error("XREDUCED is incompatible with FRACTIONAL");
+     186           0 :         if( std::abs(cmin[i]-cmax[i])<epsilon ) error("range set for x axis makes no sense");
+     187           0 :         log.printf("  confining calculation in x direction to between %f and %f \n",cmin[i],cmax[i]);
+     188             :       }
+     189           6 :     } else if( directions[i]==1 ) {
+     190           6 :       bool tflag; parseFlag("YREDUCED",tflag); confined[i]=tflag;
+     191           3 :       if( confined[i] ) {
+     192           0 :         cmin[i]=cmax[i]=0.0; parse("YLOWER",cmin[i]); parse("YUPPER",cmax[i]);
+     193           0 :         if( fractional ) error("YREDUCED is incompatible with FRACTIONAL");
+     194           0 :         if( std::abs(cmin[i]-cmax[i])<epsilon ) error("range set for y axis makes no sense");
+     195           0 :         log.printf("  confining calculation in y direction to between %f and %f \n",cmin[i],cmax[i]);
+     196             :       }
+     197           3 :     } else if( directions[i]==2 ) {
+     198           6 :       bool tflag; parseFlag("ZREDUCED",tflag); confined[i]=tflag;
+     199           3 :       if( confined[i] ) {
+     200           2 :         cmin[i]=cmax[i]=0.0; parse("ZLOWER",cmin[i]); parse("ZUPPER",cmax[i]);
+     201           1 :         if( fractional ) error("ZREDUCED is incompatible with FRACTIONAL");
+     202           1 :         if( std::abs(cmin[i]-cmax[i])<epsilon ) error("range set for z axis search makes no sense");
+     203           1 :         log.printf("  confining calculation in z direction to between %f and %f \n",cmin[i],cmax[i]);
+     204             :       }
+     205             :     }
+     206             :   }
+     207             : 
+     208             :   std::string vstring;
+     209          11 :   if( confined[0] ) vstring +="PBC=F";
+     210             :   else vstring += " PBC=T";
+     211          17 :   for(unsigned i=1; i<directions.size(); ++i) {
+     212           6 :     if( confined[i] ) vstring += ",F";
+     213             :     else vstring += ",T";
+     214             :   }
+     215          22 :   vstring +=" COMPONENTS=" + mycolv->getLabel() + ".dens";
+     216             :   vstring +=" COORDINATES=";
+     217          11 :   if( directions[0]==0 ) vstring+="x";
+     218           0 :   else if( directions[0]==1 ) vstring+="y";
+     219           0 :   else if( directions[0]==2 ) vstring+="z";
+     220          17 :   for(unsigned i=1; i<directions.size(); ++i) {
+     221           6 :     if( directions[i]==0 ) vstring+=",x";
+     222           6 :     else if( directions[i]==1 ) vstring+=",y";
+     223           3 :     else if( directions[i]==2 ) vstring+=",z";
+     224             :   }
+     225             :   // Create a task list
+     226       10899 :   for(unsigned i=0; i<mycolv->getFullNumberOfTasks(); ++i) addTaskToList(i);
+     227             :   // And create the grid
+     228          11 :   std::unique_ptr<gridtools::GridVessel> grid;
+     229          14 :   if( mycolv->isDensity() ) grid=createGrid( "histogram", vstring );
+     230          16 :   else grid=createGrid( "average", vstring );
+     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( plumed.getAtoms().usingNaturalUnits() ) mygrid->setCubeUnits( 1.0/0.5292 );
+     238           1 :     else mygrid->setCubeUnits( plumed.getAtoms().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.15
+
+ + + 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 0000000000..e18499ff3a --- /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-06-10 08:19:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar17MultiColvarFilter15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar17MultiColvarFilterC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar17MultiColvarFilterC2ERKNS_13ActionOptionsE14
_ZN4PLMD11multicolvar17MultiColvarFilter16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD11multicolvar17MultiColvarFilter28doJobsRequiredBeforeTaskListEv46
_ZNK4PLMD11multicolvar17MultiColvarFilter12completeTaskERKjRNS_10MultiValueES5_20027
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.cpp.func.html b/coverage/multicolvar/MultiColvarFilter.cpp.func.html new file mode 100644 index 0000000000..d3265157d4 --- /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-06-10 08:19:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar17MultiColvarFilter15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar17MultiColvarFilter16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD11multicolvar17MultiColvarFilter28doJobsRequiredBeforeTaskListEv46
_ZN4PLMD11multicolvar17MultiColvarFilterC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar17MultiColvarFilterC2ERKNS_13ActionOptionsE14
_ZNK4PLMD11multicolvar17MultiColvarFilter12completeTaskERKjRNS_10MultiValueES5_20027
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.cpp.gcov.html b/coverage/multicolvar/MultiColvarFilter.cpp.gcov.html new file mode 100644 index 0000000000..a1d23a84b1 --- /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-06-10 08:19:14Functions: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          20 : void MultiColvarFilter::registerKeywords( Keywords& keys ) {
+      28          20 :   BridgedMultiColvarFunction::registerKeywords( keys );
+      29          60 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+      30          80 :   keys.use("MEAN"); keys.use("MOMENTS"); keys.use("MIN"); keys.use("MAX");
+      31          60 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      32          20 : }
+      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.15
+
+ + + 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 0000000000..070fdc2d26 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar17MultiColvarFilter21getNumberOfQuantitiesEv28192
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.h.func.html b/coverage/multicolvar/MultiColvarFilter.h.func.html new file mode 100644 index 0000000000..2e1a754389 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar17MultiColvarFilter21getNumberOfQuantitiesEv28192
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.h.gcov.html b/coverage/multicolvar/MultiColvarFilter.h.gcov.html new file mode 100644 index 0000000000..e62728d923 --- /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-06-10 08:19:14Functions: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       28192 : unsigned MultiColvarFilter::getNumberOfQuantities() const {
+      58       28192 :   return getPntrToMultiColvar()->getNumberOfQuantities();
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+      63             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..2ea680c9d3 --- /dev/null +++ b/coverage/multicolvar/MultiColvarProduct.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18MultiColvarProductC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe526createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarProduct10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarProductC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarProduct16registerKeywordsERNS_8KeywordsE2
_ZNK4PLMD11multicolvar18MultiColvarProduct7computeERKjRNS0_13AtomValuePackE15
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe52C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe52D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarProduct.cpp.func.html b/coverage/multicolvar/MultiColvarProduct.cpp.func.html new file mode 100644 index 0000000000..0eb55c28e2 --- /dev/null +++ b/coverage/multicolvar/MultiColvarProduct.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe526createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe52C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe52D2Ev3473
_ZN4PLMD11multicolvar18MultiColvarProduct10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarProduct16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar18MultiColvarProductC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarProductC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar18MultiColvarProduct7computeERKjRNS0_13AtomValuePackE15
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/MultiColvarProduct.cpp.gcov.html b/coverage/multicolvar/MultiColvarProduct.cpp.gcov.html new file mode 100644 index 0000000000..58fdf14437 --- /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:2626100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ + + + + + + + +

+
          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       10421 : PLUMED_REGISTER_ACTION(MultiColvarProduct,"MCOLV_PRODUCT")
+      53             : 
+      54           2 : void MultiColvarProduct::registerKeywords( Keywords& keys ) {
+      55           2 :   MultiColvarBase::registerKeywords( keys );
+      56           4 :   keys.add("compulsory","DATA","the multicolvars you are calculating the product of");
+      57          10 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("SUM"); keys.use("LESS_THAN"); keys.use("HISTOGRAM");
+      58          14 :   keys.use("MIN"); keys.use("MAX"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("ALT_MIN"); keys.use("BETWEEN"); keys.use("MOMENTS");
+      59           2 : }
+      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.15
+
+ + + 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 0000000000..b722ad8186 --- /dev/null +++ b/coverage/multicolvar/NumberOfLinks.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:515789.5 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13NumberOfLinks10isPeriodicEv0
_ZN4PLMD11multicolvar13NumberOfLinksC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe866createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar13NumberOfLinksC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar13NumberOfLinks16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe86C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe86D2Ev3473
_ZNK4PLMD11multicolvar13NumberOfLinks15calculateWeightERKjRKdRNS0_13AtomValuePackE8064
_ZNK4PLMD11multicolvar13NumberOfLinks7computeERKjRNS0_13AtomValuePackE8064
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/NumberOfLinks.cpp.func.html b/coverage/multicolvar/NumberOfLinks.cpp.func.html new file mode 100644 index 0000000000..7b20d4a94e --- /dev/null +++ b/coverage/multicolvar/NumberOfLinks.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:515789.5 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe866createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe86C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe86D2Ev3473
_ZN4PLMD11multicolvar13NumberOfLinks10isPeriodicEv0
_ZN4PLMD11multicolvar13NumberOfLinks16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar13NumberOfLinksC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar13NumberOfLinksC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar13NumberOfLinks15calculateWeightERKjRKdRNS0_13AtomValuePackE8064
_ZNK4PLMD11multicolvar13NumberOfLinks7computeERKjRNS0_13AtomValuePackE8064
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/NumberOfLinks.cpp.gcov.html b/coverage/multicolvar/NumberOfLinks.cpp.gcov.html new file mode 100644 index 0000000000..2755b93a53 --- /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:515789.5 %
Date:2024-06-10 08:19:14Functions: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             : #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       10427 : PLUMED_REGISTER_ACTION(NumberOfLinks,"NLINKS")
+      87             : 
+      88           5 : void NumberOfLinks::registerKeywords( Keywords& keys ) {
+      89           5 :   MultiColvarBase::registerKeywords( keys );
+      90          10 :   keys.add("atoms","GROUP","");
+      91          10 :   keys.add("atoms-1","GROUPA","");
+      92          10 :   keys.add("atoms-1","GROUPB","");
+      93          10 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      94          10 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      95          10 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      96          10 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      97          10 :   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           5 :   keys.remove("LOWMEM");
+     102          10 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+     103           5 : }
+     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.15
+
+ + + 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 0000000000..ad9e7216c6 --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:3333100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar8TorsionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe856createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar8Torsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_2
_ZN4PLMD11multicolvar8TorsionsC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar8Torsions16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar8Torsions10isPeriodicEv5
_ZNK4PLMD11multicolvar8Torsions7computeERKjRNS0_13AtomValuePackE36
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe85C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe85D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.func.html b/coverage/multicolvar/Torsions.cpp.func.html new file mode 100644 index 0000000000..790451c8cb --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:3333100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe856createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe85C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe85D2Ev3473
_ZN4PLMD11multicolvar8Torsions10isPeriodicEv5
_ZN4PLMD11multicolvar8Torsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_2
_ZN4PLMD11multicolvar8Torsions16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar8TorsionsC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar8TorsionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar8Torsions7computeERKjRNS0_13AtomValuePackE36
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.gcov.html b/coverage/multicolvar/Torsions.cpp.gcov.html new file mode 100644 index 0000000000..4429902a31 --- /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:3333100.0 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ + + + + + + + +

+
          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       10423 : PLUMED_REGISTER_ACTION(Torsions,"TORSIONS")
+      86             : 
+      87           3 : void Torsions::registerKeywords( Keywords& keys ) {
+      88           3 :   MultiColvarBase::registerKeywords( keys );
+      89           6 :   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           6 :   keys.reset_style("ATOMS","atoms");
+      95           6 :   keys.use("BETWEEN"); keys.use("HISTOGRAM");
+      96           3 : }
+      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.15
+
+ + + 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 0000000000..8246f4e3b2 --- /dev/null +++ b/coverage/multicolvar/VolumeAround.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:4848100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12VolumeAroundC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe836createERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12VolumeAround16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD11multicolvar12VolumeAround12setupRegionsEv317
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe83C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe83D2Ev3473
_ZNK4PLMD11multicolvar12VolumeAround21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE56393
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeAround.cpp.func.html b/coverage/multicolvar/VolumeAround.cpp.func.html new file mode 100644 index 0000000000..f603b99f5b --- /dev/null +++ b/coverage/multicolvar/VolumeAround.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:4848100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeAround12setupRegionsEv317
_ZN4PLMD11multicolvar12VolumeAround16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD11multicolvar12VolumeAroundC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12VolumeAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe836createERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe83C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe83D2Ev3473
_ZNK4PLMD11multicolvar12VolumeAround21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE56393
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeAround.cpp.gcov.html b/coverage/multicolvar/VolumeAround.cpp.gcov.html new file mode 100644 index 0000000000..18b46411c3 --- /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:4848100.0 %
Date:2024-06-10 08:19:14Functions:7887.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 "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       10463 : PLUMED_REGISTER_ACTION(VolumeAround,"AROUND")
+      84             : 
+      85          23 : void VolumeAround::registerKeywords( Keywords& keys ) {
+      86          23 :   ActionVolume::registerKeywords( keys );
+      87          46 :   keys.add("atoms","ATOM","the atom whose vicinity we are interested in examining");
+      88          46 :   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          46 :   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          46 :   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          46 :   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          46 :   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          46 :   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          23 : }
+      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.15
+
+ + + 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 0000000000..7867fc1139 --- /dev/null +++ b/coverage/multicolvar/VolumeBetweenContours.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:75014.0 %
Date:2024-06-10 08:19:14Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe786createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16VolumeInEnvelope12setupRegionsEv0
_ZN4PLMD11multicolvar16VolumeInEnvelopeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16VolumeInEnvelopeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16VolumeInEnvelope21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
_ZN4PLMD11multicolvar16VolumeInEnvelope16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe78C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe78D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeBetweenContours.cpp.func.html b/coverage/multicolvar/VolumeBetweenContours.cpp.func.html new file mode 100644 index 0000000000..521622f395 --- /dev/null +++ b/coverage/multicolvar/VolumeBetweenContours.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:75014.0 %
Date:2024-06-10 08:19:14Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe786createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe78C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe78D2Ev3473
_ZN4PLMD11multicolvar16VolumeInEnvelope12setupRegionsEv0
_ZN4PLMD11multicolvar16VolumeInEnvelope16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD11multicolvar16VolumeInEnvelopeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16VolumeInEnvelopeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16VolumeInEnvelope21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html b/coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html new file mode 100644 index 0000000000..f9378ca722 --- /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:75014.0 %
Date:2024-06-10 08:19:14Functions:3837.5 %
+
+ + + + + + + + +

+
          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       10419 : PLUMED_REGISTER_ACTION(VolumeInEnvelope,"INENVELOPE")
+      79             : 
+      80           1 : void VolumeInEnvelope::registerKeywords( Keywords& keys ) {
+      81           1 :   ActionVolume::registerKeywords( keys ); keys.remove("SIGMA");
+      82           2 :   keys.add("atoms","ATOMS","the atom whose positions we are constructing a field from");
+      83           2 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density estimation");
+      84           2 :   keys.add("compulsory","CONTOUR","a switching function that tells PLUMED how large the density should be");
+      85           1 : }
+      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.15
+
+ + + 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 0000000000..5f2a544f5b --- /dev/null +++ b/coverage/multicolvar/VolumeCavity.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:17021479.4 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeCavityC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12VolumeCavityD2Ev0
_ZN4PLMD11multicolvar12VolumeCavityC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12VolumeCavityD0Ev2
_ZN4PLMD11multicolvar12VolumeCavityD1Ev2
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe1276createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12VolumeCavity16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar12VolumeCavity6updateEv120
_ZN4PLMD11multicolvar12VolumeCavity12setupRegionsEv1620
_ZNK4PLMD11multicolvar12VolumeCavity21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1620
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe127C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe127D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeCavity.cpp.func.html b/coverage/multicolvar/VolumeCavity.cpp.func.html new file mode 100644 index 0000000000..3632cdfaac --- /dev/null +++ b/coverage/multicolvar/VolumeCavity.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:17021479.4 %
Date:2024-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeCavity12setupRegionsEv1620
_ZN4PLMD11multicolvar12VolumeCavity16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar12VolumeCavity6updateEv120
_ZN4PLMD11multicolvar12VolumeCavityC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12VolumeCavityC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12VolumeCavityD0Ev2
_ZN4PLMD11multicolvar12VolumeCavityD1Ev2
_ZN4PLMD11multicolvar12VolumeCavityD2Ev0
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe1276createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe127C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe127D2Ev3473
_ZNK4PLMD11multicolvar12VolumeCavity21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1620
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeCavity.cpp.gcov.html b/coverage/multicolvar/VolumeCavity.cpp.gcov.html new file mode 100644 index 0000000000..df056ec1bb --- /dev/null +++ b/coverage/multicolvar/VolumeCavity.cpp.gcov.html @@ -0,0 +1,489 @@ + + + + + + + + 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:17021479.4 %
Date:2024-06-10 08:19:14Functions: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 "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/Atoms.h"
+      25             : #include "tools/Units.h"
+      26             : #include "tools/Pbc.h"
+      27             : #include "ActionVolume.h"
+      28             : 
+      29             : //+PLUMEDOC VOLUMES CAVITY
+      30             : /*
+      31             : 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.
+      32             : 
+      33             : Each of the base quantities calculated by a multicolvar can can be assigned to a particular point in three
+      34             : dimensional space. For example, if we have the coordination numbers for all the atoms in the
+      35             : system each coordination number can be assumed to lie on the position of the central atom.
+      36             : Because each base quantity can be assigned to a particular point in space we can calculate functions of the
+      37             : distribution of base quantities in a particular part of the box by using:
+      38             : 
+      39             : \f[
+      40             : \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) }
+      41             : \f]
+      42             : 
+      43             : 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$.
+      44             : 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.
+      45             : 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$
+      46             : position to a position in \f$ (u_i,v_i,z_i)\f$.  This is done using a rotation matrix as follows:
+      47             : 
+      48             : \f[
+      49             : \left(
+      50             : \begin{matrix}
+      51             :  u_i \\
+      52             :  v_i \\
+      53             :  w_i
+      54             : \end{matrix}
+      55             : \right) = \mathbf{R}
+      56             : \left(
+      57             : \begin{matrix}
+      58             :  x_i - x_o \\
+      59             :  y_i - y_o \\
+      60             :  z_i - z_o
+      61             : \end{matrix}
+      62             : \right)
+      63             : \f]
+      64             : 
+      65             : where \f$\mathbf{R}\f$ is a rotation matrix that is calculated by constructing a set of three orthonormal vectors from the
+      66             : reference positions specified by the user. The first of these unit vectors points from the first reference atom to the second.
+      67             : 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
+      68             : these first two vectors.  \f$(x_o,y_o,z_o)\f$, meanwhile, specifies the position of the first reference atom.
+      69             : 
+      70             : 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
+      71             : is equal to:
+      72             : 
+      73             : \f[
+      74             : 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
+      75             :    K\left( \frac{u - u_i}{\sigma} \right)K\left( \frac{v - v_i}{\sigma} \right)K\left( \frac{w - w_i}{\sigma} \right)
+      76             : \f]
+      77             : 
+      78             : where \f$K\f$ is one of the kernel functions described on \ref histogrambead and \f$\sigma\f$ is a bandwidth parameter.
+      79             : 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$
+      80             : directions.  Essentially the vector connecting atom 1 to atom 4 is projected onto the three unit vectors
+      81             : described above and the resulting projections determine the \f$u'\f$, \f$v'\f$ and \f$w'\f$ parameters in the above expression.
+      82             : 
+      83             : \par Examples
+      84             : 
+      85             : The following commands tell plumed to calculate the number of atoms in an ion channel in a protein.
+      86             : The extent of the channel is calculated from the positions of atoms 1, 4, 5 and 11. The final value will be labeled cav.
+      87             : 
+      88             : \plumedfile
+      89             : d1: DENSITY SPECIES=20-500
+      90             : CAVITY DATA=d1 ATOMS=1,4,5,11 SIGMA=0.1 LABEL=cav
+      91             : \endplumedfile
+      92             : 
+      93             : The following command tells plumed to calculate the coordination numbers (with other water molecules) for the water
+      94             : molecules in the protein channel described above.  The average coordination number and the number of coordination
+      95             : numbers more than 4 is then calculated.  The values of these two quantities are given the labels cav.mean and cav.morethan
+      96             : 
+      97             : \plumedfile
+      98             : d1: COORDINATIONNUMBER SPECIES=20-500 R_0=0.1
+      99             : CAVITY DATA=d1 ATOMS=1,4,5,11 SIGMA=0.1 MEAN MORE_THAN={RATIONAL R_0=4} LABEL=cav
+     100             : \endplumedfile
+     101             : 
+     102             : */
+     103             : //+ENDPLUMEDOC
+     104             : 
+     105             : namespace PLMD {
+     106             : namespace multicolvar {
+     107             : 
+     108             : class VolumeCavity : public ActionVolume {
+     109             : private:
+     110             :   bool boxout;
+     111             :   OFile boxfile;
+     112             :   double lenunit;
+     113             :   double jacob_det;
+     114             :   double len_bi, len_cross, len_perp, sigma;
+     115             :   Vector origin, bi, cross, perp;
+     116             :   std::vector<Vector> dlbi, dlcross, dlperp;
+     117             :   std::vector<Tensor> dbi, dcross, dperp;
+     118             : public:
+     119             :   static void registerKeywords( Keywords& keys );
+     120             :   explicit VolumeCavity(const ActionOptions& ao);
+     121             :   ~VolumeCavity();
+     122             :   void setupRegions() override;
+     123             :   void update() override;
+     124             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+     125             : };
+     126             : 
+     127       10423 : PLUMED_REGISTER_ACTION(VolumeCavity,"CAVITY")
+     128             : 
+     129           3 : void VolumeCavity::registerKeywords( Keywords& keys ) {
+     130           3 :   ActionVolume::registerKeywords( keys );
+     131           6 :   keys.add("atoms","ATOMS","the positions of four atoms that define spatial extent of the cavity");
+     132           6 :   keys.addFlag("PRINT_BOX",false,"write out the positions of the corners of the box to an xyz file");
+     133           6 :   keys.add("optional","FILE","the file on which to write out the box coordinates");
+     134           6 :   keys.add("optional","UNITS","( default=nm ) the units in which to write out the corners of the box");
+     135           3 : }
+     136             : 
+     137           2 : VolumeCavity::VolumeCavity(const ActionOptions& ao):
+     138             :   Action(ao),
+     139             :   ActionVolume(ao),
+     140           2 :   boxout(false),
+     141           2 :   lenunit(1.0),
+     142           2 :   dlbi(4),
+     143           2 :   dlcross(4),
+     144           2 :   dlperp(4),
+     145           2 :   dbi(3),
+     146           2 :   dcross(3),
+     147           4 :   dperp(3)
+     148             : {
+     149             :   std::vector<AtomNumber> atoms;
+     150           4 :   parseAtomList("ATOMS",atoms);
+     151           2 :   if( atoms.size()!=4 ) error("number of atoms should be equal to four");
+     152             : 
+     153           2 :   log.printf("  boundaries for region are calculated based on positions of atoms : ");
+     154          10 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+     155           2 :   log.printf("\n");
+     156             : 
+     157           2 :   boxout=false; parseFlag("PRINT_BOX",boxout);
+     158           2 :   if(boxout) {
+     159           0 :     std::string boxfname; parse("FILE",boxfname);
+     160           0 :     if(boxfname.length()==0) error("no name for box file specified");
+     161           0 :     std::string unitname; parse("UNITS",unitname);
+     162           0 :     if ( unitname.length()>0 ) {
+     163           0 :       Units u; u.setLength(unitname);
+     164           0 :       lenunit=plumed.getAtoms().getUnits().getLength()/u.getLength();
+     165           0 :     } else {
+     166             :       unitname="nm";
+     167             :     }
+     168           0 :     boxfile.link(*this);
+     169           0 :     boxfile.open( boxfname );
+     170           0 :     log.printf("  printing box coordinates on file named %s in %s \n",boxfname.c_str(), unitname.c_str() );
+     171             :   }
+     172             : 
+     173           2 :   checkRead();
+     174           2 :   requestAtoms(atoms);
+     175             :   // We have to readd the dependency because requestAtoms removes it
+     176           2 :   addDependency( getPntrToMultiColvar() );
+     177           2 : }
+     178             : 
+     179           4 : VolumeCavity::~VolumeCavity() {
+     180           4 : }
+     181             : 
+     182        1620 : void VolumeCavity::setupRegions() {
+     183             :   // Make some space for things
+     184        1620 :   Vector d1, d2, d3;
+     185             : 
+     186             :   // Retrieve the sigma value
+     187        1620 :   sigma=getSigma();
+     188             :   // Set the position of the origin
+     189        1620 :   origin=getPosition(0);
+     190             : 
+     191             :   // Get two vectors
+     192        1620 :   d1 = pbcDistance(origin,getPosition(1));
+     193        1620 :   double d1l=d1.modulo();
+     194        1620 :   d2 = pbcDistance(origin,getPosition(2));
+     195             : 
+     196             :   // Find the vector connecting the origin to the top corner of
+     197             :   // the subregion
+     198        1620 :   d3 = pbcDistance(origin,getPosition(3));
+     199             : 
+     200             :   // Create a set of unit vectors
+     201        1620 :   bi = d1 / d1l; len_bi=dotProduct( d3, bi );
+     202        1620 :   cross = crossProduct( d1, d2 ); double crossmod=cross.modulo();
+     203        1620 :   cross = cross / crossmod; len_cross=dotProduct( d3, cross );
+     204        1620 :   perp = crossProduct( cross, bi ); len_perp=dotProduct( d3, perp );
+     205             : 
+     206             :   // Calculate derivatives of box shape with respect to atoms
+     207        1620 :   double d1l3=d1l*d1l*d1l;
+     208        1620 :   dbi[0](0,0) = ( -(d1[1]*d1[1]+d1[2]*d1[2])/d1l3 );   // dx/dx
+     209        1620 :   dbi[0](0,1) = (  d1[0]*d1[1]/d1l3 );                 // dx/dy
+     210        1620 :   dbi[0](0,2) = (  d1[0]*d1[2]/d1l3 );                 // dx/dz
+     211        1620 :   dbi[0](1,0) = (  d1[1]*d1[0]/d1l3 );                 // dy/dx
+     212        1620 :   dbi[0](1,1) = ( -(d1[0]*d1[0]+d1[2]*d1[2])/d1l3 );   // dy/dy
+     213        1620 :   dbi[0](1,2) = (  d1[1]*d1[2]/d1l3 );
+     214        1620 :   dbi[0](2,0) = (  d1[2]*d1[0]/d1l3 );
+     215        1620 :   dbi[0](2,1) = (  d1[2]*d1[1]/d1l3 );
+     216        1620 :   dbi[0](2,2) = ( -(d1[1]*d1[1]+d1[0]*d1[0])/d1l3 );
+     217             : 
+     218        1620 :   dbi[1](0,0) = ( (d1[1]*d1[1]+d1[2]*d1[2])/d1l3 );
+     219        1620 :   dbi[1](0,1) = ( -d1[0]*d1[1]/d1l3 );
+     220        1620 :   dbi[1](0,2) = ( -d1[0]*d1[2]/d1l3 );
+     221        1620 :   dbi[1](1,0) = ( -d1[1]*d1[0]/d1l3 );
+     222        1620 :   dbi[1](1,1) = ( (d1[0]*d1[0]+d1[2]*d1[2])/d1l3 );
+     223        1620 :   dbi[1](1,2) = ( -d1[1]*d1[2]/d1l3 );
+     224        1620 :   dbi[1](2,0) = ( -d1[2]*d1[0]/d1l3 );
+     225        1620 :   dbi[1](2,1) = ( -d1[2]*d1[1]/d1l3 );
+     226        1620 :   dbi[1](2,2) = ( (d1[1]*d1[1]+d1[0]*d1[0])/d1l3 );
+     227        1620 :   dbi[2].zero();
+     228             : 
+     229        1620 :   Tensor tcderiv; double cmod3=crossmod*crossmod*crossmod; Vector ucross=crossmod*cross;
+     230        1620 :   tcderiv.setCol( 0, crossProduct( d1, Vector(-1.0,0.0,0.0) ) + crossProduct( Vector(-1.0,0.0,0.0), d2 ) );
+     231        1620 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,-1.0,0.0) ) + crossProduct( Vector(0.0,-1.0,0.0), d2 ) );
+     232        1620 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,-1.0) ) + crossProduct( Vector(0.0,0.0,-1.0), d2 ) );
+     233        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
+     234        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
+     235        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
+     236        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
+     237        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
+     238        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
+     239        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
+     240        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
+     241        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
+     242             : 
+     243        1620 :   tcderiv.setCol( 0, crossProduct( Vector(1.0,0.0,0.0), d2 ) );
+     244        1620 :   tcderiv.setCol( 1, crossProduct( Vector(0.0,1.0,0.0), d2 ) );
+     245        1620 :   tcderiv.setCol( 2, crossProduct( Vector(0.0,0.0,1.0), d2 ) );
+     246        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
+     247        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
+     248        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
+     249        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
+     250        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
+     251        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
+     252        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
+     253        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
+     254        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
+     255             : 
+     256        1620 :   tcderiv.setCol( 0, crossProduct( d1, Vector(1.0,0.0,0.0) ) );
+     257        1620 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,1.0,0.0) ) );
+     258        1620 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,1.0) ) );
+     259        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
+     260        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
+     261        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
+     262        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
+     263        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
+     264        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
+     265        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
+     266        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
+     267        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
+     268             : 
+     269        1620 :   dperp[0].setCol( 0, ( crossProduct( dcross[0].getCol(0), bi ) + crossProduct( cross, dbi[0].getCol(0) ) ) );
+     270        1620 :   dperp[0].setCol( 1, ( crossProduct( dcross[0].getCol(1), bi ) + crossProduct( cross, dbi[0].getCol(1) ) ) );
+     271        1620 :   dperp[0].setCol( 2, ( crossProduct( dcross[0].getCol(2), bi ) + crossProduct( cross, dbi[0].getCol(2) ) ) );
+     272             : 
+     273        1620 :   dperp[1].setCol( 0, ( crossProduct( dcross[1].getCol(0), bi ) + crossProduct( cross, dbi[1].getCol(0) ) ) );
+     274        1620 :   dperp[1].setCol( 1, ( crossProduct( dcross[1].getCol(1), bi ) + crossProduct( cross, dbi[1].getCol(1) ) ) );
+     275        1620 :   dperp[1].setCol( 2, ( crossProduct( dcross[1].getCol(2), bi ) + crossProduct( cross, dbi[1].getCol(2) ) ) );
+     276             : 
+     277        1620 :   dperp[2].setCol( 0, ( crossProduct( dcross[2].getCol(0), bi ) ) );
+     278        1620 :   dperp[2].setCol( 1, ( crossProduct( dcross[2].getCol(1), bi ) ) );
+     279        1620 :   dperp[2].setCol( 2, ( crossProduct( dcross[2].getCol(2), bi ) ) );
+     280             : 
+     281             :   // Ensure that all lengths are positive
+     282        1620 :   if( len_bi<0 ) {
+     283           0 :     bi=-bi; len_bi=-len_bi;
+     284           0 :     for(unsigned i=0; i<3; ++i) dbi[i]*=-1.0;
+     285             :   }
+     286        1620 :   if( len_cross<0 ) {
+     287           0 :     cross=-cross; len_cross=-len_cross;
+     288           0 :     for(unsigned i=0; i<3; ++i) dcross[i]*=-1.0;
+     289             :   }
+     290        1620 :   if( len_perp<0 ) {
+     291           0 :     perp=-perp; len_perp=-len_perp;
+     292           0 :     for(unsigned i=0; i<3; ++i) dperp[i]*=-1.0;
+     293             :   }
+     294        1620 :   if( len_bi<=0 || len_cross<=0 || len_bi<=0 ) plumed_merror("Invalid box coordinates");
+     295             : 
+     296             :   // Now derivatives of lengths
+     297        1620 :   Tensor dd3( Tensor::identity() );
+     298        1620 :   dlbi[0] = matmul(d3,dbi[0]) - matmul(bi,dd3);
+     299        1620 :   dlbi[1] = matmul(d3,dbi[1]);
+     300        1620 :   dlbi[2] = matmul(d3,dbi[2]);
+     301        1620 :   dlbi[3] = matmul(bi,dd3);
+     302             : 
+     303        1620 :   dlcross[0] = matmul(d3,dcross[0]) - matmul(cross,dd3);
+     304        1620 :   dlcross[1] = matmul(d3,dcross[1]);
+     305        1620 :   dlcross[2] = matmul(d3,dcross[2]);
+     306        1620 :   dlcross[3] = matmul(cross,dd3);
+     307             : 
+     308        1620 :   dlperp[0] = matmul(d3,dperp[0]) - matmul(perp,dd3);
+     309        1620 :   dlperp[1] = matmul(d3,dperp[1]);
+     310        1620 :   dlperp[2] = matmul(d3,dperp[2]);
+     311        1620 :   dlperp[3] = matmul(perp,dd3);
+     312             : 
+     313             :   // Need to calculate the jacobian
+     314        1620 :   Tensor jacob;
+     315        1620 :   jacob(0,0)=bi[0]; jacob(1,0)=bi[1]; jacob(2,0)=bi[2];
+     316        1620 :   jacob(0,1)=cross[0]; jacob(1,1)=cross[1]; jacob(2,1)=cross[2];
+     317        1620 :   jacob(0,2)=perp[0]; jacob(1,2)=perp[1]; jacob(2,2)=perp[2];
+     318        1620 :   jacob_det = std::fabs( jacob.determinant() );
+     319        1620 : }
+     320             : 
+     321         120 : void VolumeCavity::update() {
+     322         120 :   if(boxout) {
+     323           0 :     boxfile.printf("%d\n",8);
+     324           0 :     const Tensor & t(getPbc().getBox());
+     325           0 :     if(getPbc().isOrthorombic()) {
+     326           0 :       boxfile.printf(" %f %f %f\n",lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     327             :     } else {
+     328           0 :       boxfile.printf(" %f %f %f %f %f %f %f %f %f\n",
+     329           0 :                      lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     330           0 :                      lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     331           0 :                      lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     332             :                     );
+     333             :     }
+     334           0 :     boxfile.printf("AR %f %f %f \n",lenunit*origin[0],lenunit*origin[1],lenunit*origin[2]);
+     335           0 :     Vector ut, vt, wt;
+     336           0 :     ut = origin + len_bi*bi;
+     337           0 :     vt = origin + len_cross*cross;
+     338           0 :     wt = origin + len_perp*perp;
+     339           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]), lenunit*(ut[1]), lenunit*(ut[2]) );
+     340           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]), lenunit*(vt[1]), lenunit*(vt[2]) );
+     341           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(wt[0]), lenunit*(wt[1]), lenunit*(wt[2]) );
+     342           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_bi*bi[0]),
+     343           0 :                    lenunit*(vt[1]+len_bi*bi[1]),
+     344           0 :                    lenunit*(vt[2]+len_bi*bi[2]) );
+     345           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]+len_perp*perp[0]),
+     346           0 :                    lenunit*(ut[1]+len_perp*perp[1]),
+     347           0 :                    lenunit*(ut[2]+len_perp*perp[2]) );
+     348           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]),
+     349           0 :                    lenunit*(vt[1]+len_perp*perp[1]),
+     350           0 :                    lenunit*(vt[2]+len_perp*perp[2]) );
+     351           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]+len_bi*bi[0]),
+     352           0 :                    lenunit*(vt[1]+len_perp*perp[1]+len_bi*bi[1]),
+     353           0 :                    lenunit*(vt[2]+len_perp*perp[2]+len_bi*bi[2]) );
+     354             :   }
+     355         120 : }
+     356             : 
+     357        1620 : double VolumeCavity::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& rderiv ) const {
+     358             :   // Setup the histogram bead
+     359        3240 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );
+     360             : 
+     361             :   // Calculate distance of atom from origin of new coordinate frame
+     362        1620 :   Vector datom=pbcDistance( origin, cpos );
+     363             :   double ucontr, uder, vcontr, vder, wcontr, wder;
+     364             : 
+     365             :   // Calculate contribution from integral along bi
+     366        1620 :   bead.set( 0, len_bi, sigma );
+     367        1620 :   double upos=dotProduct( datom, bi );
+     368        1620 :   ucontr=bead.calculate( upos, uder );
+     369        1620 :   double udlen=bead.uboundDerivative( upos );
+     370        1620 :   double uder2 = bead.lboundDerivative( upos ) - udlen;
+     371             : 
+     372             :   // Calculate contribution from integral along cross
+     373        1620 :   bead.set( 0, len_cross, sigma );
+     374        1620 :   double vpos=dotProduct( datom, cross );
+     375        1620 :   vcontr=bead.calculate( vpos, vder );
+     376        1620 :   double vdlen=bead.uboundDerivative( vpos );
+     377        1620 :   double vder2 = bead.lboundDerivative( vpos ) - vdlen;
+     378             : 
+     379             :   // Calculate contribution from integral along perp
+     380        1620 :   bead.set( 0, len_perp, sigma );
+     381        1620 :   double wpos=dotProduct( datom, perp );
+     382        1620 :   wcontr=bead.calculate( wpos, wder );
+     383        1620 :   double wdlen=bead.uboundDerivative( wpos );
+     384        1620 :   double wder2 = bead.lboundDerivative( wpos ) - wdlen;
+     385             : 
+     386        1620 :   Vector dfd; dfd[0]=uder*vcontr*wcontr; dfd[1]=ucontr*vder*wcontr; dfd[2]=ucontr*vcontr*wder;
+     387        1620 :   derivatives[0] = (dfd[0]*bi[0]+dfd[1]*cross[0]+dfd[2]*perp[0]);
+     388        1620 :   derivatives[1] = (dfd[0]*bi[1]+dfd[1]*cross[1]+dfd[2]*perp[1]);
+     389        1620 :   derivatives[2] = (dfd[0]*bi[2]+dfd[1]*cross[2]+dfd[2]*perp[2]);
+     390        1620 :   double tot = ucontr*vcontr*wcontr*jacob_det;
+     391             : 
+     392             :   // Add reference atom derivatives
+     393        1620 :   dfd[0]=uder2*vcontr*wcontr; dfd[1]=ucontr*vder2*wcontr; dfd[2]=ucontr*vcontr*wder2;
+     394        1620 :   Vector dfld; dfld[0]=udlen*vcontr*wcontr; dfld[1]=ucontr*vdlen*wcontr; dfld[2]=ucontr*vcontr*wdlen;
+     395        1620 :   rderiv[0] = dfd[0]*matmul(datom,dbi[0]) + dfd[1]*matmul(datom,dcross[0]) + dfd[2]*matmul(datom,dperp[0]) +
+     396        3240 :               dfld[0]*dlbi[0] + dfld[1]*dlcross[0] + dfld[2]*dlperp[0] - derivatives;
+     397        1620 :   rderiv[1] = dfd[0]*matmul(datom,dbi[1]) + dfd[1]*matmul(datom,dcross[1]) + dfd[2]*matmul(datom,dperp[1]) +
+     398        3240 :               dfld[0]*dlbi[1] + dfld[1]*dlcross[1] + dfld[2]*dlperp[1];
+     399        1620 :   rderiv[2] = dfd[0]*matmul(datom,dbi[2]) + dfd[1]*matmul(datom,dcross[2]) + dfd[2]*matmul(datom,dperp[2]) +
+     400        3240 :               dfld[0]*dlbi[2] + dfld[1]*dlcross[2] + dfld[2]*dlperp[2];
+     401        1620 :   rderiv[3] = dfld[0]*dlbi[3] + dfld[1]*dlcross[3] + dfld[2]*dlperp[3];
+     402             : 
+     403        1620 :   vir.zero(); vir-=Tensor( cpos,derivatives );
+     404        8100 :   for(unsigned i=0; i<4; ++i) {
+     405        6480 :     vir -= Tensor( getPosition(i), rderiv[i] );
+     406             :   }
+     407             : 
+     408        1620 :   return tot;
+     409             : }
+     410             : 
+     411             : }
+     412             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..8facb1e711 --- /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:465879.3 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18VolumeGradientBase15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar18VolumeGradientBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar18VolumeGradientBase12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE30
_ZN4PLMD11multicolvar18VolumeGradientBaseC2ERKNS_13ActionOptionsE30
_ZN4PLMD11multicolvar18VolumeGradientBase16registerKeywordsERNS_8KeywordsE37
_ZN4PLMD11multicolvar18VolumeGradientBase28doJobsRequiredBeforeTaskListEv2239
_ZNK4PLMD11multicolvar18VolumeGradientBase12completeTaskERKjRNS_10MultiValueES5_80958
_ZNK4PLMD11multicolvar18VolumeGradientBase17setNumberInVolumeERKjS3_RKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERKSt6vectorIS7_SaIS7_EERNS_10MultiValueE115758
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.cpp.func.html b/coverage/multicolvar/VolumeGradientBase.cpp.func.html new file mode 100644 index 0000000000..102f287cf5 --- /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:465879.3 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18VolumeGradientBase12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE30
_ZN4PLMD11multicolvar18VolumeGradientBase15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar18VolumeGradientBase16registerKeywordsERNS_8KeywordsE37
_ZN4PLMD11multicolvar18VolumeGradientBase28doJobsRequiredBeforeTaskListEv2239
_ZN4PLMD11multicolvar18VolumeGradientBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar18VolumeGradientBaseC2ERKNS_13ActionOptionsE30
_ZNK4PLMD11multicolvar18VolumeGradientBase12completeTaskERKjRNS_10MultiValueES5_80958
_ZNK4PLMD11multicolvar18VolumeGradientBase17setNumberInVolumeERKjS3_RKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERKSt6vectorIS7_SaIS7_EERNS_10MultiValueE115758
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.cpp.gcov.html b/coverage/multicolvar/VolumeGradientBase.cpp.gcov.html new file mode 100644 index 0000000000..1751c6ea1f --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + + 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:465879.3 %
Date:2024-06-10 08:19:14Functions: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          37 : void VolumeGradientBase::registerKeywords( Keywords& keys ) {
+      31          37 :   BridgedMultiColvarFunction::registerKeywords( keys );
+      32          37 : }
+      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          33 :   for(const auto & p : getDependencies() ) checklabs.insert(std::pair<std::string,bool>(p->getLabel(),false));
+      44         102 :   for(const auto & p : plumed.getActionSet() ) {
+      45         102 :     if( p->getLabel()==getPntrToMultiColvar()->getLabel() ) break;
+      46           3 :     if( checklabs.count(p->getLabel()) ) checklabs[p->getLabel()]=true;
+      47             :   }
+      48          33 :   for(const auto & p : checklabs ) {
+      49           3 :     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      112725 :     }
+      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             :       CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
+     101             :       for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
+     102             :         unsigned jatom=3*catom.getIndex(i);
+     103             :         outvals.addDerivative( ivol, jatom+0, weight*outvals.getDerivative(ivol,jatom+0) + ww*catom.getDerivative(i,0,wdf) );
+     104             :         outvals.addDerivative( ivol, jatom+1, weight*outvals.getDerivative(ivol,jatom+1) + ww*catom.getDerivative(i,1,wdf) );
+     105             :         outvals.addDerivative( ivol, jatom+2, weight*outvals.getDerivative(ivol,jatom+2) + ww*catom.getDerivative(i,2,wdf) );
+     106             :       }
+     107             :       unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
+     108             :       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) );
+     109             :       for(unsigned i=0; i<refders.size(); ++i) {
+     110             :         unsigned iatom=nmder+3*i;
+     111             :         outvals.addDerivative( ivol, iatom+0, ww*refders[i][0] );
+     112             :         outvals.addDerivative( ivol, iatom+1, ww*refders[i][1] );
+     113             :         outvals.addDerivative( ivol, iatom+2, ww*refders[i][2] );
+     114             :       }
+     115             :     }
+     116             :   } else {
+     117           0 :     double ww=outvals.get(0); outvals.setValue(ivol,ww*weight);
+     118           0 :     if( derivativesAreRequired() ) {
+     119           0 :       plumed_merror("This needs testing");
+     120             :       CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
+     121             :       for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
+     122             :         unsigned jatom=3*catom.getIndex(i);
+     123             :         outvals.addDerivative( ivol, jatom+0, ww*catom.getDerivative(i,0,wdf) );
+     124             :         outvals.addDerivative( ivol, jatom+1, ww*catom.getDerivative(i,1,wdf) );
+     125             :         outvals.addDerivative( ivol, jatom+2, ww*catom.getDerivative(i,2,wdf) );
+     126             :       }
+     127             :       unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
+     128             :       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) );
+     129             :       for(unsigned i=0; i<refders.size(); ++i) {
+     130             :         unsigned iatom=nmder+3*i;
+     131             :         outvals.addDerivative( ivol, iatom+0, ww*refders[i][0] );
+     132             :         outvals.addDerivative( ivol, iatom+1, ww*refders[i][1] );
+     133             :         outvals.addDerivative( ivol, iatom+2, ww*refders[i][2] );
+     134             :       }
+     135             :     }
+     136             :   }
+     137      115758 : }
+     138             : 
+     139           0 : void VolumeGradientBase::addBridgeForces( const std::vector<double>& bb ) {
+     140             :   plumed_dbg_assert( bb.size()==tmpforces.size()-9 );
+     141             :   // Forces on local atoms
+     142           0 :   for(unsigned i=0; i<bb.size(); ++i) tmpforces[i]=bb[i];
+     143             :   // Virial contribution is zero
+     144           0 :   for(unsigned i=bb.size(); i<bb.size()+9; ++i) tmpforces[i]=0.0;
+     145           0 :   setForcesOnAtoms( tmpforces, 0 );
+     146           0 : }
+     147             : 
+     148             : }
+     149             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..34df207b61 --- /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:99100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar18VolumeGradientBase11getPositionEi240427
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.h.func.html b/coverage/multicolvar/VolumeGradientBase.h.func.html new file mode 100644 index 0000000000..ebf0f2534e --- /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:99100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar18VolumeGradientBase11getPositionEi240427
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.h.gcov.html b/coverage/multicolvar/VolumeGradientBase.h.gcov.html new file mode 100644 index 0000000000..56301473f8 --- /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:99100.0 %
Date:2024-06-10 08:19:14Functions: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      233947 :   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.15
+
+ + + 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 0000000000..11c64cb754 --- /dev/null +++ b/coverage/multicolvar/VolumeInCylinder.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:474995.9 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16VolumeInCylinderC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe876createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16VolumeInCylinderC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16VolumeInCylinder16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar16VolumeInCylinder12setupRegionsEv20
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe87C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe87D2Ev3473
_ZNK4PLMD11multicolvar16VolumeInCylinder21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE4000
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeInCylinder.cpp.func.html b/coverage/multicolvar/VolumeInCylinder.cpp.func.html new file mode 100644 index 0000000000..bfcce08ebc --- /dev/null +++ b/coverage/multicolvar/VolumeInCylinder.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:474995.9 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe876createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe87C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe87D2Ev3473
_ZN4PLMD11multicolvar16VolumeInCylinder12setupRegionsEv20
_ZN4PLMD11multicolvar16VolumeInCylinder16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar16VolumeInCylinderC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16VolumeInCylinderC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16VolumeInCylinder21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE4000
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeInCylinder.cpp.gcov.html b/coverage/multicolvar/VolumeInCylinder.cpp.gcov.html new file mode 100644 index 0000000000..0ca766d909 --- /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:474995.9 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(VolumeInCylinder,"INCYLINDER")
+      88             : 
+      89           2 : void VolumeInCylinder::registerKeywords( Keywords& keys ) {
+      90           2 :   ActionVolume::registerKeywords( keys );
+      91           4 :   keys.add("atoms","ATOM","the atom whose vicinity we are interested in examining");
+      92           4 :   keys.add("compulsory","DIRECTION","the direction of the long axis of the cylinder. Must be x, y or z");
+      93           4 :   keys.add("compulsory","RADIUS","a switching function that gives the extent of the cylinder in the plane perpendicular to the direction");
+      94           4 :   keys.add("compulsory","LOWER","0.0","the lower boundary on the direction parallel to the long axis of the cylinder");
+      95           4 :   keys.add("compulsory","UPPER","0.0","the upper boundary on the direction parallel to the long axis of the cylinder");
+      96           4 :   keys.reset_style("SIGMA","optional");
+      97           2 : }
+      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.15
+
+ + + 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 0000000000..0148b956ee --- /dev/null +++ b/coverage/multicolvar/VolumeInSphere.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar14VolumeInSphereC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe836createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar14VolumeInSphereC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar14VolumeInSphere16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar14VolumeInSphere12setupRegionsEv82
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe83C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe83D2Ev3473
_ZNK4PLMD11multicolvar14VolumeInSphere21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE155474
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeInSphere.cpp.func.html b/coverage/multicolvar/VolumeInSphere.cpp.func.html new file mode 100644 index 0000000000..791245c263 --- /dev/null +++ b/coverage/multicolvar/VolumeInSphere.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:2626100.0 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe836createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe83C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe83D2Ev3473
_ZN4PLMD11multicolvar14VolumeInSphere12setupRegionsEv82
_ZN4PLMD11multicolvar14VolumeInSphere16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar14VolumeInSphereC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar14VolumeInSphereC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar14VolumeInSphere21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE155474
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeInSphere.cpp.gcov.html b/coverage/multicolvar/VolumeInSphere.cpp.gcov.html new file mode 100644 index 0000000000..aef3118ba8 --- /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:2626100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10425 : PLUMED_REGISTER_ACTION(VolumeInSphere,"INSPHERE")
+      84             : 
+      85           4 : void VolumeInSphere::registerKeywords( Keywords& keys ) {
+      86           4 :   ActionVolume::registerKeywords( keys );
+      87           8 :   keys.add("atoms","ATOM","the atom whose vicinity we are interested in examining");
+      88           8 :   keys.add("compulsory","RADIUS","the switching function that tells us the extent of the spherical region of interest");
+      89           4 :   keys.remove("SIGMA");
+      90           4 : }
+      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.15
+
+ + + 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 0000000000..4e150a7882 --- /dev/null +++ b/coverage/multicolvar/VolumeTetrapore.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:82323.4 %
Date:2024-06-10 08:19:14Functions:31225.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe1356createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetrapore12setupRegionsEv0
_ZN4PLMD11multicolvar15VolumeTetrapore6updateEv0
_ZN4PLMD11multicolvar15VolumeTetraporeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeD0Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD1Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD2Ev0
_ZNK4PLMD11multicolvar15VolumeTetrapore21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
_ZN4PLMD11multicolvar15VolumeTetrapore16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe135C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe135D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeTetrapore.cpp.func.html b/coverage/multicolvar/VolumeTetrapore.cpp.func.html new file mode 100644 index 0000000000..3a53cb8f82 --- /dev/null +++ b/coverage/multicolvar/VolumeTetrapore.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:82323.4 %
Date:2024-06-10 08:19:14Functions:31225.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe1356createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe135C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe135D2Ev3473
_ZN4PLMD11multicolvar15VolumeTetrapore12setupRegionsEv0
_ZN4PLMD11multicolvar15VolumeTetrapore16registerKeywordsERNS_8KeywordsE1
_ZN4PLMD11multicolvar15VolumeTetrapore6updateEv0
_ZN4PLMD11multicolvar15VolumeTetraporeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeD0Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD1Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD2Ev0
_ZNK4PLMD11multicolvar15VolumeTetrapore21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/VolumeTetrapore.cpp.gcov.html b/coverage/multicolvar/VolumeTetrapore.cpp.gcov.html new file mode 100644 index 0000000000..075128d31e --- /dev/null +++ b/coverage/multicolvar/VolumeTetrapore.cpp.gcov.html @@ -0,0 +1,524 @@ + + + + + + + + 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:82323.4 %
Date:2024-06-10 08:19:14Functions:31225.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 "core/PlumedMain.h"
+      24             : #include "core/Atoms.h"
+      25             : #include "tools/Units.h"
+      26             : #include "tools/Pbc.h"
+      27             : #include "ActionVolume.h"
+      28             : 
+      29             : //+PLUMEDOC VOLUMES TETRAHEDRALPORE
+      30             : /*
+      31             : 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.
+      32             : 
+      33             : Each of the base quantities calculated by a multicolvar can can be assigned to a particular point in three
+      34             : dimensional space. For example, if we have the coordination numbers for all the atoms in the
+      35             : system each coordination number can be assumed to lie on the position of the central atom.
+      36             : Because each base quantity can be assigned to a particular point in space we can calculate functions of the
+      37             : distribution of base quantities in a particular part of the box by using:
+      38             : 
+      39             : \f[
+      40             : \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) }
+      41             : \f]
+      42             : 
+      43             : 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$.
+      44             : 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.
+      45             : 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$
+      46             : position to a position in \f$ (u_i,v_i,z_i)\f$.  This is done using a rotation matrix as follows:
+      47             : 
+      48             : \f[
+      49             : \left(
+      50             : \begin{matrix}
+      51             :  u_i \\
+      52             :  v_i \\
+      53             :  w_i
+      54             : \end{matrix}
+      55             : \right) = \mathbf{R}
+      56             : \left(
+      57             : \begin{matrix}
+      58             :  x_i - x_o \\
+      59             :  y_i - y_o \\
+      60             :  z_i - z_o
+      61             : \end{matrix}
+      62             : \right)
+      63             : \f]
+      64             : 
+      65             : where \f$\mathbf{R}\f$ is a rotation matrix that is calculated by constructing a set of three orthonormal vectors from the
+      66             : reference positions specified by the user.  Initially unit vectors are found by calculating the bisector, \f$\mathbf{b}\f$, and
+      67             : 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
+      68             : product between the cross product calculated during the first step, \f$\mathbf{c}\f$ and the bisector, \f$\mathbf{b}\f$.  From this
+      69             : second cross product \f$\mathbf{p}\f$ and the bisector \f$\mathbf{b}\f$ two new vectors are calculated using:
+      70             : 
+      71             : \f[
+      72             : v_1 = \cos\left(\frac{\pi}{4}\right)\mathbf{b} + \sin\left(\frac{\pi}{4}\right)\mathbf{p} \qquad \textrm{and} \qquad
+      73             : v_2 = \cos\left(\frac{\pi}{4}\right)\mathbf{b} - \sin\left(\frac{\pi}{4}\right)\mathbf{p}
+      74             : \f]
+      75             : 
+      76             : 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
+      77             : is equal to:
+      78             : 
+      79             : \f[
+      80             : 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
+      81             :    K\left( \frac{u - u_i}{\sigma} \right)K\left( \frac{v - v_i}{\sigma} \right)K\left( \frac{w - w_i}{\sigma} \right)
+      82             : \f]
+      83             : 
+      84             : where \f$K\f$ is one of the kernel functions described on \ref histogrambead and \f$\sigma\f$ is a bandwidth parameter.
+      85             : 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
+      86             : 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
+      87             : the calculations.  \f$w'\f$ is calculated by taking the projection of the vector connecting atoms 1 and 4 on the vector
+      88             : \f$\mathbf{c}\f$.  Notice that the manner by which this box is constructed differs from the way this is done in \ref CAVITY.
+      89             : This is in fact the only point of difference between these two actions.
+      90             : 
+      91             : \par Examples
+      92             : 
+      93             : The following commands tell plumed to calculate the number of atom inside a tetrahedral cavity.  The extent of the tetrahedral
+      94             : cavity is calculated from the positions of atoms 1, 4, 5, and 11,  The final value will be labeled cav.
+      95             : 
+      96             : \plumedfile
+      97             : d1: DENSITY SPECIES=20-500
+      98             : TETRAHEDRALPORE DATA=d1 ATOMS=1,4,5,11 SIGMA=0.1 LABEL=cav
+      99             : \endplumedfile
+     100             : 
+     101             : The following command tells plumed to calculate the coordination numbers (with other water molecules) for the water
+     102             : molecules in the tetrahedral cavity described above.  The average coordination number and the number of coordination
+     103             : numbers more than 4 is then calculated.  The values of these two quantities are given the labels cav.mean and cav.morethan
+     104             : 
+     105             : \plumedfile
+     106             : d1: COORDINATIONNUMBER SPECIES=20-500 R_0=0.1
+     107             : CAVITY DATA=d1 ATOMS=1,4,5,11 SIGMA=0.1 MEAN MORE_THAN={RATIONAL R_0=4} LABEL=cav
+     108             : \endplumedfile
+     109             : 
+     110             : */
+     111             : //+ENDPLUMEDOC
+     112             : 
+     113             : namespace PLMD {
+     114             : namespace multicolvar {
+     115             : 
+     116             : class VolumeTetrapore : public ActionVolume {
+     117             : private:
+     118             :   bool boxout;
+     119             :   OFile boxfile;
+     120             :   double lenunit;
+     121             :   double jacob_det;
+     122             :   double len_bi, len_cross, len_perp, sigma;
+     123             :   Vector origin, bi, cross, perp;
+     124             :   std::vector<Vector> dlbi, dlcross, dlperp;
+     125             :   std::vector<Tensor> dbi, dcross, dperp;
+     126             : public:
+     127             :   static void registerKeywords( Keywords& keys );
+     128             :   explicit VolumeTetrapore(const ActionOptions& ao);
+     129             :   ~VolumeTetrapore();
+     130             :   void setupRegions() override;
+     131             :   void update() override;
+     132             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+     133             : };
+     134             : 
+     135       10419 : PLUMED_REGISTER_ACTION(VolumeTetrapore,"TETRAHEDRALPORE")
+     136             : 
+     137           1 : void VolumeTetrapore::registerKeywords( Keywords& keys ) {
+     138           1 :   ActionVolume::registerKeywords( keys );
+     139           2 :   keys.add("atoms","ATOMS","the positions of four atoms that define spatial extent of the cavity");
+     140           2 :   keys.addFlag("PRINT_BOX",false,"write out the positions of the corners of the box to an xyz file");
+     141           2 :   keys.add("optional","FILE","the file on which to write out the box coordinates");
+     142           2 :   keys.add("optional","UNITS","( default=nm ) the units in which to write out the corners of the box");
+     143           1 : }
+     144             : 
+     145           0 : VolumeTetrapore::VolumeTetrapore(const ActionOptions& ao):
+     146             :   Action(ao),
+     147             :   ActionVolume(ao),
+     148           0 :   boxout(false),
+     149           0 :   lenunit(1.0),
+     150           0 :   dlbi(4),
+     151           0 :   dlcross(4),
+     152           0 :   dlperp(4),
+     153           0 :   dbi(3),
+     154           0 :   dcross(3),
+     155           0 :   dperp(3)
+     156             : {
+     157             :   std::vector<AtomNumber> atoms;
+     158           0 :   parseAtomList("ATOMS",atoms);
+     159           0 :   if( atoms.size()!=4 ) error("number of atoms should be equal to four");
+     160             : 
+     161           0 :   log.printf("  boundaries for region are calculated based on positions of atoms : ");
+     162           0 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+     163           0 :   log.printf("\n");
+     164             : 
+     165           0 :   boxout=false; parseFlag("PRINT_BOX",boxout);
+     166           0 :   if(boxout) {
+     167           0 :     std::string boxfname; parse("FILE",boxfname);
+     168           0 :     if(boxfname.length()==0) error("no name for box file specified");
+     169           0 :     std::string unitname; parse("UNITS",unitname);
+     170           0 :     if ( unitname.length()>0 ) {
+     171           0 :       Units u; u.setLength(unitname);
+     172           0 :       lenunit=plumed.getAtoms().getUnits().getLength()/u.getLength();
+     173           0 :     } else {
+     174             :       unitname="nm";
+     175             :     }
+     176           0 :     boxfile.link(*this);
+     177           0 :     boxfile.open( boxfname );
+     178           0 :     log.printf("  printing box coordinates on file named %s in %s \n",boxfname.c_str(), unitname.c_str() );
+     179             :   }
+     180             : 
+     181           0 :   checkRead();
+     182           0 :   requestAtoms(atoms);
+     183             :   // We have to readd the dependency because requestAtoms removes it
+     184           0 :   addDependency( getPntrToMultiColvar() );
+     185           0 : }
+     186             : 
+     187           0 : VolumeTetrapore::~VolumeTetrapore() {
+     188           0 : }
+     189             : 
+     190           0 : void VolumeTetrapore::setupRegions() {
+     191             :   // Make some space for things
+     192           0 :   Vector d1, d2, d3;
+     193             : 
+     194             :   // Retrieve the sigma value
+     195           0 :   sigma=getSigma();
+     196             :   // Set the position of the origin
+     197           0 :   origin=getPosition(0);
+     198             : 
+     199             :   // Get two vectors
+     200           0 :   d1 = pbcDistance(origin,getPosition(1));
+     201           0 :   d2 = pbcDistance(origin,getPosition(2));
+     202             : 
+     203             :   // Find the vector connecting the origin to the top corner of
+     204             :   // the subregion
+     205           0 :   d3 = pbcDistance(origin,getPosition(3));
+     206             : 
+     207             :   // Create a set of unit vectors
+     208           0 :   Vector bisector = d1 + d2; double bmod=bisector.modulo(); bisector=bisector/bmod;
+     209             : 
+     210             :   // bi = d1 / d1l; len_bi=dotProduct( d3, bi );
+     211           0 :   cross = crossProduct( d1, d2 ); double crossmod=cross.modulo();
+     212           0 :   cross = cross / crossmod; len_cross=dotProduct( d3, cross );
+     213           0 :   Vector truep = crossProduct( cross, bisector );
+     214             : 
+     215             :   // These are our true vectors 45 degrees from bisector
+     216           0 :   bi = std::cos(pi/4.0)*bisector + std::sin(pi/4.0)*truep;
+     217           0 :   perp = std::cos(pi/4.0)*bisector - std::sin(pi/4.0)*truep;
+     218             : 
+     219             :   // And the lengths of the various parts average distance to opposite corners of tetetrahedron
+     220           0 :   len_bi = dotProduct( d1, bi ); double len_bi2 = dotProduct( d2, bi ); unsigned lbi=1;
+     221           0 :   if( len_bi2>len_bi ) { len_bi=len_bi2; lbi=2; }
+     222           0 :   len_perp = dotProduct( d1, perp ); double len_perp2 = dotProduct( d2, perp ); unsigned lpi=1;
+     223           0 :   if( len_perp2>len_perp ) { len_perp=len_perp2; lpi=2; }
+     224           0 :   plumed_assert( lbi!=lpi );
+     225             : 
+     226           0 :   Tensor tcderiv; double cmod3=crossmod*crossmod*crossmod; Vector ucross=crossmod*cross;
+     227           0 :   tcderiv.setCol( 0, crossProduct( d1, Vector(-1.0,0.0,0.0) ) + crossProduct( Vector(-1.0,0.0,0.0), d2 ) );
+     228           0 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,-1.0,0.0) ) + crossProduct( Vector(0.0,-1.0,0.0), d2 ) );
+     229           0 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,-1.0) ) + crossProduct( Vector(0.0,0.0,-1.0), d2 ) );
+     230           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
+     231           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
+     232           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
+     233           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
+     234           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
+     235           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
+     236           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
+     237           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
+     238           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
+     239             : 
+     240           0 :   tcderiv.setCol( 0, crossProduct( Vector(1.0,0.0,0.0), d2 ) );
+     241           0 :   tcderiv.setCol( 1, crossProduct( Vector(0.0,1.0,0.0), d2 ) );
+     242           0 :   tcderiv.setCol( 2, crossProduct( Vector(0.0,0.0,1.0), d2 ) );
+     243           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
+     244           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
+     245           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
+     246           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
+     247           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
+     248           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
+     249           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
+     250           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
+     251           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
+     252             : 
+     253           0 :   tcderiv.setCol( 0, crossProduct( d1, Vector(1.0,0.0,0.0) ) );
+     254           0 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,1.0,0.0) ) );
+     255           0 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,1.0) ) );
+     256           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
+     257           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
+     258           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
+     259           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
+     260           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
+     261           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
+     262           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
+     263           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
+     264           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
+     265             : 
+     266           0 :   std::vector<Tensor> dbisector(3);
+     267           0 :   double bmod3=bmod*bmod*bmod; Vector ubisector=bmod*bisector;
+     268           0 :   dbisector[0](0,0)= -2.0/bmod + 2*ubisector[0]*ubisector[0]/bmod3;
+     269           0 :   dbisector[0](0,1)= 2*ubisector[0]*ubisector[1]/bmod3;
+     270           0 :   dbisector[0](0,2)= 2*ubisector[0]*ubisector[2]/bmod3;
+     271           0 :   dbisector[0](1,0)= 2*ubisector[1]*ubisector[0]/bmod3;
+     272           0 :   dbisector[0](1,1)= -2.0/bmod + 2*ubisector[1]*ubisector[1]/bmod3;
+     273           0 :   dbisector[0](1,2)= 2*ubisector[1]*ubisector[2]/bmod3;
+     274           0 :   dbisector[0](2,0)= 2*ubisector[2]*ubisector[0]/bmod3;
+     275           0 :   dbisector[0](2,1)= 2*ubisector[2]*ubisector[1]/bmod3;
+     276           0 :   dbisector[0](2,2)= -2.0/bmod + 2*ubisector[2]*ubisector[2]/bmod3;
+     277             : 
+     278           0 :   dbisector[1](0,0)= 1.0/bmod - ubisector[0]*ubisector[0]/bmod3;
+     279           0 :   dbisector[1](0,1)= -ubisector[0]*ubisector[1]/bmod3;
+     280           0 :   dbisector[1](0,2)= -ubisector[0]*ubisector[2]/bmod3;
+     281           0 :   dbisector[1](1,0)= -ubisector[1]*ubisector[0]/bmod3;
+     282           0 :   dbisector[1](1,1)= 1.0/bmod - ubisector[1]*ubisector[1]/bmod3;
+     283           0 :   dbisector[1](1,2)= -ubisector[1]*ubisector[2]/bmod3;
+     284           0 :   dbisector[1](2,0)= -ubisector[2]*ubisector[0]/bmod3;
+     285           0 :   dbisector[1](2,1)= -ubisector[2]*ubisector[1]/bmod3;
+     286           0 :   dbisector[1](2,2)=1.0/bmod - ubisector[2]*ubisector[2]/bmod3;
+     287             : 
+     288           0 :   dbisector[2](0,0)=1.0/bmod - ubisector[0]*ubisector[0]/bmod3;
+     289           0 :   dbisector[2](0,1)= -ubisector[0]*ubisector[1]/bmod3;
+     290           0 :   dbisector[2](0,2)= -ubisector[0]*ubisector[2]/bmod3;
+     291           0 :   dbisector[2](1,0)= -ubisector[1]*ubisector[0]/bmod3;
+     292           0 :   dbisector[2](1,1)=1.0/bmod - ubisector[1]*ubisector[1]/bmod3;
+     293           0 :   dbisector[2](1,2)= -ubisector[1]*ubisector[2]/bmod3;
+     294           0 :   dbisector[2](2,0)= -ubisector[2]*ubisector[0]/bmod3;
+     295           0 :   dbisector[2](2,1)= -ubisector[2]*ubisector[1]/bmod3;
+     296           0 :   dbisector[2](2,2)=1.0/bmod - ubisector[2]*ubisector[2]/bmod3;
+     297             : 
+     298           0 :   std::vector<Tensor> dtruep(3);
+     299           0 :   dtruep[0].setCol( 0, ( crossProduct( dcross[0].getCol(0), bisector ) + crossProduct( cross, dbisector[0].getCol(0) ) ) );
+     300           0 :   dtruep[0].setCol( 1, ( crossProduct( dcross[0].getCol(1), bisector ) + crossProduct( cross, dbisector[0].getCol(1) ) ) );
+     301           0 :   dtruep[0].setCol( 2, ( crossProduct( dcross[0].getCol(2), bisector ) + crossProduct( cross, dbisector[0].getCol(2) ) ) );
+     302             : 
+     303           0 :   dtruep[1].setCol( 0, ( crossProduct( dcross[1].getCol(0), bisector ) + crossProduct( cross, dbisector[1].getCol(0) ) ) );
+     304           0 :   dtruep[1].setCol( 1, ( crossProduct( dcross[1].getCol(1), bisector ) + crossProduct( cross, dbisector[1].getCol(1) ) ) );
+     305           0 :   dtruep[1].setCol( 2, ( crossProduct( dcross[1].getCol(2), bisector ) + crossProduct( cross, dbisector[1].getCol(2) ) ) );
+     306             : 
+     307           0 :   dtruep[2].setCol( 0, ( crossProduct( dcross[2].getCol(0), bisector ) + crossProduct( cross, dbisector[2].getCol(0) ) ) );
+     308           0 :   dtruep[2].setCol( 1, ( crossProduct( dcross[2].getCol(1), bisector ) + crossProduct( cross, dbisector[2].getCol(1) ) ) );
+     309           0 :   dtruep[2].setCol( 2, ( crossProduct( dcross[2].getCol(2), bisector ) + crossProduct( cross, dbisector[2].getCol(2) ) ) );
+     310             : 
+     311             :   // Now convert these to the derivatives of the true axis
+     312           0 :   for(unsigned i=0; i<3; ++i) {
+     313           0 :     dbi[i] = std::cos(pi/4.0)*dbisector[i] + std::sin(pi/4.0)*dtruep[i];
+     314           0 :     dperp[i] = std::cos(pi/4.0)*dbisector[i] - std::sin(pi/4.0)*dtruep[i];
+     315             :   }
+     316             : 
+     317             :   // Ensure that all lengths are positive
+     318           0 :   if( len_bi<0 ) {
+     319           0 :     bi=-bi; len_bi=-len_bi;
+     320           0 :     for(unsigned i=0; i<3; ++i) dbi[i]*=-1.0;
+     321             :   }
+     322           0 :   if( len_cross<0 ) {
+     323           0 :     cross=-cross; len_cross=-len_cross;
+     324           0 :     for(unsigned i=0; i<3; ++i) dcross[i]*=-1.0;
+     325             :   }
+     326           0 :   if( len_perp<0 ) {
+     327           0 :     perp=-perp; len_perp=-len_perp;
+     328           0 :     for(unsigned i=0; i<3; ++i) dperp[i]*=-1.0;
+     329             :   }
+     330           0 :   if( len_bi<=0 || len_cross<=0 || len_bi<=0 ) plumed_merror("Invalid box coordinates");
+     331             : 
+     332             :   // Now derivatives of lengths
+     333           0 :   Tensor dd3( Tensor::identity() ); Vector ddb2=d1; if( lbi==2 ) ddb2=d2;
+     334           0 :   dlbi[1].zero(); dlbi[2].zero(); dlbi[3].zero();
+     335           0 :   dlbi[0] = matmul(ddb2,dbi[0]) - matmul(bi,dd3);
+     336           0 :   dlbi[lbi] = matmul(ddb2,dbi[lbi]) + matmul(bi,dd3);  // Derivative wrt d1
+     337             : 
+     338           0 :   dlcross[0] = matmul(d3,dcross[0]) - matmul(cross,dd3);
+     339           0 :   dlcross[1] = matmul(d3,dcross[1]);
+     340           0 :   dlcross[2] = matmul(d3,dcross[2]);
+     341           0 :   dlcross[3] = matmul(cross,dd3);
+     342             : 
+     343           0 :   ddb2=d1; if( lpi==2 ) ddb2=d2;
+     344           0 :   dlperp[1].zero(); dlperp[2].zero(); dlperp[3].zero();
+     345           0 :   dlperp[0] = matmul(ddb2,dperp[0]) - matmul( perp, dd3 );
+     346           0 :   dlperp[lpi] = matmul(ddb2,dperp[lpi]) + matmul(perp, dd3);
+     347             : 
+     348             :   // Need to calculate the jacobian
+     349           0 :   Tensor jacob;
+     350           0 :   jacob(0,0)=bi[0]; jacob(1,0)=bi[1]; jacob(2,0)=bi[2];
+     351           0 :   jacob(0,1)=cross[0]; jacob(1,1)=cross[1]; jacob(2,1)=cross[2];
+     352           0 :   jacob(0,2)=perp[0]; jacob(1,2)=perp[1]; jacob(2,2)=perp[2];
+     353           0 :   jacob_det = std::fabs( jacob.determinant() );
+     354           0 : }
+     355             : 
+     356           0 : void VolumeTetrapore::update() {
+     357           0 :   if(boxout) {
+     358           0 :     boxfile.printf("%d\n",8);
+     359           0 :     const Tensor & t(getPbc().getBox());
+     360           0 :     if(getPbc().isOrthorombic()) {
+     361           0 :       boxfile.printf(" %f %f %f\n",lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     362             :     } else {
+     363           0 :       boxfile.printf(" %f %f %f %f %f %f %f %f %f\n",
+     364           0 :                      lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     365           0 :                      lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     366           0 :                      lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     367             :                     );
+     368             :     }
+     369           0 :     boxfile.printf("AR %f %f %f \n",lenunit*origin[0],lenunit*origin[1],lenunit*origin[2]);
+     370           0 :     Vector ut, vt, wt;
+     371           0 :     ut = origin + len_bi*bi;
+     372           0 :     vt = origin + len_cross*cross;
+     373           0 :     wt = origin + len_perp*perp;
+     374           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]), lenunit*(ut[1]), lenunit*(ut[2]) );
+     375           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]), lenunit*(vt[1]), lenunit*(vt[2]) );
+     376           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(wt[0]), lenunit*(wt[1]), lenunit*(wt[2]) );
+     377           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_bi*bi[0]),
+     378           0 :                    lenunit*(vt[1]+len_bi*bi[1]),
+     379           0 :                    lenunit*(vt[2]+len_bi*bi[2]) );
+     380           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]+len_perp*perp[0]),
+     381           0 :                    lenunit*(ut[1]+len_perp*perp[1]),
+     382           0 :                    lenunit*(ut[2]+len_perp*perp[2]) );
+     383           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]),
+     384           0 :                    lenunit*(vt[1]+len_perp*perp[1]),
+     385           0 :                    lenunit*(vt[2]+len_perp*perp[2]) );
+     386           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]+len_bi*bi[0]),
+     387           0 :                    lenunit*(vt[1]+len_perp*perp[1]+len_bi*bi[1]),
+     388           0 :                    lenunit*(vt[2]+len_perp*perp[2]+len_bi*bi[2]) );
+     389             :   }
+     390           0 : }
+     391             : 
+     392           0 : double VolumeTetrapore::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& rderiv ) const {
+     393             :   // Setup the histogram bead
+     394           0 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );
+     395             : 
+     396             :   // Calculate distance of atom from origin of new coordinate frame
+     397           0 :   Vector datom=pbcDistance( origin, cpos );
+     398             :   double ucontr, uder, vcontr, vder, wcontr, wder;
+     399             : 
+     400             :   // Calculate contribution from integral along bi
+     401           0 :   bead.set( 0, len_bi, sigma );
+     402           0 :   double upos=dotProduct( datom, bi );
+     403           0 :   ucontr=bead.calculate( upos, uder );
+     404           0 :   double udlen=bead.uboundDerivative( upos );
+     405           0 :   double uder2 = bead.lboundDerivative( upos ) - udlen;
+     406             : 
+     407             :   // Calculate contribution from integral along cross
+     408           0 :   bead.set( 0, len_cross, sigma );
+     409           0 :   double vpos=dotProduct( datom, cross );
+     410           0 :   vcontr=bead.calculate( vpos, vder );
+     411           0 :   double vdlen=bead.uboundDerivative( vpos );
+     412           0 :   double vder2 = bead.lboundDerivative( vpos ) - vdlen;
+     413             : 
+     414             :   // Calculate contribution from integral along perp
+     415           0 :   bead.set( 0, len_perp, sigma );
+     416           0 :   double wpos=dotProduct( datom, perp );
+     417           0 :   wcontr=bead.calculate( wpos, wder );
+     418           0 :   double wdlen=bead.uboundDerivative( wpos );
+     419           0 :   double wder2 = bead.lboundDerivative( wpos ) - wdlen;
+     420             : 
+     421           0 :   Vector dfd; dfd[0]=uder*vcontr*wcontr; dfd[1]=ucontr*vder*wcontr; dfd[2]=ucontr*vcontr*wder;
+     422           0 :   derivatives[0] = (dfd[0]*bi[0]+dfd[1]*cross[0]+dfd[2]*perp[0]);
+     423           0 :   derivatives[1] = (dfd[0]*bi[1]+dfd[1]*cross[1]+dfd[2]*perp[1]);
+     424           0 :   derivatives[2] = (dfd[0]*bi[2]+dfd[1]*cross[2]+dfd[2]*perp[2]);
+     425           0 :   double tot = ucontr*vcontr*wcontr*jacob_det;
+     426             : 
+     427             :   // Add reference atom derivatives
+     428           0 :   dfd[0]=uder2*vcontr*wcontr; dfd[1]=ucontr*vder2*wcontr; dfd[2]=ucontr*vcontr*wder2;
+     429           0 :   Vector dfld; dfld[0]=udlen*vcontr*wcontr; dfld[1]=ucontr*vdlen*wcontr; dfld[2]=ucontr*vcontr*wdlen;
+     430           0 :   rderiv[0] = dfd[0]*matmul(datom,dbi[0]) + dfd[1]*matmul(datom,dcross[0]) + dfd[2]*matmul(datom,dperp[0]) +
+     431           0 :               dfld[0]*dlbi[0] + dfld[1]*dlcross[0] + dfld[2]*dlperp[0] - derivatives;
+     432           0 :   rderiv[1] = dfd[0]*matmul(datom,dbi[1]) + dfd[1]*matmul(datom,dcross[1]) + dfd[2]*matmul(datom,dperp[1]) +
+     433           0 :               dfld[0]*dlbi[1] + dfld[1]*dlcross[1] + dfld[2]*dlperp[1];
+     434           0 :   rderiv[2] = dfd[0]*matmul(datom,dbi[2]) + dfd[1]*matmul(datom,dcross[2]) + dfd[2]*matmul(datom,dperp[2]) +
+     435           0 :               dfld[0]*dlbi[2] + dfld[1]*dlcross[2] + dfld[2]*dlperp[2];
+     436           0 :   rderiv[3] = dfld[0]*dlbi[3] + dfld[1]*dlcross[3] + dfld[2]*dlperp[3];
+     437             : 
+     438           0 :   vir.zero(); vir-=Tensor( cpos,derivatives );
+     439           0 :   for(unsigned i=0; i<4; ++i) {
+     440           0 :     vir -= Tensor( getPosition(i), rderiv[i] );
+     441             :   }
+     442             : 
+     443           0 :   return tot;
+     444             : }
+     445             : 
+     446             : }
+     447             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..81c26105e0 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + 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:505198.0 %
Date:2024-06-10 08:19:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe1006createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar7XAnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe996createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe1016createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar7XAngles10isPeriodicEv3
_ZN4PLMD11multicolvar7XAnglesC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar7XAngles16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD11multicolvar7XAngles7computeERKjRNS0_13AtomValuePackE50
_ZNK4PLMD11multicolvar7XAngles15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe99C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe99D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe100C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe100D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe101C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe101D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.func.html b/coverage/multicolvar/XAngle.cpp.func.html new file mode 100644 index 0000000000..31373a4b0d --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + 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:505198.0 %
Date:2024-06-10 08:19:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe996createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe99C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe99D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe1006createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe100C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe100D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe1016createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe101C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe101D2Ev3473
_ZN4PLMD11multicolvar7XAngles10isPeriodicEv3
_ZN4PLMD11multicolvar7XAngles16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar7XAnglesC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar7XAnglesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar7XAngles15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZNK4PLMD11multicolvar7XAngles7computeERKjRNS0_13AtomValuePackE50
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.gcov.html b/coverage/multicolvar/XAngle.cpp.gcov.html new file mode 100644 index 0000000000..8fe08eff5e --- /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:505198.0 %
Date:2024-06-10 08:19:14Functions:131586.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/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       10421 : PLUMED_REGISTER_ACTION(XAngles,"XANGLES")
+     100       10419 : PLUMED_REGISTER_ACTION(XAngles,"YANGLES")
+     101       10423 : PLUMED_REGISTER_ACTION(XAngles,"ZANGLES")
+     102             : 
+     103           6 : void XAngles::registerKeywords( Keywords& keys ) {
+     104           6 :   MultiColvarBase::registerKeywords( keys );
+     105          12 :   keys.use("MAX"); keys.use("ALT_MIN");
+     106          18 :   keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN");
+     107          12 :   keys.use("LOWEST"); keys.use("HIGHEST");
+     108          24 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     109          12 :   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          12 :   keys.reset_style("ATOMS","atoms");
+     115          12 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     116          12 :   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          12 :   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          12 :   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           6 : }
+     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.15
+
+ + + 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 0000000000..aaa3a85c46 --- /dev/null +++ b/coverage/multicolvar/XDistances.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + 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:153641.7 %
Date:2024-06-10 08:19:14Functions:71450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10XDistances10isPeriodicEv0
_ZN4PLMD11multicolvar10XDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar10XDistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe1856createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe1866createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe1876createERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar10XDistances7computeERKjRNS0_13AtomValuePackE0
_ZN4PLMD11multicolvar10XDistances16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe185C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe185D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe186C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe186D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe187C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe187D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/XDistances.cpp.func.html b/coverage/multicolvar/XDistances.cpp.func.html new file mode 100644 index 0000000000..c780d594f0 --- /dev/null +++ b/coverage/multicolvar/XDistances.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + 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:153641.7 %
Date:2024-06-10 08:19:14Functions:71450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10XDistances10isPeriodicEv0
_ZN4PLMD11multicolvar10XDistances16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar10XDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar10XDistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe1856createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe185C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe185D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe1866createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe186C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe186D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe1876createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe187C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe187D2Ev3473
_ZNK4PLMD11multicolvar10XDistances7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/XDistances.cpp.gcov.html b/coverage/multicolvar/XDistances.cpp.gcov.html new file mode 100644 index 0000000000..acf0335ff1 --- /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:153641.7 %
Date:2024-06-10 08:19:14Functions:71450.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           0 :   bool isPeriodic() override { return false; }
+     183             : };
+     184             : 
+     185       10419 : PLUMED_REGISTER_ACTION(XDistances,"XDISTANCES")
+     186       10419 : PLUMED_REGISTER_ACTION(XDistances,"YDISTANCES")
+     187       10419 : PLUMED_REGISTER_ACTION(XDistances,"ZDISTANCES")
+     188             : 
+     189           3 : void XDistances::registerKeywords( Keywords& keys ) {
+     190           3 :   MultiColvarBase::registerKeywords( keys );
+     191           6 :   keys.use("MAX"); keys.use("ALT_MIN");
+     192           9 :   keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN");
+     193           6 :   keys.use("LOWEST"); keys.use("HIGHEST");
+     194          12 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     195           6 :   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           6 :   keys.reset_style("ATOMS","atoms");
+     201           6 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     202           6 :   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           6 :   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           3 : }
+     207             : 
+     208           0 : XDistances::XDistances(const ActionOptions&ao):
+     209             :   Action(ao),
+     210           0 :   MultiColvarBase(ao)
+     211             : {
+     212           0 :   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           0 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     220           0 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     221           0 :   setupMultiColvarBase( all_atoms );
+     222             :   // And check everything has been read in correctly
+     223           0 :   checkRead();
+     224           0 : }
+     225             : 
+     226           0 : double XDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     227           0 :   Vector distance;
+     228           0 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     229           0 :   const double value=distance[myc];
+     230             : 
+     231           0 :   Vector myvec; myvec.zero();
+     232             :   // And finish the calculation
+     233           0 :   myvec[myc]=+1; addAtomDerivatives( 1, 1, myvec, myatoms );
+     234           0 :   myvec[myc]=-1; addAtomDerivatives( 1, 0, myvec, myatoms );
+     235           0 :   myatoms.addBoxDerivatives( 1, Tensor(distance,myvec) );
+     236           0 :   return value;
+     237             : }
+     238             : 
+     239             : }
+     240             : }
+     241             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ef26510c77 --- /dev/null +++ b/coverage/multicolvar/XYDistances.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + 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:143935.9 %
Date:2024-06-10 08:19:14Functions:71450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11XYDistances10isPeriodicEv0
_ZN4PLMD11multicolvar11XYDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11XYDistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe1106createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe1116createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe1126createERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar11XYDistances7computeERKjRNS0_13AtomValuePackE0
_ZN4PLMD11multicolvar11XYDistances16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe110C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe110D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe111C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe111D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe112C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe112D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/XYDistances.cpp.func.html b/coverage/multicolvar/XYDistances.cpp.func.html new file mode 100644 index 0000000000..6b0139e91b --- /dev/null +++ b/coverage/multicolvar/XYDistances.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + 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:143935.9 %
Date:2024-06-10 08:19:14Functions:71450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11XYDistances10isPeriodicEv0
_ZN4PLMD11multicolvar11XYDistances16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar11XYDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11XYDistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe1106createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe110C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe110D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe1116createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe111C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe111D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe1126createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe112C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe112D2Ev3473
_ZNK4PLMD11multicolvar11XYDistances7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/XYDistances.cpp.gcov.html b/coverage/multicolvar/XYDistances.cpp.gcov.html new file mode 100644 index 0000000000..41152de035 --- /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:143935.9 %
Date:2024-06-10 08:19:14Functions:71450.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       10419 : PLUMED_REGISTER_ACTION(XYDistances,"XYDISTANCES")
+     111       10419 : PLUMED_REGISTER_ACTION(XYDistances,"XZDISTANCES")
+     112       10419 : PLUMED_REGISTER_ACTION(XYDistances,"YZDISTANCES")
+     113             : 
+     114           3 : void XYDistances::registerKeywords( Keywords& keys ) {
+     115           3 :   MultiColvarBase::registerKeywords( keys );
+     116           6 :   keys.use("MAX"); keys.use("ALT_MIN");
+     117          15 :   keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     118          12 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     119           6 :   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           6 :   keys.reset_style("ATOMS","atoms");
+     125           6 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     126           6 :   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           6 :   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           3 : }
+     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.15
+
+ + + 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 0000000000..dd6d152365 --- /dev/null +++ b/coverage/multicolvar/XYTorsion.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + 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:585998.3 %
Date:2024-06-10 08:19:14Functions:202580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1496createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1506createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1516createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1526createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar9XYTorsionC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1546createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar9XYTorsion14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1536createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar9XYTorsion10isPeriodicEv3
_ZN4PLMD11multicolvar9XYTorsionC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar9XYTorsion16registerKeywordsERNS_8KeywordsE9
_ZNK4PLMD11multicolvar9XYTorsion7computeERKjRNS0_13AtomValuePackE50
_ZNK4PLMD11multicolvar9XYTorsion15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe149C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe149D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe150C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe150D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe151C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe151D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe152C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe152D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe153C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe153D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe154C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe154D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/XYTorsion.cpp.func.html b/coverage/multicolvar/XYTorsion.cpp.func.html new file mode 100644 index 0000000000..025302173f --- /dev/null +++ b/coverage/multicolvar/XYTorsion.cpp.func.html @@ -0,0 +1,173 @@ + + + + + + + + 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:585998.3 %
Date:2024-06-10 08:19:14Functions:202580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1496createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe149C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe149D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1506createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe150C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe150D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1516createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe151C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe151D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1526createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe152C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe152D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1536createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe153C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe153D2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1546createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe154C2Ev3473
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe154D2Ev3473
_ZN4PLMD11multicolvar9XYTorsion10isPeriodicEv3
_ZN4PLMD11multicolvar9XYTorsion14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1
_ZN4PLMD11multicolvar9XYTorsion16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD11multicolvar9XYTorsionC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar9XYTorsionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar9XYTorsion15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZNK4PLMD11multicolvar9XYTorsion7computeERKjRNS0_13AtomValuePackE50
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/XYTorsion.cpp.gcov.html b/coverage/multicolvar/XYTorsion.cpp.gcov.html new file mode 100644 index 0000000000..91c03c423c --- /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:585998.3 %
Date:2024-06-10 08:19:14Functions:202580.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/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       10419 : PLUMED_REGISTER_ACTION(XYTorsion,"XYTORSIONS")
+     150       10419 : PLUMED_REGISTER_ACTION(XYTorsion,"XZTORSIONS")
+     151       10419 : PLUMED_REGISTER_ACTION(XYTorsion,"YXTORSIONS")
+     152       10419 : PLUMED_REGISTER_ACTION(XYTorsion,"YZTORSIONS")
+     153       10423 : PLUMED_REGISTER_ACTION(XYTorsion,"ZXTORSIONS")
+     154       10421 : PLUMED_REGISTER_ACTION(XYTorsion,"ZYTORSIONS")
+     155             : 
+     156           9 : void XYTorsion::registerKeywords( Keywords& keys ) {
+     157           9 :   MultiColvarBase::registerKeywords( keys );
+     158          18 :   keys.use("MAX"); keys.use("ALT_MIN");
+     159          18 :   keys.use("MEAN"); keys.use("MIN");
+     160          18 :   keys.use("LOWEST"); keys.use("HIGHEST");
+     161          27 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     162          18 :   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          18 :   keys.reset_style("ATOMS","atoms");
+     168          18 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     169          18 :   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          18 :   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          18 :   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           9 : }
+     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.15
+
+ + + diff --git a/coverage/multicolvar/index-sort-f.html b/coverage/multicolvar/index-sort-f.html new file mode 100644 index 0000000000..406ab09a69 --- /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:2379302878.6 %
Date:2024-06-10 08:19:14Functions:32942278.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
VolumeTetrapore.cpp +
3.4%3.4%
+
3.4 %8 / 23225.0 %3 / 12
VolumeBetweenContours.cpp +
14.0%14.0%
+
14.0 %7 / 5037.5 %3 / 8
InPlaneDistances.cpp +
21.3%21.3%
+
21.3 %10 / 4737.5 %3 / 8
XYDistances.cpp +
35.9%35.9%
+
35.9 %14 / 3950.0 %7 / 14
XDistances.cpp +
41.7%41.7%
+
41.7 %15 / 3650.0 %7 / 14
BridgedMultiColvarFunction.h +
52.2%52.2%
+
52.2 %12 / 2358.3 %7 / 12
MultiColvarFilter.cpp +
82.5%82.5%
+
82.5 %33 / 4066.7 %4 / 6
Density.cpp +
70.8%70.8%
+
70.8 %17 / 2466.7 %8 / 12
VolumeGradientBase.cpp +
79.3%79.3%
+
79.3 %46 / 5875.0 %6 / 8
DihedralCorrelation.cpp +
98.0%98.0%
+
98.0 %49 / 5075.0 %6 / 8
Bridge.cpp +
79.2%79.2%
+
79.2 %42 / 5375.0 %6 / 8
AlphaBeta.cpp +
87.9%87.9%
+
87.9 %51 / 5875.0 %6 / 8
DumpMultiColvar.cpp +
93.1%93.1%
+
93.1 %67 / 7276.9 %10 / 13
NumberOfLinks.cpp +
89.5%89.5%
+
89.5 %51 / 5777.8 %7 / 9
ActionVolume.cpp +
100.0%
+
100.0 %39 / 3980.0 %4 / 5
MultiColvarBase.h +
85.2%85.2%
+
85.2 %23 / 2780.0 %8 / 10
FilterLessThan.cpp +
81.5%81.5%
+
81.5 %22 / 2780.0 %8 / 10
LocalAverage.cpp +
79.3%79.3%
+
79.3 %107 / 13580.0 %8 / 10
FilterBetween.cpp +
82.8%82.8%
+
82.8 %24 / 2980.0 %8 / 10
XYTorsion.cpp +
98.3%98.3%
+
98.3 %58 / 5980.0 %20 / 25
BridgedMultiColvarFunction.cpp +
92.9%92.9%
+
92.9 %52 / 5681.8 %9 / 11
MultiColvarDensity.cpp +
83.5%83.5%
+
83.5 %116 / 13983.3 %10 / 12
VolumeCavity.cpp +
79.4%79.4%
+
79.4 %170 / 21483.3 %10 / 12
DistanceFromContour.cpp +
86.3%86.3%
+
86.3 %132 / 15384.6 %11 / 13
CenterOfMultiColvar.cpp +
96.3%96.3%
+
96.3 %78 / 8185.7 %6 / 7
XAngle.cpp +
98.0%98.0%
+
98.0 %50 / 5186.7 %13 / 15
MultiColvarCombine.cpp +
100.0%
+
100.0 %31 / 3187.5 %7 / 8
VolumeAround.cpp +
100.0%
+
100.0 %48 / 4887.5 %7 / 8
VolumeInSphere.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
MultiColvarProduct.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
Distances.cpp +
95.6%95.6%
+
95.6 %43 / 4587.5 %7 / 8
CoordinationNumbers.cpp +
100.0%
+
100.0 %50 / 5087.5 %7 / 8
VolumeInCylinder.cpp +
95.9%95.9%
+
95.9 %47 / 4987.5 %7 / 8
Angles.cpp +
84.0%84.0%
+
84.0 %63 / 7588.9 %8 / 9
Torsions.cpp +
100.0%
+
100.0 %33 / 3388.9 %8 / 9
FilterMoreThan.cpp +
81.5%81.5%
+
81.5 %22 / 2790.0 %9 / 10
MultiColvarBase.cpp +
89.4%89.4%
+
89.4 %583 / 65297.6 %40 / 41
ActionVolume.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
CatomPack.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
MultiColvarFilter.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
VolumeGradientBase.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
CatomPack.h +
88.9%88.9%
+
88.9 %8 / 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.15
+
+ + + diff --git a/coverage/multicolvar/index-sort-l.html b/coverage/multicolvar/index-sort-l.html new file mode 100644 index 0000000000..c1c92f4a7b --- /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:2379302878.6 %
Date:2024-06-10 08:19:14Functions:32942278.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
VolumeTetrapore.cpp +
3.4%3.4%
+
3.4 %8 / 23225.0 %3 / 12
VolumeBetweenContours.cpp +
14.0%14.0%
+
14.0 %7 / 5037.5 %3 / 8
InPlaneDistances.cpp +
21.3%21.3%
+
21.3 %10 / 4737.5 %3 / 8
XYDistances.cpp +
35.9%35.9%
+
35.9 %14 / 3950.0 %7 / 14
XDistances.cpp +
41.7%41.7%
+
41.7 %15 / 3650.0 %7 / 14
BridgedMultiColvarFunction.h +
52.2%52.2%
+
52.2 %12 / 2358.3 %7 / 12
Density.cpp +
70.8%70.8%
+
70.8 %17 / 2466.7 %8 / 12
Bridge.cpp +
79.2%79.2%
+
79.2 %42 / 5375.0 %6 / 8
LocalAverage.cpp +
79.3%79.3%
+
79.3 %107 / 13580.0 %8 / 10
VolumeGradientBase.cpp +
79.3%79.3%
+
79.3 %46 / 5875.0 %6 / 8
VolumeCavity.cpp +
79.4%79.4%
+
79.4 %170 / 21483.3 %10 / 12
FilterMoreThan.cpp +
81.5%81.5%
+
81.5 %22 / 2790.0 %9 / 10
FilterLessThan.cpp +
81.5%81.5%
+
81.5 %22 / 2780.0 %8 / 10
MultiColvarFilter.cpp +
82.5%82.5%
+
82.5 %33 / 4066.7 %4 / 6
FilterBetween.cpp +
82.8%82.8%
+
82.8 %24 / 2980.0 %8 / 10
MultiColvarDensity.cpp +
83.5%83.5%
+
83.5 %116 / 13983.3 %10 / 12
Angles.cpp +
84.0%84.0%
+
84.0 %63 / 7588.9 %8 / 9
MultiColvarBase.h +
85.2%85.2%
+
85.2 %23 / 2780.0 %8 / 10
DistanceFromContour.cpp +
86.3%86.3%
+
86.3 %132 / 15384.6 %11 / 13
AlphaBeta.cpp +
87.9%87.9%
+
87.9 %51 / 5875.0 %6 / 8
CatomPack.h +
88.9%88.9%
+
88.9 %8 / 9100.0 %2 / 2
NumberOfLinks.cpp +
89.5%89.5%
+
89.5 %51 / 5777.8 %7 / 9
MultiColvarBase.cpp +
89.4%89.4%
+
89.4 %583 / 65297.6 %40 / 41
BridgedMultiColvarFunction.cpp +
92.9%92.9%
+
92.9 %52 / 5681.8 %9 / 11
DumpMultiColvar.cpp +
93.1%93.1%
+
93.1 %67 / 7276.9 %10 / 13
AtomValuePack.h +
95.1%95.1%
+
95.1 %39 / 41100.0 %7 / 7
Distances.cpp +
95.6%95.6%
+
95.6 %43 / 4587.5 %7 / 8
VolumeInCylinder.cpp +
95.9%95.9%
+
95.9 %47 / 4987.5 %7 / 8
CenterOfMultiColvar.cpp +
96.3%96.3%
+
96.3 %78 / 8185.7 %6 / 7
DihedralCorrelation.cpp +
98.0%98.0%
+
98.0 %49 / 5075.0 %6 / 8
XAngle.cpp +
98.0%98.0%
+
98.0 %50 / 5186.7 %13 / 15
XYTorsion.cpp +
98.3%98.3%
+
98.3 %58 / 5980.0 %20 / 25
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 %9 / 9100.0 %1 / 1
VolumeInSphere.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
MultiColvarProduct.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
MultiColvarCombine.cpp +
100.0%
+
100.0 %31 / 3187.5 %7 / 8
Torsions.cpp +
100.0%
+
100.0 %33 / 3388.9 %8 / 9
ActionVolume.cpp +
100.0%
+
100.0 %39 / 3980.0 %4 / 5
VolumeAround.cpp +
100.0%
+
100.0 %48 / 4887.5 %7 / 8
AtomValuePack.cpp +
100.0%
+
100.0 %49 / 49100.0 %4 / 4
CoordinationNumbers.cpp +
100.0%
+
100.0 %50 / 5087.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/multicolvar/index.html b/coverage/multicolvar/index.html new file mode 100644 index 0000000000..85bb72a15d --- /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:2379302878.6 %
Date:2024-06-10 08:19:14Functions:32942278.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.9%87.9%
+
87.9 %51 / 5875.0 %6 / 8
Angles.cpp +
84.0%84.0%
+
84.0 %63 / 7588.9 %8 / 9
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 +
79.2%79.2%
+
79.2 %42 / 5375.0 %6 / 8
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 +
88.9%88.9%
+
88.9 %8 / 9100.0 %2 / 2
CenterOfMultiColvar.cpp +
96.3%96.3%
+
96.3 %78 / 8185.7 %6 / 7
CoordinationNumbers.cpp +
100.0%
+
100.0 %50 / 5087.5 %7 / 8
Density.cpp +
70.8%70.8%
+
70.8 %17 / 2466.7 %8 / 12
DihedralCorrelation.cpp +
98.0%98.0%
+
98.0 %49 / 5075.0 %6 / 8
DistanceFromContour.cpp +
86.3%86.3%
+
86.3 %132 / 15384.6 %11 / 13
Distances.cpp +
95.6%95.6%
+
95.6 %43 / 4587.5 %7 / 8
DumpMultiColvar.cpp +
93.1%93.1%
+
93.1 %67 / 7276.9 %10 / 13
FilterBetween.cpp +
82.8%82.8%
+
82.8 %24 / 2980.0 %8 / 10
FilterLessThan.cpp +
81.5%81.5%
+
81.5 %22 / 2780.0 %8 / 10
FilterMoreThan.cpp +
81.5%81.5%
+
81.5 %22 / 2790.0 %9 / 10
InPlaneDistances.cpp +
21.3%21.3%
+
21.3 %10 / 4737.5 %3 / 8
LocalAverage.cpp +
79.3%79.3%
+
79.3 %107 / 13580.0 %8 / 10
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 %31 / 3187.5 %7 / 8
MultiColvarDensity.cpp +
83.5%83.5%
+
83.5 %116 / 13983.3 %10 / 12
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 %26 / 2687.5 %7 / 8
NumberOfLinks.cpp +
89.5%89.5%
+
89.5 %51 / 5777.8 %7 / 9
Torsions.cpp +
100.0%
+
100.0 %33 / 3388.9 %8 / 9
VolumeAround.cpp +
100.0%
+
100.0 %48 / 4887.5 %7 / 8
VolumeBetweenContours.cpp +
14.0%14.0%
+
14.0 %7 / 5037.5 %3 / 8
VolumeCavity.cpp +
79.4%79.4%
+
79.4 %170 / 21483.3 %10 / 12
VolumeGradientBase.cpp +
79.3%79.3%
+
79.3 %46 / 5875.0 %6 / 8
VolumeGradientBase.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
VolumeInCylinder.cpp +
95.9%95.9%
+
95.9 %47 / 4987.5 %7 / 8
VolumeInSphere.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
VolumeTetrapore.cpp +
3.4%3.4%
+
3.4 %8 / 23225.0 %3 / 12
XAngle.cpp +
98.0%98.0%
+
98.0 %50 / 5186.7 %13 / 15
XDistances.cpp +
41.7%41.7%
+
41.7 %15 / 3650.0 %7 / 14
XYDistances.cpp +
35.9%35.9%
+
35.9 %14 / 3950.0 %7 / 14
XYTorsion.cpp +
98.3%98.3%
+
98.3 %58 / 5980.0 %20 / 25
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..bd96669fe4 --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + 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:9310192.1 %
Date:2024-06-10 08:19:14Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVcustomC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes9ECVcustom15initECVs_observERKSt6vectorIdSaIdEEjj1
_ZN4PLMD4opes9ECVcustom16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe856createERKNS_13ActionOptionsE2
_ZN4PLMD4opes9ECVcustom8initECVsEv2
_ZN4PLMD4opes9ECVcustomC1ERKNS_13ActionOptionsE2
_ZNK4PLMD4opes9ECVcustom10getIndex_kEv2
_ZNK4PLMD4opes9ECVcustom10getLambdasB5cxx11Ev2
_ZN4PLMD4opes9ECVcustom16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4opes9ECVcustom13getPntrToECVsEj4
_ZN4PLMD4opes9ECVcustom16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVcustom13calculateECVsEPKd91
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe85C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe85D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.func.html b/coverage/opes/ECVcustom.cpp.func.html new file mode 100644 index 0000000000..86634dec0e --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + 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:9310192.1 %
Date:2024-06-10 08:19:14Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe856createERKNS_13ActionOptionsE2
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe85C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe85D2Ev3473
_ZN4PLMD4opes9ECVcustom13calculateECVsEPKd91
_ZN4PLMD4opes9ECVcustom13getPntrToECVsEj4
_ZN4PLMD4opes9ECVcustom15initECVs_observERKSt6vectorIdSaIdEEjj1
_ZN4PLMD4opes9ECVcustom16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVcustom16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVcustom16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4opes9ECVcustom8initECVsEv2
_ZN4PLMD4opes9ECVcustomC1ERKNS_13ActionOptionsE2
_ZN4PLMD4opes9ECVcustomC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes9ECVcustom10getIndex_kEv2
_ZNK4PLMD4opes9ECVcustom10getLambdasB5cxx11Ev2
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.gcov.html b/coverage/opes/ECVcustom.cpp.gcov.html new file mode 100644 index 0000000000..6f53636ded --- /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:9310192.1 %
Date:2024-06-10 08:19:14Functions:131492.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       10423 : PLUMED_REGISTER_ACTION(ECVcustom,"ECV_CUSTOM")
+      86             : 
+      87           3 : void ECVcustom::registerKeywords(Keywords& keys)
+      88             : {
+      89           3 :   ExpansionCVs::registerKeywords(keys);
+      90           3 :   keys.remove("ARG");
+      91           6 :   keys.add("compulsory","ARG","the labels of the single ECVs, \\f$\\Delta U_i\\f$, in energy units");
+      92           6 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+      93           6 :   keys.addFlag("DIMENSIONLESS",false,"consider ARG as dimensionless rather than an energy, thus do not multiply it by \\f$\\beta\\f$");
+      94           6 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+      95           3 : }
+      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.15
+
+ + + 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 0000000000..78f0eae4a0 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:11512095.8 %
Date:2024-06-10 08:19:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVlinearC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes9ECVlinear16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVlinear15initECVs_observERKSt6vectorIdSaIdEEjj3
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe956createERKNS_13ActionOptionsE4
_ZN4PLMD4opes9ECVlinear13getPntrToECVsEj4
_ZN4PLMD4opes9ECVlinear16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVlinear8initECVsEv4
_ZN4PLMD4opes9ECVlinearC1ERKNS_13ActionOptionsE4
_ZNK4PLMD4opes9ECVlinear10getLambdasB5cxx11Ev4
_ZN4PLMD4opes9ECVlinear16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4opes9ECVlinear13calculateECVsEPKd182
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe95C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe95D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.func.html b/coverage/opes/ECVlinear.cpp.func.html new file mode 100644 index 0000000000..0fae7c80e8 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:11512095.8 %
Date:2024-06-10 08:19:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe956createERKNS_13ActionOptionsE4
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe95C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe95D2Ev3473
_ZN4PLMD4opes9ECVlinear13calculateECVsEPKd182
_ZN4PLMD4opes9ECVlinear13getPntrToECVsEj4
_ZN4PLMD4opes9ECVlinear15initECVs_observERKSt6vectorIdSaIdEEjj3
_ZN4PLMD4opes9ECVlinear16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVlinear16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVlinear16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4opes9ECVlinear8initECVsEv4
_ZN4PLMD4opes9ECVlinearC1ERKNS_13ActionOptionsE4
_ZN4PLMD4opes9ECVlinearC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes9ECVlinear10getLambdasB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.gcov.html b/coverage/opes/ECVlinear.cpp.gcov.html new file mode 100644 index 0000000000..7eb4523f06 --- /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:11512095.8 %
Date:2024-06-10 08:19:14Functions: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 "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       10427 : PLUMED_REGISTER_ACTION(ECVlinear,"ECV_LINEAR")
+      96             : 
+      97           5 : void ECVlinear::registerKeywords(Keywords& keys)
+      98             : {
+      99           5 :   ExpansionCVs::registerKeywords(keys);
+     100           5 :   keys.remove("ARG");
+     101          10 :   keys.add("compulsory","ARG","the label of the Hamiltonian difference \\f$\\Delta U\\f$");
+     102          10 :   keys.add("compulsory","LAMBDA","0","the lambda at which the underlying simulation runs");
+     103          10 :   keys.add("optional","LAMBDA_MIN","( default=0 ) the minimum of the lambda range");
+     104          10 :   keys.add("optional","LAMBDA_MAX","( default=1 ) the maximum of the lambda range");
+     105          10 :   keys.add("optional","LAMBDA_STEPS","uniformly place the lambda values, for a total of LAMBDA_STEPS");
+     106          10 :   keys.add("optional","LAMBDA_SET_ALL","manually set all the lamdbas");
+     107          10 :   keys.addFlag("DIMENSIONLESS",false,"ARG is considered dimensionless rather than an energy, thus is not multiplied by \\f$\\beta\\f$");
+     108          10 :   keys.addFlag("GEOM_SPACING",false,"use geometrical spacing in lambda instead of linear spacing");
+     109           5 : }
+     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.15
+
+ + + 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 0000000000..ee556f9cfa --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:10811395.6 %
Date:2024-06-10 08:19:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes15ECVmultiThermalC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes15ECVmultiThermal16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes15ECVmultiThermal15initECVs_observERKSt6vectorIdSaIdEEjj8
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe1036createERKNS_13ActionOptionsE11
_ZN4PLMD4opes15ECVmultiThermal13getPntrToECVsEj11
_ZN4PLMD4opes15ECVmultiThermal16getPntrToDerECVsEj11
_ZN4PLMD4opes15ECVmultiThermal8initECVsEv11
_ZN4PLMD4opes15ECVmultiThermalC1ERKNS_13ActionOptionsE11
_ZNK4PLMD4opes15ECVmultiThermal10getLambdasB5cxx11Ev11
_ZN4PLMD4opes15ECVmultiThermal16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4opes15ECVmultiThermal13calculateECVsEPKd586
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe103C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe103D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.func.html b/coverage/opes/ECVmultiThermal.cpp.func.html new file mode 100644 index 0000000000..2b5488605d --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:10811395.6 %
Date:2024-06-10 08:19:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe1036createERKNS_13ActionOptionsE11
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe103C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe103D2Ev3473
_ZN4PLMD4opes15ECVmultiThermal13calculateECVsEPKd586
_ZN4PLMD4opes15ECVmultiThermal13getPntrToECVsEj11
_ZN4PLMD4opes15ECVmultiThermal15initECVs_observERKSt6vectorIdSaIdEEjj8
_ZN4PLMD4opes15ECVmultiThermal16getPntrToDerECVsEj11
_ZN4PLMD4opes15ECVmultiThermal16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes15ECVmultiThermal16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD4opes15ECVmultiThermal8initECVsEv11
_ZN4PLMD4opes15ECVmultiThermalC1ERKNS_13ActionOptionsE11
_ZN4PLMD4opes15ECVmultiThermalC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes15ECVmultiThermal10getLambdasB5cxx11Ev11
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.gcov.html b/coverage/opes/ECVmultiThermal.cpp.gcov.html new file mode 100644 index 0000000000..ddd487f87f --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.gcov.html @@ -0,0 +1,347 @@ + + + + + + + + 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:10811395.6 %
Date:2024-06-10 08:19:14Functions: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 "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : #include "core/PlumedMain.h"
+      22             : #include "core/Atoms.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace opes {
+      26             : 
+      27             : //+PLUMEDOC OPES_EXPANSION_CV ECV_MULTITHERMAL
+      28             : /*
+      29             : Expand a simulation to sample multiple temperatures simultaneously.
+      30             : 
+      31             : The internal energy \f$U\f$ of of the system should be used as ARG.
+      32             : \f[
+      33             :   \Delta u_{\beta'}=(\beta'-\beta) U\, ,
+      34             : \f]
+      35             : where \f$\beta'\f$ are the temperatures to be sampled and \f$\beta\f$ is the temperature at which the simulation is conducted.
+      36             : 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.
+      37             : 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).
+      38             : 
+      39             : By defauly the needed steps in temperatures are automatically guessed from few initial unbiased MD steps, as descibed in \cite Invernizzi2020unified.
+      40             : Otherwise you can manually set this number with TEMP_STEPS.
+      41             : In both cases the steps will be geometrically spaced in temperature.
+      42             : Use instead the keyword NO_GEOM_SPACING for a linear spacing in the inverse temperature (beta), that typically increases the focus on lower temperatures.
+      43             : Finally, you can use instead the keyword TEMP_SET_ALL and explicitly provide each temperature.
+      44             : 
+      45             : You can reweight the resulting simulation at any temperature in the chosen range, using e.g. \ref REWEIGHT_TEMP_PRESS.
+      46             : A similar target distribution can be sampled using \ref TD_MULTICANONICAL.
+      47             : 
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : Fixed volume, multicanonical simulation:
+      52             : 
+      53             : \plumedfile
+      54             : ene: ENERGY
+      55             : ecv: ECV_MULTITHERMAL ARG=ene TEMP=300 TEMP_MIN=300 TEMP_MAX=800
+      56             : opes: OPES_EXPANDED ARG=ecv.ene PACE=500
+      57             : \endplumedfile
+      58             : 
+      59             : which, if your MD code passes the temperature to PLUMED, is equivalent to:
+      60             : 
+      61             : \plumedfile
+      62             : ene: ENERGY
+      63             : ecv: ECV_MULTITHERMAL ARG=ene TEMP_MAX=800
+      64             : opes: OPES_EXPANDED ARG=ecv.ene PACE=500
+      65             : \endplumedfile
+      66             : 
+      67             : If instead the pressure is fixed and the volume changes, you shuld calculate the internal energy first, \f$U=E+pV\f$
+      68             : 
+      69             : \plumedfile
+      70             : ene: ENERGY
+      71             : vol: VOLUME
+      72             : intEne: CUSTOM PERIODIC=NO ARG=ene,vol FUNC=x+0.06022140857*y
+      73             : ecv: ECV_MULTITHERMAL ARG=intEne TEMP_MAX=800
+      74             : opes: OPES_EXPANDED ARG=ecv.intEne PACE=500
+      75             : \endplumedfile
+      76             : 
+      77             : Notice that \f$p=0.06022140857\f$ corresponds to 1 bar when using the default PLUMED units.
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : class ECVmultiThermal :
+      83             :   public ExpansionCVs
+      84             : {
+      85             : private:
+      86             :   bool todoAutomatic_;
+      87             :   bool geom_spacing_;
+      88             :   std::vector<double> ECVs_;
+      89             :   std::vector<double> derECVs_; //(beta_k-beta0) or (temp0/temp_k-1)/kbt
+      90             :   void initECVs();
+      91             : 
+      92             : public:
+      93             :   explicit ECVmultiThermal(const ActionOptions&);
+      94             :   static void registerKeywords(Keywords& keys);
+      95             :   void calculateECVs(const double *) override;
+      96             :   const double * getPntrToECVs(unsigned) override;
+      97             :   const double * getPntrToDerECVs(unsigned) override;
+      98             :   std::vector<std::string> getLambdas() const override;
+      99             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+     100             :   void initECVs_restart(const std::vector<std::string>&) override;
+     101             : };
+     102             : 
+     103       10441 : PLUMED_REGISTER_ACTION(ECVmultiThermal,"ECV_MULTITHERMAL")
+     104             : 
+     105          12 : void ECVmultiThermal::registerKeywords(Keywords& keys)
+     106             : {
+     107          12 :   ExpansionCVs::registerKeywords(keys);
+     108          12 :   keys.remove("ARG");
+     109          24 :   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");
+     110          24 :   keys.add("optional","TEMP_MIN","the minimum of the temperature range");
+     111          24 :   keys.add("optional","TEMP_MAX","the maximum of the temperature range");
+     112          24 :   keys.add("optional","TEMP_STEPS","the number of steps in temperature");
+     113          24 :   keys.add("optional","TEMP_SET_ALL","manually set all the temperatures");
+     114          24 :   keys.addFlag("NO_GEOM_SPACING",false,"do not use geometrical spacing in temperature, but instead linear spacing in inverse temperature");
+     115          12 : }
+     116             : 
+     117          11 : ECVmultiThermal::ECVmultiThermal(const ActionOptions&ao)
+     118             :   : Action(ao)
+     119             :   , ExpansionCVs(ao)
+     120          11 :   , todoAutomatic_(false)
+     121             : {
+     122          11 :   plumed_massert(getNumberOfArguments()==1,"only the internal energy should be given as ARG");
+     123             : 
+     124             : //set temp0
+     125          11 :   const double temp0=kbt_/plumed.getAtoms().getKBoltzmann();
+     126             : 
+     127             : //parse temp range
+     128          11 :   double temp_min=-1;
+     129          11 :   double temp_max=-1;
+     130          11 :   parse("TEMP_MIN",temp_min);
+     131          11 :   parse("TEMP_MAX",temp_max);
+     132          11 :   unsigned temp_steps=0;
+     133          22 :   parse("TEMP_STEPS",temp_steps);
+     134             :   std::vector<double> temps;
+     135          11 :   parseVector("TEMP_SET_ALL",temps);
+     136          11 :   parseFlag("NO_GEOM_SPACING",geom_spacing_);
+     137          11 :   geom_spacing_=!geom_spacing_;
+     138             : 
+     139          11 :   checkRead();
+     140             : 
+     141             : //set the intermediate temperatures
+     142          11 :   if(temps.size()>0)
+     143             :   {
+     144           2 :     plumed_massert(temp_steps==0,"cannot set both TEMP_STEPS and TEMP_SET_ALL");
+     145           2 :     plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both TEMP_SET_ALL and TEMP_MIN/MAX");
+     146           2 :     plumed_massert(temps.size()>=2,"set at least 2 temperatures");
+     147           2 :     temp_min=temps[0];
+     148           2 :     temp_max=temps[temps.size()-1];
+     149           2 :     derECVs_.resize(temps.size());
+     150          10 :     for(unsigned k=0; k<derECVs_.size(); k++)
+     151             :     {
+     152           8 :       derECVs_[k]=(temp0/temps[k]-1.)/kbt_;
+     153           8 :       if(k<derECVs_.size()-1)
+     154           6 :         plumed_massert(temps[k]<=temps[k+1],"TEMP_SET_ALL must be properly ordered");
+     155             :     }
+     156             :   }
+     157             :   else
+     158             :   { //get TEMP_MIN and TEMP_MAX
+     159           9 :     plumed_massert(temp_min!=-1 || temp_max!=-1,"TEMP_MIN, TEMP_MAX or both, should be set");
+     160           9 :     if(temp_min==-1)
+     161             :     {
+     162           2 :       temp_min=temp0;
+     163           2 :       log.printf("  no TEMP_MIN provided, using TEMP_MIN=TEMP\n");
+     164             :     }
+     165           9 :     if(temp_max==-1)
+     166             :     {
+     167           0 :       temp_max=temp0;
+     168           0 :       log.printf("  no TEMP_MAX provided, using TEMP_MAX=TEMP\n");
+     169             :     }
+     170           9 :     plumed_massert(temp_max>=temp_min,"TEMP_MAX should be bigger than TEMP_MIN");
+     171           9 :     derECVs_.resize(2);
+     172           9 :     derECVs_[0]=(temp0/temp_min-1.)/kbt_;
+     173           9 :     derECVs_[1]=(temp0/temp_max-1.)/kbt_;
+     174           9 :     if(temp_min==temp_max && temp_steps==0)
+     175           0 :       temp_steps=1;
+     176           9 :     if(temp_steps>0)
+     177          14 :       derECVs_=getSteps(derECVs_[0],derECVs_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     178             :     else
+     179           2 :       todoAutomatic_=true;
+     180             :   }
+     181             :   const double tol=1e-3; //if temp is taken from MD engine it might be numerically slightly different
+     182          11 :   if(temp0<(1-tol)*temp_min || temp0>(1+tol)*temp_max)
+     183           0 :     log.printf(" +++ WARNING +++ running at TEMP=%g which is outside the chosen temperature range\n",temp0);
+     184             : 
+     185             : //print some info
+     186          11 :   log.printf("  targeting a temperature range from TEMP_MIN=%g to TEMP_MAX=%g\n",temp_min,temp_max);
+     187          11 :   if(!geom_spacing_)
+     188           1 :     log.printf(" -- NO_GEOM_SPACING: inverse temperatures will be linearly spaced\n");
+     189          11 : }
+     190             : 
+     191         586 : void ECVmultiThermal::calculateECVs(const double * ene)
+     192             : {
+     193        3618 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     194        3032 :     ECVs_[k]=derECVs_[k]*ene[0];
+     195             : // derivatives never change: derECVs_k=(beta_k-beta0)
+     196         586 : }
+     197             : 
+     198          11 : const double * ECVmultiThermal::getPntrToECVs(unsigned j)
+     199             : {
+     200          11 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     201          11 :   plumed_massert(j==0,getName()+" has only one CV, the ENERGY");
+     202          11 :   return &ECVs_[0];
+     203             : }
+     204             : 
+     205          11 : const double * ECVmultiThermal::getPntrToDerECVs(unsigned j)
+     206             : {
+     207          11 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     208          11 :   plumed_massert(j==0,getName()+" has only one CV, the ENERGY");
+     209          11 :   return &derECVs_[0];
+     210             : }
+     211             : 
+     212          11 : std::vector<std::string> ECVmultiThermal::getLambdas() const
+     213             : {
+     214          11 :   plumed_massert(!todoAutomatic_,"cannot access lambdas before initializing them");
+     215          11 :   const double temp0=kbt_/plumed.getAtoms().getKBoltzmann();
+     216          11 :   std::vector<std::string> lambdas(derECVs_.size());
+     217          70 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     218             :   {
+     219          59 :     std::ostringstream subs;
+     220          59 :     subs<<temp0/(derECVs_[k]*kbt_+1); //temp_k
+     221          59 :     lambdas[k]=subs.str();
+     222          59 :   }
+     223          11 :   return lambdas;
+     224           0 : }
+     225             : 
+     226          11 : void ECVmultiThermal::initECVs()
+     227             : {
+     228          11 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     229          11 :   plumed_massert(!todoAutomatic_,"this should not happen");
+     230          11 :   totNumECVs_=derECVs_.size();
+     231          11 :   ECVs_.resize(derECVs_.size());
+     232          11 :   isReady_=true;
+     233          11 :   log.printf("  *%4lu temperatures for %s\n",derECVs_.size(),getName().c_str());
+     234          11 : }
+     235             : 
+     236           8 : void ECVmultiThermal::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     237             : {
+     238           8 :   if(todoAutomatic_) //estimate the steps in beta from observations
+     239             :   {
+     240           1 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j<ncv,"initECVs_observ parameters are inconsistent");
+     241           1 :     std::vector<double> obs_ene(all_obs_cvs.size()/ncv); //copy only useful observation (would be better not to copy...)
+     242          11 :     for(unsigned t=0; t<obs_ene.size(); t++)
+     243          10 :       obs_ene[t]=all_obs_cvs[t*ncv+index_j];
+     244           1 :     const unsigned temp_steps=estimateNumSteps(derECVs_[0],derECVs_[1],obs_ene,"TEMP");
+     245           1 :     log.printf("    (spacing is in beta, not in temperature)\n");
+     246           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     247           1 :     todoAutomatic_=false;
+     248             :   }
+     249           8 :   initECVs();
+     250           8 :   calculateECVs(&all_obs_cvs[index_j]);
+     251           8 : }
+     252             : 
+     253           3 : void ECVmultiThermal::initECVs_restart(const std::vector<std::string>& lambdas)
+     254             : {
+     255           3 :   std::size_t pos=lambdas[0].find("_");
+     256           3 :   plumed_massert(pos==std::string::npos,"this should not happen, only one CV is used in "+getName());
+     257           3 :   if(todoAutomatic_)
+     258             :   {
+     259           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],lambdas.size(),"TEMP",geom_spacing_,1./kbt_);
+     260           1 :     todoAutomatic_=false;
+     261             :   }
+     262           3 :   std::vector<std::string> myLambdas=getLambdas();
+     263           3 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     264           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     265             : 
+     266           3 :   initECVs();
+     267           3 : }
+     268             : 
+     269             : }
+     270             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..291c9d42b4 --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + 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:26427396.7 %
Date:2024-06-10 08:19:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes20ECVmultiThermalBaricC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes20ECVmultiThermalBaric15initECVs_observERKSt6vectorIdSaIdEEjj6
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe1106createERKNS_13ActionOptionsE9
_ZN4PLMD4opes20ECVmultiThermalBaric8initECVsEv9
_ZN4PLMD4opes20ECVmultiThermalBaricC1ERKNS_13ActionOptionsE9
_ZNK4PLMD4opes20ECVmultiThermalBaric10getIndex_kEv9
_ZN4PLMD4opes20ECVmultiThermalBaric16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4opes20ECVmultiThermalBaric13getPntrToECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric16getPntrToDerECVsEj18
_ZNK4PLMD4opes20ECVmultiThermalBaric10getLambdasB5cxx11Ev18
_ZZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEENKUljE_clEj230
_ZN4PLMD4opes20ECVmultiThermalBaric13calculateECVsEPKd463
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe110C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe110D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.func.html b/coverage/opes/ECVmultiThermalBaric.cpp.func.html new file mode 100644 index 0000000000..347a79ad7e --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + 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:26427396.7 %
Date:2024-06-10 08:19:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe1106createERKNS_13ActionOptionsE9
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe110C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe110D2Ev3473
_ZN4PLMD4opes20ECVmultiThermalBaric13calculateECVsEPKd463
_ZN4PLMD4opes20ECVmultiThermalBaric13getPntrToECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric15initECVs_observERKSt6vectorIdSaIdEEjj6
_ZN4PLMD4opes20ECVmultiThermalBaric16getPntrToDerECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes20ECVmultiThermalBaric16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4opes20ECVmultiThermalBaric8initECVsEv9
_ZN4PLMD4opes20ECVmultiThermalBaricC1ERKNS_13ActionOptionsE9
_ZN4PLMD4opes20ECVmultiThermalBaricC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes20ECVmultiThermalBaric10getIndex_kEv9
_ZNK4PLMD4opes20ECVmultiThermalBaric10getLambdasB5cxx11Ev18
_ZZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEENKUljE_clEj230
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html b/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html new file mode 100644 index 0000000000..4f2ed853eb --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html @@ -0,0 +1,609 @@ + + + + + + + + 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:26427396.7 %
Date:2024-06-10 08:19:14Functions:141593.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 "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : #include "core/PlumedMain.h"
+      22             : #include "core/Atoms.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace opes {
+      26             : 
+      27             : //+PLUMEDOC OPES_EXPANSION_CV ECV_MULTITHERMAL_MULTIBARIC
+      28             : /*
+      29             : Expand a simulation to sample multiple temperatures and pressures.
+      30             : 
+      31             : The potential \ref ENERGY, \f$E\f$, and the \ref VOLUME, \f$V\f$, of the system should be used as ARG.
+      32             : \f[
+      33             :   \Delta u_{\beta',p'}=(\beta'-\beta) E + (\beta' p' -\beta p) V\, ,
+      34             : \f]
+      35             : 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.
+      36             : 
+      37             : 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$.
+      38             : 
+      39             : The TEMP_STEPS and PRESSURE_STEPS are automatically guessed from the initial unbiased steps (see OBSERVATION_STEPS in \ref OPES_EXPANDED), unless explicitly set.
+      40             : The algorithm for this guess is described in \cite Invernizzi2020unified should provide a rough estimate useful for most applications.
+      41             : The pressures are uniformely spaced, while the temperatures steps are geometrically spaced.
+      42             : Use instead the keyword NO_GEOM_SPACING for a linear spacing in inverse temperature (beta).
+      43             : For more detailed control you can use instead TEMP_SET_ALL and/or PRESSURE_SET_ALL to explicitly set all of them.
+      44             : The temperatures and pressures are then combined in a 2D grid.
+      45             : 
+      46             : You can use CUT_CORNER to avoid a high-temperature/low-pressure region.
+      47             : This can be useful e.g. to increase the temperature for greater ergodicity, while avoiding water to vaporize, as in Ref.\cite Invernizzi2020unified.
+      48             : 
+      49             : You can reweight the resulting simulation at any temperature and pressure in chosen target, using e.g. \ref REWEIGHT_TEMP_PRESS.
+      50             : A similar target distribution can be sampled using \ref TD_MULTITHERMAL_MULTIBARIC.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : \plumedfile
+      55             : ene: ENERGY
+      56             : vol: VOLUME
+      57             : ecv: ECV_MULTITHERMAL_MULTIBARIC ...
+      58             :   ARG=ene,vol
+      59             :   TEMP=500
+      60             :   TEMP_MIN=270
+      61             :   TEMP_MAX=800
+      62             :   PRESSURE=0.06022140857*2000 #2 kbar
+      63             :   PRESSURE_MIN=0.06022140857  #1 bar
+      64             :   PRESSURE_MAX=0.06022140857*4000 #4 kbar
+      65             :   CUT_CORNER=500,0.06022140857,800,0.06022140857*1000
+      66             : ...
+      67             : opes: OPES_EXPANDED ARG=ecv.* FILE=DeltaF.data PACE=500 WALKERS_MPI
+      68             : \endplumedfile
+      69             : 
+      70             : Notice that \f$p=0.06022140857\f$ corresponds to 1 bar only when using the default PLUMED units.
+      71             : If you modify them via the \ref UNITS command, then the pressure has to be rescaled accordingly.
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : class ECVmultiThermalBaric :
+      77             :   public ExpansionCVs
+      78             : {
+      79             : private:
+      80             :   bool todoAutomatic_beta_;
+      81             :   bool todoAutomatic_pres_;
+      82             :   bool geom_spacing_;
+      83             :   double pres0_;
+      84             :   std::vector<double> pres_;
+      85             :   std::vector<double> ECVs_beta_;
+      86             :   std::vector<double> ECVs_pres_;
+      87             :   std::vector<double> derECVs_beta_; //(beta_k-beta0) or (temp0/temp_k-1)/kbt
+      88             :   std::vector<double> derECVs_pres_; //(beta_k*pres_kk-beta0*pres0) or (temp0/temp_k*pres_kk-pres0)/kbt
+      89             :   void initECVs();
+      90             : 
+      91             : //CUT_CORNER stuff
+      92             :   double coeff_;
+      93             :   double pres_low_;
+      94             :   double kB_temp_low_;
+      95             : //SET_ALL_TEMP_PRESSURE stuff
+      96             :   std::vector<std::string> custom_lambdas_;
+      97             : 
+      98             : public:
+      99             :   explicit ECVmultiThermalBaric(const ActionOptions&);
+     100             :   static void registerKeywords(Keywords& keys);
+     101             :   void calculateECVs(const double *) override;
+     102             :   const double * getPntrToECVs(unsigned) override;
+     103             :   const double * getPntrToDerECVs(unsigned) override;
+     104             :   std::vector< std::vector<unsigned> > getIndex_k() const override;
+     105             :   std::vector<std::string> getLambdas() const override;
+     106             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+     107             :   void initECVs_restart(const std::vector<std::string>&) override;
+     108             : };
+     109             : 
+     110       10437 : PLUMED_REGISTER_ACTION(ECVmultiThermalBaric,"ECV_MULTITHERMAL_MULTIBARIC")
+     111             : 
+     112          10 : void ECVmultiThermalBaric::registerKeywords(Keywords& keys)
+     113             : {
+     114          10 :   ExpansionCVs::registerKeywords(keys);
+     115          10 :   keys.remove("ARG");
+     116          20 :   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");
+     117             : //temperature
+     118          20 :   keys.add("optional","TEMP_MIN","the minimum of the temperature range");
+     119          20 :   keys.add("optional","TEMP_MAX","the maximum of the temperature range");
+     120          20 :   keys.add("optional","TEMP_STEPS","the number of steps in temperature");
+     121          20 :   keys.add("optional","TEMP_SET_ALL","manually set all the temperatures");
+     122          20 :   keys.addFlag("NO_GEOM_SPACING",false,"do not use geometrical spacing in temperature, but instead linear spacing in inverse temperature");
+     123             : //pressure
+     124          20 :   keys.add("compulsory","PRESSURE","pressure. Use the proper units");
+     125          20 :   keys.add("optional","PRESSURE_MIN","the minimum of the pressure range");
+     126          20 :   keys.add("optional","PRESSURE_MAX","the maximum of the pressure range");
+     127          20 :   keys.add("optional","PRESSURE_STEPS","the number of steps in pressure");
+     128          30 :   keys.add("optional","PRESSURE_SET_ALL","manually set all the pressures");
+     129             : //other
+     130          30 :   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,...");
+     131          20 :   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$");
+     132          10 : }
+     133             : 
+     134           9 : ECVmultiThermalBaric::ECVmultiThermalBaric(const ActionOptions&ao)
+     135             :   : Action(ao)
+     136             :   , ExpansionCVs(ao)
+     137           9 :   , todoAutomatic_beta_(false)
+     138           9 :   , todoAutomatic_pres_(false)
+     139           9 :   , coeff_(0)
+     140           9 :   , pres_low_(0)
+     141           9 :   , kB_temp_low_(0)
+     142             : {
+     143           9 :   plumed_massert(getNumberOfArguments()==2,"ENERGY and VOLUME should be given as ARG");
+     144             : 
+     145             : //set temp0
+     146           9 :   const double kB=plumed.getAtoms().getKBoltzmann();
+     147           9 :   const double temp0=kbt_/kB;
+     148             : 
+     149             : //parse temp range
+     150           9 :   double temp_min=-1;
+     151           9 :   double temp_max=-1;
+     152           9 :   parse("TEMP_MIN",temp_min);
+     153           9 :   parse("TEMP_MAX",temp_max);
+     154           9 :   unsigned temp_steps=0;
+     155          18 :   parse("TEMP_STEPS",temp_steps);
+     156             :   std::vector<double> temps;
+     157           9 :   parseVector("TEMP_SET_ALL",temps);
+     158           9 :   parseFlag("NO_GEOM_SPACING",geom_spacing_);
+     159           9 :   geom_spacing_=!geom_spacing_;
+     160             : //parse pressures
+     161           9 :   parse("PRESSURE",pres0_);
+     162             :   const double myNone=std::numeric_limits<double>::lowest(); //quiet_NaN is not supported by some intel compiler
+     163           9 :   double pres_min=myNone; //-1 might be a meaningful pressure
+     164           9 :   double pres_max=myNone;
+     165           9 :   parse("PRESSURE_MIN",pres_min);
+     166           9 :   parse("PRESSURE_MAX",pres_max);
+     167           9 :   unsigned pres_steps=0;
+     168           9 :   parse("PRESSURE_STEPS",pres_steps);
+     169          18 :   parseVector("PRESSURE_SET_ALL",pres_);
+     170             : //other
+     171             :   std::vector<double> cut_corner;
+     172           9 :   parseVector("CUT_CORNER",cut_corner);
+     173           9 :   parseVector("SET_ALL_TEMP_PRESSURE",custom_lambdas_);
+     174             : 
+     175           9 :   checkRead();
+     176             : 
+     177           9 :   if(custom_lambdas_.size()>0)
+     178             :   {
+     179             :     //make sure no incompatible options are used
+     180           2 :     plumed_massert(temps.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_SET_ALL");
+     181           2 :     plumed_massert(pres_.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_SET_ALL");
+     182           2 :     plumed_massert(temp_steps==0,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_STEPS");
+     183           2 :     plumed_massert(pres_steps==0,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_STEPS");
+     184           2 :     plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_MIN/MAX");
+     185           2 :     plumed_massert(pres_min==myNone && pres_max==myNone,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_MIN/MAX");
+     186           2 :     plumed_massert(cut_corner.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and CUT_CORNER");
+     187             : //setup the target temperature-pressure grid
+     188           2 :     derECVs_beta_.resize(custom_lambdas_.size());
+     189           2 :     derECVs_pres_.resize(custom_lambdas_.size());
+     190           2 :     const std::string error_msg="SET_ALL_TEMP_PRESSURE: two underscore-separated values are expected for each comma-separated point, cannot understand: ";
+     191          22 :     for(unsigned i=0; i<custom_lambdas_.size(); i++)
+     192             :     {
+     193             :       try
+     194             :       {
+     195             :         std::size_t pos1;
+     196             :         const double temp_i=std::stod(custom_lambdas_[i],&pos1);
+     197          20 :         plumed_massert(pos1+1<custom_lambdas_[i].size(),error_msg+custom_lambdas_[i]);
+     198          20 :         plumed_massert(custom_lambdas_[i][pos1]=='_',error_msg+custom_lambdas_[i]);
+     199             :         std::size_t pos2;
+     200          20 :         const double pres_i=std::stod(custom_lambdas_[i].substr(pos1+1),&pos2);
+     201          20 :         plumed_massert(pos1+1+pos2==custom_lambdas_[i].size(),error_msg+custom_lambdas_[i]);
+     202             : 
+     203          20 :         derECVs_beta_[i]=(temp0/temp_i-1.)/kbt_;
+     204          20 :         derECVs_pres_[i]=(temp0/temp_i*pres_i-pres0_)/kbt_;
+     205             :       }
+     206           0 :       catch (std::exception &ex)
+     207             :       {
+     208           0 :         plumed_merror(error_msg+custom_lambdas_[i]);
+     209           0 :       }
+     210             :     }
+     211             :   }
+     212             :   else
+     213             :   {
+     214             :     //set the intermediate temperatures
+     215           7 :     if(temps.size()>0)
+     216             :     {
+     217           1 :       plumed_massert(temp_steps==0,"cannot set both TEMP_STEPS and TEMP_SET_ALL");
+     218           1 :       plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both TEMP_SET_ALL and TEMP_MIN/MAX");
+     219           1 :       plumed_massert(temps.size()>=2,"set at least 2 temperatures");
+     220           1 :       temp_min=temps[0];
+     221           1 :       temp_max=temps[temps.size()-1];
+     222           1 :       derECVs_beta_.resize(temps.size());
+     223           5 :       for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     224             :       {
+     225           4 :         derECVs_beta_[k]=(temp0/temps[k]-1.)/kbt_;
+     226           4 :         if(k<derECVs_beta_.size()-1)
+     227           3 :           plumed_massert(temps[k]<=temps[k+1],"TEMP_SET_ALL must be properly ordered");
+     228             :       }
+     229             :     }
+     230             :     else
+     231             :     { //get TEMP_MIN and TEMP_MAX
+     232           6 :       if(temp_min==-1)
+     233             :       {
+     234           0 :         temp_min=temp0;
+     235           0 :         log.printf("  no TEMP_MIN provided, using TEMP_MIN=TEMP\n");
+     236             :       }
+     237           6 :       if(temp_max==-1)
+     238             :       {
+     239           1 :         temp_max=temp0;
+     240           1 :         log.printf("  no TEMP_MAX provided, using TEMP_MAX=TEMP\n");
+     241             :       }
+     242           6 :       plumed_massert(temp_max>=temp_min,"TEMP_MAX should be bigger than TEMP_MIN");
+     243           6 :       derECVs_beta_.resize(2);
+     244           6 :       derECVs_beta_[0]=(temp0/temp_min-1.)/kbt_;
+     245           6 :       derECVs_beta_[1]=(temp0/temp_max-1.)/kbt_;
+     246           6 :       if(temp_min==temp_max && temp_steps==0)
+     247           0 :         temp_steps=1;
+     248           6 :       if(temp_steps>0)
+     249           4 :         derECVs_beta_=getSteps(derECVs_beta_[0],derECVs_beta_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     250             :       else
+     251           4 :         todoAutomatic_beta_=true;
+     252             :     }
+     253             :     const double tol=1e-3; //if temp is taken from MD engine it might be numerically slightly different
+     254           7 :     if(temp0<(1-tol)*temp_min || temp0>(1+tol)*temp_max)
+     255           1 :       log.printf(" +++ WARNING +++ running at TEMP=%g which is outside the chosen temperature range\n",temp0);
+     256             : 
+     257             :     //set the intermediate pressures
+     258           7 :     if(pres_.size()>0)
+     259             :     {
+     260           1 :       plumed_massert(pres_steps==0,"cannot set both PRESSURE_STEPS and PRESSURE_SET_ALL");
+     261           1 :       plumed_massert(pres_min==myNone && pres_max==myNone,"cannot set both PRESSURE_SET_ALL and PRESSURE_MIN/MAX");
+     262           1 :       plumed_massert(pres_.size()>=2,"set at least 2 pressures");
+     263           6 :       for(unsigned kk=0; kk<pres_.size()-1; kk++)
+     264           5 :         plumed_massert(pres_[kk]<=pres_[kk+1],"PRESSURE_SET_ALL must be properly ordered");
+     265           1 :       pres_min=pres_[0];
+     266           1 :       pres_max=pres_[pres_.size()-1];
+     267             :     }
+     268             :     else
+     269             :     { //get PRESSURE_MIN and PRESSURE_MAX
+     270           6 :       if(pres_min==myNone)
+     271             :       {
+     272           3 :         pres_min=pres0_;
+     273           3 :         log.printf("  no PRESSURE_MIN provided, using PRESSURE_MIN=PRESSURE\n");
+     274             :       }
+     275           6 :       if(pres_max==myNone)
+     276             :       {
+     277           2 :         pres_max=pres0_;
+     278           2 :         log.printf("  no PRESSURE_MAX provided, using PRESSURE_MAX=PRESSURE\n");
+     279             :       }
+     280           6 :       plumed_massert(pres_max>=pres_min,"PRESSURE_MAX should be bigger than PRESSURE_MIN");
+     281           6 :       if(pres_min==pres_max && pres_steps==0)
+     282           0 :         pres_steps=1;
+     283           6 :       if(pres_steps>0)
+     284           4 :         pres_=getSteps(pres_min,pres_max,pres_steps,"PRESSURE",false,0);
+     285             :       else
+     286             :       {
+     287           4 :         pres_.resize(2);
+     288           4 :         pres_[0]=pres_min;
+     289           4 :         pres_[1]=pres_max;
+     290           4 :         todoAutomatic_pres_=true;
+     291             :       }
+     292             :     }
+     293           7 :     if(pres0_<pres_min || pres0_>pres_max)
+     294           0 :       log.printf(" +++ WARNING +++ running at PRESSURE=%g which is outside the chosen pressure range\n",pres0_);
+     295             : 
+     296             :     //set CUT_CORNER
+     297           7 :     std::string cc_usage("CUT_CORNER=temp_low,pres_low,temp_high,pres_high");
+     298           7 :     if(cut_corner.size()==4)
+     299             :     {
+     300           6 :       const double temp_low=cut_corner[0];
+     301           6 :       const double pres_low=cut_corner[1];
+     302           6 :       const double temp_high=cut_corner[2];
+     303           6 :       const double pres_high=cut_corner[3];
+     304           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);
+     305           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);
+     306           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);
+     307           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);
+     308           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);
+     309           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);
+     310           6 :       kB_temp_low_=kB*temp_low;
+     311           6 :       coeff_=(pres_high-pres_low)/(temp_high-temp_low)/kB;
+     312           6 :       plumed_massert(coeff_!=0,"this should not be possible");
+     313           6 :       const double small_value=(temp_high-pres_low)/1e4;
+     314           6 :       pres_low_=pres_low-small_value; //make sure pres_max is included
+     315           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);
+     316             :     }
+     317             :     else
+     318             :     {
+     319           1 :       plumed_massert(cut_corner.size()==0,"expected 4 values: "+cc_usage);
+     320             :     }
+     321             :   }
+     322             : 
+     323             : //print some info
+     324           9 :   log.printf("  running at TEMP=%g and PRESSURE=%g\n",temp0,pres0_);
+     325           9 :   log.printf("  targeting a temperature range from TEMP_MIN=%g to TEMP_MAX=%g\n",temp_min,temp_max);
+     326           9 :   if(temp_min==temp_max)
+     327           2 :     log.printf(" +++ WARNING +++ if you only need a multibaric simulation it is more efficient to set it up with ECV_LINEAR\n");
+     328           9 :   log.printf("   and a pressure range from PRESSURE_MIN=%g to PRESSURE_MAX=%g\n",pres_min,pres_max);
+     329           9 :   if(pres_min==pres_max)
+     330           2 :     log.printf(" +++ WARNING +++ if you only need a multithermal simulation it is more efficient to set it up with ECV_MULTITHERMAL\n");
+     331           9 :   if(geom_spacing_)
+     332           8 :     log.printf(" -- NO_GEOM_SPACING: inverse temperatures will be linearly spaced\n");
+     333           9 :   if(coeff_!=0)
+     334           6 :     log.printf(" -- CUT_CORNER: ignoring some high temperature and low pressure values\n");
+     335           9 : }
+     336             : 
+     337         463 : void ECVmultiThermalBaric::calculateECVs(const double * ene_vol)
+     338             : {
+     339        5925 :   for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     340        5462 :     ECVs_beta_[k]=derECVs_beta_[k]*ene_vol[0];
+     341       50075 :   for(unsigned i=0; i<derECVs_pres_.size(); i++)
+     342       49612 :     ECVs_pres_[i]=derECVs_pres_[i]*ene_vol[1];
+     343             : // derivatives are constant, as usual in linear expansions
+     344         463 : }
+     345             : 
+     346          18 : const double * ECVmultiThermalBaric::getPntrToECVs(unsigned j)
+     347             : {
+     348          18 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     349          18 :   plumed_massert(j==0 || j==1,getName()+" has only two CVs, the ENERGY and the VOLUME");
+     350          18 :   if(j==0)
+     351           9 :     return &ECVs_beta_[0];
+     352             :   else //if (j==1)
+     353           9 :     return &ECVs_pres_[0];
+     354             : }
+     355             : 
+     356          18 : const double * ECVmultiThermalBaric::getPntrToDerECVs(unsigned j)
+     357             : {
+     358          18 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     359          18 :   plumed_massert(j==0 || j==1,getName()+" has only two CVs, the ENERGY and the VOLUME");
+     360          18 :   if(j==0)
+     361           9 :     return &derECVs_beta_[0];
+     362             :   else //if (j==1)
+     363           9 :     return &derECVs_pres_[0];
+     364             : }
+     365             : 
+     366           9 : std::vector< std::vector<unsigned> > ECVmultiThermalBaric::getIndex_k() const
+     367             : {
+     368           9 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+     369             :   std::vector< std::vector<unsigned> > index_k;
+     370           9 :   if(custom_lambdas_.size()>0)
+     371             :   { //same as default getIndex_k() function
+     372           2 :     plumed_massert(totNumECVs_==custom_lambdas_.size(),"this should not happen");
+     373          22 :     for(unsigned i=0; i<totNumECVs_; i++)
+     374          40 :       index_k.emplace_back(std::vector<unsigned> {i,i});
+     375             :   }
+     376             :   else
+     377             :   {
+     378             :     unsigned i=0;
+     379         146 :     for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     380             :     {
+     381         139 :       const double kB_temp_k=kbt_/(derECVs_beta_[k]*kbt_+1);
+     382         139 :       const double line_k=coeff_*(kB_temp_k-kB_temp_low_)+pres_low_;
+     383        2594 :       for(unsigned kk=0; kk<pres_.size(); kk++)
+     384             :       {
+     385        2455 :         if(coeff_==0 || pres_[kk]>=line_k) //important to be inclusive, thus >=, not just >
+     386             :         {
+     387        2254 :           index_k.emplace_back(std::vector<unsigned> {k,i});
+     388        2254 :           i++;
+     389             :         }
+     390             :       }
+     391             :     }
+     392           7 :     plumed_massert(totNumECVs_==index_k.size(),"this should not happen, is something wrong with CUT_CORNER ?");
+     393             :   }
+     394           9 :   return index_k;
+     395           0 : }
+     396             : 
+     397          18 : std::vector<std::string> ECVmultiThermalBaric::getLambdas() const
+     398             : {
+     399          18 :   if(custom_lambdas_.size()>0)
+     400           4 :     return custom_lambdas_;
+     401             : 
+     402          14 :   plumed_massert(!todoAutomatic_beta_ && !todoAutomatic_pres_,"cannot access lambdas before initializing them");
+     403             :   std::vector<std::string> lambdas;
+     404          14 :   const double kB=plumed.getAtoms().getKBoltzmann();
+     405         292 :   for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     406             :   {
+     407         278 :     const double kB_temp_k=kbt_/(derECVs_beta_[k]*kbt_+1);
+     408         278 :     const double line_k=coeff_*(kB_temp_k-kB_temp_low_)+pres_low_;
+     409        5188 :     for(unsigned kk=0; kk<pres_.size(); kk++)
+     410             :     {
+     411        4910 :       if(coeff_==0 || pres_[kk]>=line_k)
+     412             :       {
+     413        4508 :         std::ostringstream subs;
+     414        4508 :         subs<<kB_temp_k/kB<<"_"<<pres_[kk];
+     415        4508 :         lambdas.emplace_back(subs.str());
+     416        4508 :       }
+     417             :     }
+     418             :   }
+     419             :   return lambdas;
+     420          14 : }
+     421             : 
+     422           9 : void ECVmultiThermalBaric::initECVs()
+     423             : {
+     424           9 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     425           9 :   plumed_massert(!todoAutomatic_beta_ && !todoAutomatic_pres_,"this should not happen");
+     426           9 :   totNumECVs_=getLambdas().size(); //slow, but runs only once
+     427           9 :   if(custom_lambdas_.size()>0)
+     428             :   {
+     429           2 :     log.printf("  *%4lu temperatures for %s\n",derECVs_beta_.size(),getName().c_str());
+     430           2 :     log.printf("  *%4lu beta-pressures for %s\n",derECVs_pres_.size(),getName().c_str());
+     431           2 :     log.printf("    -- SET_ALL_TEMP_PRESSURE: total number of temp-pres points is %u\n",totNumECVs_);
+     432             :   }
+     433             :   else
+     434             :   {
+     435           7 :     plumed_massert(derECVs_beta_.size()*pres_.size()>=totNumECVs_,"this should not happen, is something wrong with CUT_CORNER ?");
+     436           7 :     derECVs_pres_.resize(totNumECVs_); //pres is mixed with temp (beta*p*V), thus we need to store all possible
+     437             :     //initialize the derECVs.
+     438             :     //this could be done before and one could avoid storing also beta0, beta_k, etc. but this way the code should be more readable
+     439             :     unsigned i=0;
+     440         146 :     for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     441             :     {
+     442         139 :       const double kB_temp_k=kbt_/(derECVs_beta_[k]*kbt_+1);
+     443         139 :       const double line_k=coeff_*(kB_temp_k-kB_temp_low_)+pres_low_;
+     444        2594 :       for(unsigned kk=0; kk<pres_.size(); kk++)
+     445             :       {
+     446        2455 :         if(coeff_==0 || pres_[kk]>=line_k)
+     447             :         {
+     448        2254 :           derECVs_pres_[i]=(pres_[kk]/kB_temp_k-pres0_/kbt_);
+     449        2254 :           i++;
+     450             :         }
+     451             :       }
+     452             :     }
+     453           7 :     log.printf("  *%4lu temperatures for %s\n",derECVs_beta_.size(),getName().c_str());
+     454           7 :     log.printf("  *%4lu pressures for %s\n",pres_.size(),getName().c_str());
+     455           7 :     if(coeff_!=0)
+     456           6 :       log.printf("    -- CUT_CORNER: %lu temp-pres points were excluded, thus total is %u\n",derECVs_beta_.size()*pres_.size()-totNumECVs_,totNumECVs_);
+     457             :   }
+     458           9 :   ECVs_beta_.resize(derECVs_beta_.size());
+     459           9 :   ECVs_pres_.resize(derECVs_pres_.size());
+     460           9 :   isReady_=true;
+     461           9 : }
+     462             : 
+     463           6 : void ECVmultiThermalBaric::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     464             : {
+     465           6 :   if(todoAutomatic_beta_) //estimate the steps in beta from observations
+     466             :   {
+     467           2 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j<ncv,"initECVs_observ parameters are inconsistent");
+     468           2 :     std::vector<double> obs_ene(all_obs_cvs.size()/ncv); //copy only useful observations
+     469          17 :     for(unsigned t=0; t<obs_ene.size(); t++)
+     470          15 :       obs_ene[t]=all_obs_cvs[t*ncv+index_j]+pres0_*all_obs_cvs[t*ncv+index_j+1]; //U=E+pV
+     471           2 :     const unsigned temp_steps=estimateNumSteps(derECVs_beta_[0],derECVs_beta_[1],obs_ene,"TEMP");
+     472           2 :     log.printf("    (spacing is on beta, not on temperature)\n");
+     473           4 :     derECVs_beta_=getSteps(derECVs_beta_[0],derECVs_beta_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     474           2 :     todoAutomatic_beta_=false;
+     475             :   }
+     476           6 :   if(todoAutomatic_pres_) //estimate the steps in pres from observations
+     477             :   {
+     478           2 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j+1<ncv,"initECVs_observ parameters are inconsistent");
+     479           2 :     std::vector<double> obs_vol(all_obs_cvs.size()/ncv); //copy only useful observations
+     480          17 :     for(unsigned t=0; t<obs_vol.size(); t++)
+     481          15 :       obs_vol[t]=all_obs_cvs[t*ncv+index_j+1];
+     482           2 :     const unsigned pres_steps=estimateNumSteps((pres_[0]-pres0_)/kbt_,(pres_[1]-pres0_)/kbt_,obs_vol,"PRESSURE");
+     483           2 :     log.printf("    (spacing is in beta0 units)\n");
+     484           4 :     pres_=getSteps(pres_[0],pres_[1],pres_steps,"PRESSURE",false,0);
+     485           2 :     todoAutomatic_pres_=false;
+     486             :   }
+     487           6 :   initECVs();
+     488           6 :   calculateECVs(&all_obs_cvs[index_j]);
+     489           6 : }
+     490             : 
+     491           3 : void ECVmultiThermalBaric::initECVs_restart(const std::vector<std::string>& lambdas)
+     492             : {
+     493           3 :   std::size_t pos=lambdas[0].find("_");
+     494           3 :   plumed_massert(pos!=std::string::npos,"this should not happen, two CVs are used in "+getName()+", not less");
+     495           3 :   pos=lambdas[0].find("_",pos+1);
+     496           3 :   plumed_massert(pos==std::string::npos,"this should not happen, two CVs are used in "+getName()+", not more");
+     497             : 
+     498         230 :   auto getPres=[&lambdas](const unsigned i) {return lambdas[i].substr(lambdas[i].find("_")+1);};
+     499           3 :   if(todoAutomatic_pres_)
+     500             :   {
+     501             :     unsigned pres_steps=1;
+     502           2 :     std::string pres_min=getPres(0);
+     503          20 :     for(unsigned i=1; i<lambdas.size(); i++) //pres is second, thus increas by 1
+     504             :     {
+     505          20 :       if(getPres(i)==pres_min)
+     506             :         break;
+     507          18 :       pres_steps++;
+     508             :     }
+     509           4 :     pres_=getSteps(pres_[0],pres_[1],pres_steps,"PRESSURE",false,0);
+     510           2 :     todoAutomatic_pres_=false;
+     511             :   }
+     512           3 :   if(todoAutomatic_beta_)
+     513             :   {
+     514             :     unsigned temp_steps=1;
+     515           2 :     std::string pres_max=getPres(pres_.size()-1);
+     516         208 :     for(unsigned i=pres_.size(); i<lambdas.size(); i++)
+     517             :     { //even if CUT_CORNER, the max pressures are all present, for each temp
+     518         206 :       if(getPres(i)==pres_max)
+     519          24 :         temp_steps++;
+     520             :     }
+     521           4 :     derECVs_beta_=getSteps(derECVs_beta_[0],derECVs_beta_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     522           2 :     todoAutomatic_beta_=false;
+     523             :   }
+     524           3 :   std::vector<std::string> myLambdas=getLambdas();
+     525           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";
+     526           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     527             : 
+     528           3 :   initECVs();
+     529           3 : }
+     530             : 
+     531             : }
+     532             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e4b924da8e --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:11912198.3 %
Date:2024-06-10 08:19:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasFileC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes16ECVumbrellasFile16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes16ECVumbrellasFile15initECVs_observERKSt6vectorIdSaIdEEjj2
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe966createERKNS_13ActionOptionsE3
_ZN4PLMD4opes16ECVumbrellasFile8initECVsEv3
_ZN4PLMD4opes16ECVumbrellasFileC1ERKNS_13ActionOptionsE3
_ZNK4PLMD4opes16ECVumbrellasFile10getLambdasB5cxx11Ev3
_ZN4PLMD4opes16ECVumbrellasFile16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4opes16ECVumbrellasFile13getPntrToECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile16getPntrToDerECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile13calculateECVsEPKd131
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe96C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe96D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.func.html b/coverage/opes/ECVumbrellasFile.cpp.func.html new file mode 100644 index 0000000000..cecb8023c6 --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:11912198.3 %
Date:2024-06-10 08:19:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe966createERKNS_13ActionOptionsE3
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe96C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe96D2Ev3473
_ZN4PLMD4opes16ECVumbrellasFile13calculateECVsEPKd131
_ZN4PLMD4opes16ECVumbrellasFile13getPntrToECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile15initECVs_observERKSt6vectorIdSaIdEEjj2
_ZN4PLMD4opes16ECVumbrellasFile16getPntrToDerECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes16ECVumbrellasFile16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4opes16ECVumbrellasFile8initECVsEv3
_ZN4PLMD4opes16ECVumbrellasFileC1ERKNS_13ActionOptionsE3
_ZN4PLMD4opes16ECVumbrellasFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes16ECVumbrellasFile10getLambdasB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.gcov.html b/coverage/opes/ECVumbrellasFile.cpp.gcov.html new file mode 100644 index 0000000000..6fa4815779 --- /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:11912198.3 %
Date:2024-06-10 08:19:14Functions: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 "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       10425 : PLUMED_REGISTER_ACTION(ECVumbrellasFile,"ECV_UMBRELLAS_FILE")
+      97             : 
+      98           4 : void ECVumbrellasFile::registerKeywords(Keywords& keys)
+      99             : {
+     100           4 :   ExpansionCVs::registerKeywords(keys);
+     101           4 :   keys.use("ARG");
+     102           8 :   keys.add("compulsory","FILE","the name of the file containing the umbrellas");
+     103           8 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+     104           8 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+     105           8 :   keys.addFlag("LOWER_HALF_ONLY",false,"use only the lower half of each umbrella potentials");
+     106           4 : }
+     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.15
+
+ + + 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 0000000000..767010f334 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:13013298.5 %
Date:2024-06-10 08:19:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasLineC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes16ECVumbrellasLine16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes16ECVumbrellasLine15initECVs_observERKSt6vectorIdSaIdEEjj5
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe966createERKNS_13ActionOptionsE8
_ZN4PLMD4opes16ECVumbrellasLine8initECVsEv8
_ZN4PLMD4opes16ECVumbrellasLineC1ERKNS_13ActionOptionsE8
_ZNK4PLMD4opes16ECVumbrellasLine10getLambdasB5cxx11Ev8
_ZN4PLMD4opes16ECVumbrellasLine16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4opes16ECVumbrellasLine13getPntrToECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16getPntrToDerECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine13calculateECVsEPKd433
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe96C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe96D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.func.html b/coverage/opes/ECVumbrellasLine.cpp.func.html new file mode 100644 index 0000000000..7ab6fe64e9 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:13013298.5 %
Date:2024-06-10 08:19:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe966createERKNS_13ActionOptionsE8
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe96C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe96D2Ev3473
_ZN4PLMD4opes16ECVumbrellasLine13calculateECVsEPKd433
_ZN4PLMD4opes16ECVumbrellasLine13getPntrToECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine15initECVs_observERKSt6vectorIdSaIdEEjj5
_ZN4PLMD4opes16ECVumbrellasLine16getPntrToDerECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes16ECVumbrellasLine16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4opes16ECVumbrellasLine8initECVsEv8
_ZN4PLMD4opes16ECVumbrellasLineC1ERKNS_13ActionOptionsE8
_ZN4PLMD4opes16ECVumbrellasLineC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes16ECVumbrellasLine10getLambdasB5cxx11Ev8
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.gcov.html b/coverage/opes/ECVumbrellasLine.cpp.gcov.html new file mode 100644 index 0000000000..6260424021 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.gcov.html @@ -0,0 +1,377 @@ + + + + + + + + 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:13013298.5 %
Date:2024-06-10 08:19:14Functions: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 "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             : The umbrellas can be multidimensional, but you should rescale the dimensions so that a single SIGMA can be used.
+      37             : 
+      38             : The keyword BARRIER can be helpful to avoid breaking your system due to a too strong initial bias.
+      39             : 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.
+      40             : See also Appendix B of Ref.\cite Invernizzi2020unified for more details on these last two options.
+      41             : 
+      42             : 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.
+      43             : 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.
+      44             : By pushing only from below one can avoid too extreme forces that could crash the simulation.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : \plumedfile
+      49             : cv: DISTANCE ATOMS=1,2
+      50             : ecv: ECV_UMBRELLAS_LINE ARG=cv CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5 SPACING=1.5
+      51             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      52             : \endplumedfile
+      53             : 
+      54             : It is also possible to combine different ECV_UMBRELLAS_LINE to build a grid of CV values that will be sampled.
+      55             : For example the following code will sample a whole 2D region of cv1 and cv2.
+      56             : 
+      57             : \plumedfile
+      58             : cv1: DISTANCE ATOMS=1,2
+      59             : ecv2: ECV_UMBRELLAS_LINE ARG=cv1 CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5
+      60             : 
+      61             : cv2: DISTANCE ATOMS=3,4
+      62             : ecv1: ECV_UMBRELLAS_LINE ARG=cv2 CV_MIN=13.8 CV_MAX=21.4 SIGMA=4.3
+      63             : 
+      64             : opes: OPES_EXPANDED ARG=ecv1.*,ecv2.* PACE=500
+      65             : \endplumedfile
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : class ECVumbrellasLine :
+      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             :   double sigma_;
+      80             : 
+      81             :   std::vector< std::vector<double> > ECVs_;
+      82             :   std::vector< std::vector<double> > derECVs_;
+      83             :   void initECVs();
+      84             : 
+      85             : public:
+      86             :   explicit ECVumbrellasLine(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       10435 : PLUMED_REGISTER_ACTION(ECVumbrellasLine,"ECV_UMBRELLAS_LINE")
+      97             : 
+      98           9 : void ECVumbrellasLine::registerKeywords(Keywords& keys)
+      99             : {
+     100           9 :   ExpansionCVs::registerKeywords(keys);
+     101           9 :   keys.use("ARG");
+     102          18 :   keys.add("compulsory","CV_MIN","the minimum of the CV range to be explored");
+     103          18 :   keys.add("compulsory","CV_MAX","the maximum of the CV range to be explored");
+     104          18 :   keys.add("compulsory","SIGMA","sigma of the umbrella Gaussians");
+     105          18 :   keys.add("compulsory","SPACING","1","the distance between umbrellas, in units of SIGMA");
+     106          18 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+     107          18 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+     108          18 :   keys.addFlag("LOWER_HALF_ONLY",false,"use only the lower half of each umbrella potentials");
+     109           9 : }
+     110             : 
+     111           8 : ECVumbrellasLine::ECVumbrellasLine(const ActionOptions&ao):
+     112             :   Action(ao),
+     113           8 :   ExpansionCVs(ao)
+     114             : {
+     115             : //set P0_contribution_
+     116           8 :   bool add_P0=false;
+     117           8 :   parseFlag("ADD_P0",add_P0);
+     118           8 :   if(add_P0)
+     119           2 :     P0_contribution_=1;
+     120             :   else
+     121           6 :     P0_contribution_=0;
+     122             : 
+     123             : //set barrier_
+     124           8 :   barrier_=std::numeric_limits<double>::infinity();
+     125           8 :   parse("BARRIER",barrier_);
+     126           8 :   parseFlag("LOWER_HALF_ONLY",lower_only_);
+     127             : 
+     128             : //set umbrellas
+     129          16 :   parse("SIGMA",sigma_);
+     130             :   std::vector<double> cv_min;
+     131             :   std::vector<double> cv_max;
+     132           8 :   parseVector("CV_MIN",cv_min);
+     133          16 :   parseVector("CV_MAX",cv_max);
+     134           8 :   plumed_massert(cv_min.size()==getNumberOfArguments(),"wrong number of CV_MINs");
+     135           8 :   plumed_massert(cv_max.size()==getNumberOfArguments(),"wrong number of CV_MAXs");
+     136             :   double spacing;
+     137           8 :   parse("SPACING",spacing);
+     138             :   double length=0;
+     139          18 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     140          10 :     length+=std::pow(cv_max[j]-cv_min[j],2);
+     141           8 :   length=std::sqrt(length);
+     142           8 :   unsigned sizeUmbrellas=1+std::round(length/(sigma_*spacing));
+     143           8 :   centers_.resize(getNumberOfArguments()); //centers_[cv][umbrellas]
+     144             :   unsigned full_period=0;
+     145          18 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     146             :   {
+     147          10 :     centers_[j].resize(sizeUmbrellas);
+     148          10 :     if(sizeUmbrellas>1)
+     149         140 :       for(unsigned k=0; k<sizeUmbrellas; k++)
+     150         130 :         centers_[j][k]=cv_min[j]+k*(cv_max[j]-cv_min[j])/(sizeUmbrellas-1);
+     151             :     else
+     152           0 :       centers_[j][0]=(cv_min[j]+cv_max[j])/2.;
+     153          10 :     if(getPntrToArgument(j)->isPeriodic())
+     154             :     {
+     155             :       double min,max;
+     156             :       std::string min_str,max_str;
+     157          10 :       getPntrToArgument(j)->getDomain(min,max);
+     158          10 :       getPntrToArgument(j)->getDomain(min_str,max_str);
+     159          10 :       plumed_massert(cv_min[j]>=min,"ARG "+std::to_string(j)+": CV_MIN cannot be smaller than the periodic bound "+min_str);
+     160          10 :       plumed_massert(cv_max[j]<=max,"ARG "+std::to_string(j)+": CV_MAX cannot be greater than the periodic bound "+max_str);
+     161          10 :       if(cv_min[j]==min && cv_max[j]==max)
+     162           6 :         full_period++;
+     163             :     }
+     164             :   }
+     165           8 :   if(full_period==getNumberOfArguments() && sizeUmbrellas>1) //first and last are the same point
+     166             :   {
+     167           6 :     sizeUmbrellas--;
+     168          12 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     169           6 :       centers_[j].pop_back();
+     170             :   }
+     171             : 
+     172           8 :   checkRead();
+     173             : 
+     174             : //set ECVs stuff
+     175           8 :   totNumECVs_=sizeUmbrellas+P0_contribution_;
+     176           8 :   ECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     177           8 :   derECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     178             : 
+     179             : //printing some info
+     180           8 :   log.printf("  total number of umbrellas = %u\n",sizeUmbrellas);
+     181           8 :   log.printf("    with SIGMA = %g\n",sigma_);
+     182           8 :   log.printf("    and SPACING = %g\n",spacing);
+     183           8 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     184           2 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     185           8 :   if(P0_contribution_==1)
+     186           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     187           8 :   if(lower_only_)
+     188           1 :     log.printf(" -- LOWER_HALF_ONLY: the ECVs are set to zero for values of the CV above the respective center\n");
+     189           8 : }
+     190             : 
+     191         433 : void ECVumbrellasLine::calculateECVs(const double * cv)
+     192             : {
+     193         433 :   if(lower_only_)
+     194             :   {
+     195         153 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     196             :     {
+     197        2040 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     198             :       {
+     199        1938 :         const unsigned kk=k-P0_contribution_;
+     200        1938 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigma_; //PBC might be present
+     201        1938 :         if(dist_jk>=0)
+     202             :         {
+     203         933 :           ECVs_[j][k]=0;
+     204         933 :           derECVs_[j][k]=0;
+     205             :         }
+     206             :         else
+     207             :         {
+     208        1005 :           ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     209        1005 :           derECVs_[j][k]=dist_jk/sigma_;
+     210             :         }
+     211             :       }
+     212             :     }
+     213             :   }
+     214             :   else
+     215             :   {
+     216         804 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     217             :     {
+     218        4678 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     219             :       {
+     220        4256 :         const unsigned kk=k-P0_contribution_;
+     221        4256 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigma_; //PBC might be present
+     222        4256 :         ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     223        4256 :         derECVs_[j][k]=dist_jk/sigma_;
+     224             :       }
+     225             :     }
+     226             :   }
+     227         433 : }
+     228             : 
+     229          10 : const double * ECVumbrellasLine::getPntrToECVs(unsigned j)
+     230             : {
+     231          10 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     232          10 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     233          10 :   return &ECVs_[j][0];
+     234             : }
+     235             : 
+     236          10 : const double * ECVumbrellasLine::getPntrToDerECVs(unsigned j)
+     237             : {
+     238          10 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     239          10 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     240          10 :   return &derECVs_[j][0];
+     241             : }
+     242             : 
+     243           8 : std::vector<std::string> ECVumbrellasLine::getLambdas() const
+     244             : {
+     245           8 :   std::vector<std::string> lambdas(totNumECVs_);
+     246           8 :   if(P0_contribution_==1)
+     247             :   {
+     248           2 :     std::ostringstream subs;
+     249           2 :     subs<<"P0";
+     250           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     251           2 :       subs<<"_P0";
+     252           2 :     lambdas[0]=subs.str();
+     253           2 :   }
+     254          94 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     255             :   {
+     256          86 :     const unsigned kk=k-P0_contribution_;
+     257          86 :     std::ostringstream subs;
+     258          86 :     subs<<centers_[0][kk];
+     259         124 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     260          38 :       subs<<"_"<<centers_[j][kk];
+     261          86 :     lambdas[k]=subs.str();
+     262          86 :   }
+     263           8 :   return lambdas;
+     264           0 : }
+     265             : 
+     266           8 : void ECVumbrellasLine::initECVs()
+     267             : {
+     268           8 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     269           8 :   isReady_=true;
+     270           8 :   log.printf("  *%4u windows for %s\n",totNumECVs_,getName().c_str());
+     271           8 : }
+     272             : 
+     273           5 : void ECVumbrellasLine::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     274             : {
+     275             :   //this non-linear exansion never uses automatic initialization
+     276           5 :   initECVs();
+     277           5 :   calculateECVs(&all_obs_cvs[index_j]); //use only first obs point
+     278          11 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     279          76 :     for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     280         123 :       ECVs_[j][k]=std::min(barrier_/kbt_,ECVs_[j][k]);
+     281           5 : }
+     282             : 
+     283           3 : void ECVumbrellasLine::initECVs_restart(const std::vector<std::string>& lambdas)
+     284             : {
+     285             :   std::size_t pos=0;
+     286           4 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     287           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     288           3 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     289           3 :   pos=lambdas[0].find("_",pos+1);
+     290           3 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     291             : 
+     292           3 :   std::vector<std::string> myLambdas=getLambdas();
+     293           3 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     294           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     295             : 
+     296           3 :   initECVs();
+     297           3 : }
+     298             : 
+     299             : }
+     300             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..947e120728 --- /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:10211191.9 %
Date:2024-06-10 08:19:14Functions: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_8KeywordsE43
_ZZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_ENKUldS6_E_clEdS6_109
_ZN4PLMD4opes12ExpansionCVs5applyEv1847
_ZN4PLMD4opes12ExpansionCVs9calculateEv1847
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.func.html b/coverage/opes/ExpansionCVs.cpp.func.html new file mode 100644 index 0000000000..1fcb3929a1 --- /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:10211191.9 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVs16registerKeywordsERNS_8KeywordsE43
_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.15
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.gcov.html b/coverage/opes/ExpansionCVs.cpp.gcov.html new file mode 100644 index 0000000000..f5f385fe0f --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.gcov.html @@ -0,0 +1,310 @@ + + + + + + + + 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:10211191.9 %
Date:2024-06-10 08:19:14Functions: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             : #include "core/PlumedMain.h"
+      23             : #include "core/Atoms.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace opes {
+      27             : 
+      28          43 : void ExpansionCVs::registerKeywords(Keywords& keys)
+      29             : {
+      30          43 :   Action::registerKeywords(keys);
+      31          43 :   ActionWithValue::registerKeywords(keys);
+      32          43 :   ActionWithArguments::registerKeywords(keys);
+      33          43 :   ActionWithValue::useCustomisableComponents(keys);
+      34          86 :   keys.add("compulsory","TEMP","-1","temperature. If not specified tries to get it from MD engine");
+      35          43 : }
+      36             : 
+      37          37 : ExpansionCVs::ExpansionCVs(const ActionOptions&ao)
+      38             :   : Action(ao)
+      39             :   , ActionWithValue(ao)
+      40             :   , ActionWithArguments(ao)
+      41          37 :   , isReady_(false)
+      42          37 :   , totNumECVs_(0)
+      43             : {
+      44             : //set kbt_
+      45          37 :   const double kB=plumed.getAtoms().getKBoltzmann();
+      46          37 :   kbt_=plumed.getAtoms().getKbT();
+      47          37 :   double temp=-1;
+      48          37 :   parse("TEMP",temp);
+      49          37 :   if(temp>0)
+      50             :   {
+      51          37 :     if(kbt_>0 && std::abs(kbt_-kB*temp)>1e-4)
+      52           0 :       log.printf(" +++ WARNING +++ using TEMP=%g while MD engine uses %g\n",temp,kbt_/kB);
+      53          37 :     kbt_=kB*temp;
+      54             :   }
+      55          37 :   plumed_massert(kbt_>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+      56          37 :   log.printf("  temperature = %g, beta = %g\n",kbt_/kB,1./kbt_);
+      57             : 
+      58             : //set components
+      59          37 :   plumed_massert( getNumberOfArguments()!=0, "you must specify the underlying CV");
+      60          90 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      61             :   {
+      62          53 :     std::string name_j=getPntrToArgument(j)->getName();
+      63          53 :     ActionWithValue::addComponentWithDerivatives(name_j);
+      64          53 :     getPntrToComponent(j)->resizeDerivatives(1);
+      65          53 :     if(getPntrToArgument(j)->isPeriodic()) //it should not be necessary, but why not
+      66             :     {
+      67             :       std::string min,max;
+      68          17 :       getPntrToArgument(j)->getDomain(min,max);
+      69          17 :       getPntrToComponent(j)->setDomain(min,max);
+      70             :     }
+      71             :     else
+      72          36 :       getPntrToComponent(j)->setNotPeriodic();
+      73             :   }
+      74          37 :   plumed_massert((int)getNumberOfArguments()==getNumberOfComponents(),"Expansion CVs have same number of arguments and components");
+      75          37 : }
+      76             : 
+      77        1847 : void ExpansionCVs::calculate()
+      78             : {
+      79        1847 :   std::vector<double> args(getNumberOfArguments());
+      80        4470 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      81             :   {
+      82        2623 :     args[j]=getArgument(j);
+      83        2623 :     getPntrToComponent(j)->set(args[j]); //components are equal to arguments
+      84        2623 :     getPntrToComponent(j)->addDerivative(0,1.); //the derivative of the identity is 1
+      85             :   }
+      86        1847 :   if(isReady_)
+      87        1417 :     calculateECVs(&args[0]);
+      88        1847 : }
+      89             : 
+      90        1847 : void ExpansionCVs::apply()
+      91             : {
+      92        4470 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      93             :   {
+      94        2623 :     std::vector<double> force_j(1);
+      95        2623 :     if(getPntrToComponent(j)->applyForce(force_j)) //a bias is applied?
+      96        2623 :       getPntrToArgument(j)->addForce(force_j[0]); //just tell it to the CV!
+      97             :   }
+      98        1847 : }
+      99             : 
+     100          26 : std::vector< std::vector<unsigned> > ExpansionCVs::getIndex_k() const
+     101             : {
+     102          26 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+     103          26 :   std::vector< std::vector<unsigned> > index_k(totNumECVs_,std::vector<unsigned>(getNumberOfArguments()));
+     104         869 :   for(unsigned k=0; k<totNumECVs_; k++)
+     105        2391 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     106        1548 :       index_k[k][j]=k; //each CV gives rise to the same number of ECVs
+     107          26 :   return index_k;
+     108           0 : }
+     109             : 
+     110             : //following methods are meant to be used only in case of linear expansions
+     111          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
+     112             : {
+     113          24 :   plumed_massert(!(lambda_min==lambda_max && lambda_steps>1),"cannot have multiple "+msg+"_STEPS if "+msg+"_MIN=="+msg+"_MAX");
+     114          24 :   std::vector<double> lambda(lambda_steps);
+     115          24 :   if(lambda_steps==1)
+     116             :   {
+     117           0 :     lambda[0]=(lambda_min+lambda_max)/2.;
+     118           0 :     log.printf(" +++ WARNING +++ using one single %s as target = %g\n",msg.c_str(),lambda[0]);
+     119             :   }
+     120             :   else
+     121             :   {
+     122          24 :     if(geom_spacing) //geometric spacing
+     123             :     { //this way lambda[k]/lambda[k+1] is constant
+     124          14 :       lambda_min+=shift;
+     125          14 :       lambda_max+=shift;
+     126          14 :       plumed_massert(lambda_min>0,"cannot use GEOM_SPACING when %s_MIN is not greater than zero");
+     127          14 :       plumed_massert(lambda_max>0,"cannot use GEOM_SPACING when %s_MAX is not greater than zero");
+     128          14 :       const double log_lambda_min=std::log(lambda_min);
+     129          14 :       const double log_lambda_max=std::log(lambda_max);
+     130         196 :       for(unsigned k=0; k<lambda.size(); k++)
+     131         182 :         lambda[k]=std::exp(log_lambda_min+k*(log_lambda_max-log_lambda_min)/(lambda_steps-1))-shift;
+     132             :     }
+     133             :     else //linear spacing
+     134         108 :       for(unsigned k=0; k<lambda.size(); k++)
+     135          98 :         lambda[k]=lambda_min+k*(lambda_max-lambda_min)/(lambda_steps-1);
+     136             :   }
+     137          24 :   return lambda;
+     138             : }
+     139             : 
+     140           6 : unsigned ExpansionCVs::estimateNumSteps(const double left_side,const double right_side,const std::vector<double>& obs,const std::string& msg) const
+     141             : { //for linear expansions only, it uses effective sample size (Neff) to estimate the grid spacing
+     142           6 :   if(left_side==0 && right_side==0)
+     143             :   {
+     144           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());
+     145           0 :     return 1;
+     146             :   }
+     147           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
+     148             :   {
+     149             :     //func: Neff/N-0.5 is a function between -0.5 and 0.5
+     150         109 :     auto func=[](const double delta,const std::vector<double>& obs)
+     151             :     {
+     152             :       double sum_w=0;
+     153             :       double sum_w2=0;
+     154             :       //we could avoid recomputing safe_shift every time, but here speed is not a concern
+     155         109 :       const double safe_shift=delta<0?*std::max_element(obs.begin(),obs.end()):*std::min_element(obs.begin(),obs.end());
+     156         899 :       for(unsigned t=0; t<obs.size(); t++)
+     157             :       {
+     158         790 :         const double w=std::exp(-delta*(obs[t]-safe_shift)); //robust to overflow
+     159         790 :         sum_w+=w;
+     160         790 :         sum_w2+=w*w;
+     161             :       }
+     162         109 :       return sum_w*sum_w/sum_w2/obs.size()-0.5;
+     163             :     };
+     164             :     //here we find the root of func using the regula falsi (false position) method
+     165             :     //but any method would be OK, not much precision is needed. src/tools/RootFindingBase.h looked complicated
+     166             :     const double tolerance=1e-4; //seems to be a good default
+     167             :     double a=0; //default is right side case
+     168             :     double func_a=0.5;
+     169             :     double b=side;
+     170           9 :     double func_b=func(side,obs);
+     171           9 :     if(func_b>=0)
+     172             :       return 0.0; //no zero is present!
+     173           9 :     if(b<0) //left side case
+     174             :     {
+     175             :       std::swap(a,b);
+     176             :       std::swap(func_a,func_b);
+     177             :     }
+     178             :     double c=a;
+     179             :     double func_c=func_a;
+     180         109 :     while(std::abs(func_c)>tolerance)
+     181             :     {
+     182         100 :       if(func_a*func_c>0)
+     183             :       {
+     184             :         a=c;
+     185             :         func_a=func_c;
+     186             :       }
+     187             :       else
+     188             :       {
+     189             :         b=c;
+     190             :         func_b=func_c;
+     191             :       }
+     192         100 :       c=(a*func_b-b*func_a)/(func_b-func_a);
+     193         100 :       func_c=func(c,obs); //func is evaluated only here, it might be expensive
+     194             :     }
+     195           9 :     return std::abs(c);
+     196             :   };
+     197             : 
+     198             : //estimation
+     199             :   double left_HWHM=0;
+     200           6 :   if(left_side!=0)
+     201           4 :     left_HWHM=get_neff_HWHM(left_side,obs);
+     202             :   double right_HWHM=0;
+     203           6 :   if(right_side!=0)
+     204           5 :     right_HWHM=get_neff_HWHM(right_side,obs);
+     205           6 :   if(left_HWHM==0)
+     206             :   {
+     207           2 :     right_HWHM*=2;
+     208           2 :     if(left_side==0)
+     209           2 :       log.printf(" --- %s_MIN is equal to %s\n",msg.c_str(),msg.c_str());
+     210             :     else
+     211           0 :       log.printf(" +++ WARNING +++ %s_MIN is very close to %s\n",msg.c_str(),msg.c_str());
+     212             :   }
+     213           6 :   if(right_HWHM==0)
+     214             :   {
+     215           1 :     left_HWHM*=2;
+     216           1 :     if(right_side==0)
+     217           1 :       log.printf(" --- %s_MAX is equal to %s\n",msg.c_str(),msg.c_str());
+     218             :     else
+     219           0 :       log.printf(" +++ WARNING +++ %s_MAX is very close to %s\n",msg.c_str(),msg.c_str());
+     220             :   }
+     221           6 :   const double grid_spacing=left_HWHM+right_HWHM;
+     222           6 :   log.printf("   estimated %s spacing = %g\n",msg.c_str(),grid_spacing);
+     223           6 :   unsigned steps=std::ceil(std::abs(right_side-left_side)/grid_spacing);
+     224           6 :   if(steps<2 || grid_spacing==0)
+     225             :   {
+     226           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());
+     227             :     steps=2;
+     228             :   }
+     229             :   return steps;
+     230             : }
+     231             : 
+     232             : }
+     233             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..302c795ef7 --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVsD2Ev37
_ZNK4PLMD4opes12ExpansionCVs13getTotNumECVsEv50
_ZN4PLMD4opes12ExpansionCVs22getNumberOfDerivativesEv170
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.func.html b/coverage/opes/ExpansionCVs.h.func.html new file mode 100644 index 0000000000..aead5d910d --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVs22getNumberOfDerivativesEv170
_ZN4PLMD4opes12ExpansionCVsD2Ev37
_ZNK4PLMD4opes12ExpansionCVs13getTotNumECVsEv50
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.gcov.html b/coverage/opes/ExpansionCVs.h.gcov.html new file mode 100644 index 0000000000..5535d27db8 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..5b26bbd5f1 --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + 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:43044297.3 %
Date:2024-06-10 08:19:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12OPESexpandedC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes12OPESexpanded15dumpStateToFileEv11
_ZN4PLMD4opes12OPESexpanded12init_fromObsEv20
_ZN4PLMD4opes12OPESexpanded13init_linkECVsEv30
_ZN4PLMD4opes12OPESexpanded20init_pntrToECVsClassEv30
_ZN4PLMD4opes12OPESexpandedC1ERKNS_13ActionOptionsE30
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe1776createERKNS_13ActionOptionsE30
_ZN4PLMD4opes12OPESexpanded16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD4opes12OPESexpanded11printDeltaFEv64
_ZZN4PLMD4opes12OPESexpandedC4ERKNS_13ActionOptionsEENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjjE_clESC_jj525
_ZN4PLMD4opes12OPESexpanded12updateDeltaFEd660
_ZN4PLMD4opes12OPESexpanded6updateEv1490
_ZN4PLMD4opes12OPESexpanded9calculateEv1490
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe177C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe177D2Ev3473
_ZNK4PLMD4opes12OPESexpanded12getExpansionEj644469
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.func.html b/coverage/opes/OPESexpanded.cpp.func.html new file mode 100644 index 0000000000..dfc1e84f6f --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + 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:43044297.3 %
Date:2024-06-10 08:19:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12OPESexpanded11printDeltaFEv64
_ZN4PLMD4opes12OPESexpanded12init_fromObsEv20
_ZN4PLMD4opes12OPESexpanded12updateDeltaFEd660
_ZN4PLMD4opes12OPESexpanded13init_linkECVsEv30
_ZN4PLMD4opes12OPESexpanded15dumpStateToFileEv11
_ZN4PLMD4opes12OPESexpanded16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD4opes12OPESexpanded20init_pntrToECVsClassEv30
_ZN4PLMD4opes12OPESexpanded6updateEv1490
_ZN4PLMD4opes12OPESexpanded9calculateEv1490
_ZN4PLMD4opes12OPESexpandedC1ERKNS_13ActionOptionsE30
_ZN4PLMD4opes12OPESexpandedC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe1776createERKNS_13ActionOptionsE30
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe177C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe177D2Ev3473
_ZNK4PLMD4opes12OPESexpanded12getExpansionEj644469
_ZZN4PLMD4opes12OPESexpandedC4ERKNS_13ActionOptionsEENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjjE_clESC_jj525
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.gcov.html b/coverage/opes/OPESexpanded.cpp.gcov.html new file mode 100644 index 0000000000..0c8b7d5b85 --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.gcov.html @@ -0,0 +1,1015 @@ + + + + + + + + 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:43044297.3 %
Date:2024-06-10 08:19:14Functions:151693.8 %
+
+ + + + + + + + +

+
          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 (\ref OPES "OPES") with expanded ensembles target distribution (replica-exchange-like) \cite Invernizzi2020unified.
+      35             : 
+      36             : An expanded ensemble is obtained by summing a set of ensembles at slightly different termodynamic conditions, or with slightly different Hamiltonians.
+      37             : Such ensembles can be sampled via methods like replica exchange, or this \ref OPES_EXPANDED bias action.
+      38             : A typical example is a multicanonical simulation, in which a whole range of temperatures is sampled instead of a single one.
+      39             : 
+      40             : In oreder to define an expanded target ensemble we use \ref EXPANSION_CV "expansion collective variables" (ECVs), \f$\Delta u_\lambda(\mathbf{x})\f$.
+      41             : The bias at step \f$n\f$ is
+      42             : \f[
+      43             :   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)\, .
+      44             : \f]
+      45             : See Ref.\cite Invernizzi2020unified for more details on the method.
+      46             : 
+      47             : 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.
+      48             : The DELTAFS file also contains an estimate of \f$c(t)=\frac{1}{\beta} \log \langle e^{\beta V}\rangle\f$.
+      49             : 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.
+      50             : Its value is also needed for restarting a simulation.
+      51             : 
+      52             : You can store the instantaneous \f$\Delta F_n(\lambda)\f$ estimates also in a more readable format using STATE_WFILE and STATE_WSTRIDE.
+      53             : Restart can be done either from a DELTAFS file or from a STATE_RFILE, it is equivalent.
+      54             : 
+      55             : Contrary to \ref OPES_METAD, \ref OPES_EXPANDED does not use kernel density estimation.
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : \plumedfile
+      60             : # simulate multiple temperatures, as in parallel tempering
+      61             : ene: ENERGY
+      62             : ecv: ECV_MULTITHERMAL ARG=ene TEMP_MAX=1000
+      63             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      64             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,opes.bias
+      65             : \endplumedfile
+      66             : 
+      67             : You can easily combine multiple ECVs.
+      68             : The \ref OPES_EXPANDED bias will create a multidimensional target grid to sample all the combinations.
+      69             : 
+      70             : \plumedfile
+      71             : # simulate multiple temperatures while biasing a CV
+      72             : ene: ENERGY
+      73             : dst: DISTANCE ATOMS=1,2
+      74             : 
+      75             : ecv1: ECV_MULTITHERMAL ARG=ene TEMP_SET_ALL=200,300,500,1000
+      76             : ecv2: ECV_UMBRELLAS_LINE ARG=dst CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5
+      77             : opes: OPES_EXPANDED ARG=ecv1.*,ecv2.* PACE=500 OBSERVATION_STEPS=1
+      78             : 
+      79             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,dst,opes.bias
+      80             : \endplumedfile
+      81             : 
+      82             : If an ECV is based on more than one CV you must provide all the output component, in the proper order.
+      83             : You can use \ref Regex for that, like in the following example.
+      84             : 
+      85             : \plumedfile
+      86             : # simulate multiple temperatures and pressures while biasing a two-CVs linear path
+      87             : ene: ENERGY
+      88             : vol: VOLUME
+      89             : ecv_mtp: ECV_MULTITHERMAL_MULTIBARIC ...
+      90             :   ARG=ene,vol
+      91             :   TEMP=300
+      92             :   TEMP_MIN=200
+      93             :   TEMP_MAX=800
+      94             :   PRESSURE=0.06022140857*1000 #1 kbar
+      95             :   PRESSURE_MIN=0
+      96             :   PRESSURE_MAX=0.06022140857*2000 #2 kbar
+      97             : ...
+      98             : 
+      99             : cv1: DISTANCE ATOMS=1,2
+     100             : cv2: DISTANCE ATOMS=3,4
+     101             : 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
+     102             : 
+     103             : opes: OPES_EXPANDED ARG=(ecv_.*) PACE=500 WALKERS_MPI PRINT_STRIDE=1000
+     104             : 
+     105             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,vol,cv1,cv2,opes.bias
+     106             : \endplumedfile
+     107             : 
+     108             : 
+     109             : */
+     110             : //+ENDPLUMEDOC
+     111             : 
+     112             : class OPESexpanded : public bias::Bias {
+     113             : 
+     114             : private:
+     115             :   bool isFirstStep_;
+     116             :   unsigned NumOMP_;
+     117             :   unsigned NumParallel_;
+     118             :   unsigned rank_;
+     119             :   unsigned NumWalkers_;
+     120             :   unsigned walker_rank_;
+     121             :   unsigned long counter_;
+     122             :   std::size_t ncv_;
+     123             : 
+     124             :   std::vector<const double *> ECVs_;
+     125             :   std::vector<const double *> derECVs_;
+     126             :   std::vector<opes::ExpansionCVs*> pntrToECVsClass_;
+     127             :   std::vector< std::vector<unsigned> > index_k_;
+     128             : // A note on indexes usage:
+     129             : //  j -> underlying CVs
+     130             : //  i -> DeltaFs
+     131             : //  k -> single ECVs, which might not be trivially numbered
+     132             : //  l -> groups of ECVs, pntrToECVsClass
+     133             : //  h -> subgroups of ECVs, arguments in ECVsClass
+     134             : //  w -> walkers
+     135             : 
+     136             :   double kbt_;
+     137             :   unsigned stride_;
+     138             :   unsigned deltaF_size_; //different from deltaF_.size() if NumParallel_>1
+     139             :   std::vector<double> deltaF_;
+     140             :   std::vector<double> diff_;
+     141             :   double rct_;
+     142             : 
+     143             :   std::vector<double> all_deltaF_;
+     144             :   std::vector<int> all_size_;
+     145             :   std::vector<int> disp_;
+     146             : 
+     147             :   unsigned obs_steps_;
+     148             :   std::vector<double> obs_cvs_;
+     149             : 
+     150             :   bool calc_work_;
+     151             :   double work_;
+     152             : 
+     153             :   unsigned print_stride_;
+     154             :   OFile deltaFsOfile_;
+     155             :   std::vector<std::string> deltaF_name_;
+     156             : 
+     157             :   OFile stateOfile_;
+     158             :   int wStateStride_;
+     159             :   bool storeOldStates_;
+     160             : 
+     161             :   void init_pntrToECVsClass();
+     162             :   void init_linkECVs();
+     163             :   void init_fromObs();
+     164             : 
+     165             :   void printDeltaF();
+     166             :   void dumpStateToFile();
+     167             :   void updateDeltaF(double);
+     168             :   double getExpansion(const unsigned) const;
+     169             : 
+     170             : public:
+     171             :   explicit OPESexpanded(const ActionOptions&);
+     172             :   void calculate() override;
+     173             :   void update() override;
+     174             :   static void registerKeywords(Keywords& keys);
+     175             : };
+     176             : 
+     177       10479 : PLUMED_REGISTER_ACTION(OPESexpanded,"OPES_EXPANDED")
+     178             : 
+     179          31 : void OPESexpanded::registerKeywords(Keywords& keys)
+     180             : {
+     181          31 :   Bias::registerKeywords(keys);
+     182          31 :   keys.remove("ARG");
+     183          62 :   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");
+     184          62 :   keys.add("compulsory","PACE","how often the bias is updated");
+     185          93 :   keys.add("compulsory","OBSERVATION_STEPS","100","number of unbiased initial PACE steps to collect statistics for initialization");
+     186             : //DeltaFs and state files
+     187          62 :   keys.add("compulsory","FILE","DELTAFS","a file with the estimate of the relative \\f$\\Delta F\\f$ for each component of the target and of the global \\f$c(t)\\f$");
+     188          62 :   keys.add("compulsory","PRINT_STRIDE","100","stride for printing to DELTAFS file, in units of PACE");
+     189          62 :   keys.add("optional","FMT","specify format for DELTAFS file");
+     190          62 :   keys.add("optional","STATE_RFILE","read from this file the \\f$\\Delta F\\f$ estimates and all the info needed to RESTART the simulation");
+     191          62 :   keys.add("optional","STATE_WFILE","write to this file the \\f$\\Delta F\\f$ estimates and all the info needed to RESTART the simulation");
+     192          62 :   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)");
+     193          62 :   keys.addFlag("STORE_STATES",false,"append to STATE_WFILE instead of ovewriting it each time");
+     194             : //miscellaneous
+     195          62 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     196          62 :   keys.addFlag("WALKERS_MPI",false,"switch on MPI version of multiple walkers");
+     197          62 :   keys.addFlag("SERIAL",false,"perform calculations in serial");
+     198          31 :   keys.use("RESTART");
+     199          31 :   keys.use("UPDATE_FROM");
+     200          31 :   keys.use("UPDATE_UNTIL");
+     201             : 
+     202             : //output components
+     203          31 :   componentsAreNotOptional(keys);
+     204          62 :   keys.addOutputComponent("work","CALC_WORK","total accumulated work done by the bias");
+     205          31 : }
+     206             : 
+     207          30 : OPESexpanded::OPESexpanded(const ActionOptions&ao)
+     208             :   : PLUMED_BIAS_INIT(ao)
+     209          30 :   , isFirstStep_(true)
+     210          30 :   , counter_(0)
+     211          30 :   , ncv_(getNumberOfArguments())
+     212          30 :   , deltaF_size_(0)
+     213          30 :   , rct_(0)
+     214          30 :   , work_(0)
+     215             : {
+     216             : //set pace
+     217          30 :   parse("PACE",stride_);
+     218          30 :   parse("OBSERVATION_STEPS",obs_steps_);
+     219          30 :   plumed_massert(obs_steps_!=0,"minimum is OBSERVATION_STEPS=1");
+     220          30 :   obs_cvs_.resize(obs_steps_*ncv_);
+     221             : 
+     222             : //deltaFs file
+     223             :   std::string deltaFsFileName;
+     224          30 :   parse("FILE",deltaFsFileName);
+     225          60 :   parse("PRINT_STRIDE",print_stride_);
+     226             :   std::string fmt;
+     227          60 :   parse("FMT",fmt);
+     228             : //output checkpoint of current state
+     229             :   std::string restartFileName;
+     230          60 :   parse("STATE_RFILE",restartFileName);
+     231             :   std::string stateFileName;
+     232          30 :   parse("STATE_WFILE",stateFileName);
+     233          30 :   wStateStride_=0;
+     234          30 :   parse("STATE_WSTRIDE",wStateStride_);
+     235          30 :   storeOldStates_=false;
+     236          30 :   parseFlag("STORE_STATES",storeOldStates_);
+     237          30 :   if(wStateStride_!=0 || storeOldStates_)
+     238           5 :     plumed_massert(stateFileName.length()>0,"filename for storing simulation status not specified, use STATE_WFILE");
+     239          30 :   if(wStateStride_>0)
+     240           5 :     plumed_massert(wStateStride_>=(int)stride_,"STATE_WSTRIDE is in units of MD steps, thus should be a multiple of PACE");
+     241          30 :   if(stateFileName.length()>0 && wStateStride_==0)
+     242           1 :     wStateStride_=-1;//will print only on CPT events (checkpoints set by some MD engines, like gromacs)
+     243             : 
+     244             : //work flag
+     245          30 :   parseFlag("CALC_WORK",calc_work_);
+     246             : 
+     247             : //multiple walkers //external MW for cp2k not supported, but anyway cp2k cannot put bias on energy!
+     248          30 :   bool walkers_mpi=false;
+     249          30 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     250          30 :   if(walkers_mpi)
+     251             :   {
+     252           4 :     if(comm.Get_rank()==0) //multi_sim_comm works on first rank only
+     253             :     {
+     254           4 :       NumWalkers_=multi_sim_comm.Get_size();
+     255           4 :       walker_rank_=multi_sim_comm.Get_rank();
+     256             :     }
+     257           4 :     comm.Bcast(NumWalkers_,0); //if each walker has more than one processor update them all
+     258           4 :     comm.Bcast(walker_rank_,0);
+     259             :   }
+     260             :   else
+     261             :   {
+     262          26 :     NumWalkers_=1;
+     263          26 :     walker_rank_=0;
+     264             :   }
+     265             : 
+     266             : //parallelization stuff
+     267          30 :   NumOMP_=OpenMP::getNumThreads();
+     268          30 :   NumParallel_=comm.Get_size();
+     269          30 :   rank_=comm.Get_rank();
+     270          30 :   bool serial=false;
+     271          30 :   parseFlag("SERIAL",serial);
+     272          30 :   if(serial)
+     273             :   {
+     274           5 :     NumOMP_=1;
+     275           5 :     NumParallel_=1;
+     276           5 :     rank_=0;
+     277             :   }
+     278             : 
+     279          30 :   checkRead();
+     280             : 
+     281             : //check ECVs and link them
+     282          30 :   init_pntrToECVsClass();
+     283             : //set kbt_
+     284          30 :   kbt_=pntrToECVsClass_[0]->getKbT();
+     285          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     286          37 :     plumed_massert(std::abs(kbt_-pntrToECVsClass_[l]->getKbT())<1e-4,"must set same TEMP for each ECV");
+     287             : 
+     288             : //restart if needed
+     289          30 :   if(getRestart())
+     290             :   {
+     291             :     bool stateRestart=true;
+     292          10 :     if(restartFileName.length()==0)
+     293             :     {
+     294             :       stateRestart=false;
+     295             :       restartFileName=deltaFsFileName;
+     296             :     }
+     297          10 :     IFile ifile;
+     298          10 :     ifile.link(*this);
+     299          10 :     if(ifile.FileExist(restartFileName))
+     300             :     {
+     301          10 :       log.printf("  RESTART - make sure all ECVs used are the same as before\n");
+     302          10 :       log.printf("    restarting from: %s\n",restartFileName.c_str());
+     303          10 :       ifile.open(restartFileName);
+     304          10 :       if(stateRestart) //get all info
+     305             :       {
+     306           2 :         log.printf("    it should be a STATE file (not a DELTAFS file)\n");
+     307             :         double time; //not used
+     308           2 :         ifile.scanField("time",time);
+     309           2 :         ifile.scanField("counter",counter_);
+     310           4 :         ifile.scanField("rct",rct_);
+     311             :         std::string tmp_lambda;
+     312          66 :         while(ifile.scanField(getPntrToArgument(0)->getName(),tmp_lambda))
+     313             :         {
+     314          64 :           std::string subs="DeltaF_"+tmp_lambda;
+     315         128 :           for(unsigned jj=1; jj<ncv_; jj++)
+     316             :           {
+     317             :             tmp_lambda.clear();
+     318          64 :             ifile.scanField(getPntrToArgument(jj)->getName(),tmp_lambda);
+     319         128 :             subs+="_"+tmp_lambda;
+     320             :           }
+     321          64 :           deltaF_name_.push_back(subs);
+     322             :           double tmp_deltaF;
+     323          64 :           ifile.scanField("DeltaF",tmp_deltaF);
+     324          64 :           deltaF_.push_back(tmp_deltaF);
+     325          64 :           ifile.scanField();
+     326             :           tmp_lambda.clear();
+     327             :         }
+     328           2 :         log.printf("  successfully read %lu DeltaF values\n",deltaF_name_.size());
+     329           2 :         if(NumParallel_>1)
+     330           2 :           all_deltaF_=deltaF_;
+     331             :       }
+     332             :       else //get just deltaFs names
+     333             :       {
+     334           8 :         ifile.scanFieldList(deltaF_name_);
+     335           8 :         plumed_massert(deltaF_name_.size()>=4,"RESTART - fewer than expected FIELDS found in '"+deltaFsFileName+"' file");
+     336           8 :         plumed_massert(deltaF_name_[deltaF_name_.size()-1]=="print_stride","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     337           8 :         plumed_massert(deltaF_name_[0]=="time","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     338           8 :         plumed_massert(deltaF_name_[1]=="rct","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     339           8 :         deltaF_name_.pop_back();
+     340             :         deltaF_name_.erase(deltaF_name_.begin(),deltaF_name_.begin()+2);
+     341             :         std::size_t pos=5; //each name starts with "DeltaF"
+     342          22 :         for(unsigned j=0; j<ncv_; j++)
+     343          14 :           pos=deltaF_name_[0].find("_",pos+1); //checking only first one, hopefully is enough
+     344           8 :         plumed_massert(pos<deltaF_name_[0].length(),"RESTART - fewer '_' than expected in DeltaF fields: did you remove any CV?");
+     345           8 :         pos=deltaF_name_[0].find("_",pos+1);
+     346           8 :         plumed_massert(pos>deltaF_name_[0].length(),"RESTART - more '_' than expected in DeltaF fields: did you add new CV?");
+     347             :       }
+     348             :       //get lambdas, init ECVs and Link them
+     349          10 :       deltaF_size_=deltaF_name_.size();
+     350         525 :       auto getLambdaName=[](const std::string& name,const unsigned start,const unsigned dim)
+     351             :       {
+     352             :         std::size_t pos_start=5; //each name starts with "DeltaF"
+     353        1068 :         for(unsigned j=0; j<=start; j++)
+     354         543 :           pos_start=name.find("_",pos_start+1);
+     355             :         std::size_t pos_end=pos_start;
+     356        1527 :         for(unsigned j=0; j<dim; j++)
+     357        1002 :           pos_end=name.find("_",pos_end+1);
+     358         525 :         pos_start++; //do not include heading "_"
+     359         525 :         return name.substr(pos_start,pos_end-pos_start);
+     360             :       };
+     361          10 :       unsigned index_j=ncv_;
+     362             :       unsigned sizeSkip=1;
+     363          22 :       for(int l=pntrToECVsClass_.size()-1; l>=0; l--)
+     364             :       {
+     365          12 :         const unsigned dim_l=pntrToECVsClass_[l]->getNumberOfArguments();
+     366          12 :         index_j-=dim_l;
+     367          12 :         std::vector<std::string> lambdas_l(1);
+     368          12 :         lambdas_l[0]=getLambdaName(deltaF_name_[0],index_j,dim_l);
+     369         523 :         for(unsigned i=sizeSkip; i<deltaF_size_; i+=sizeSkip)
+     370             :         {
+     371         513 :           std::string tmp_lambda=getLambdaName(deltaF_name_[i],index_j,dim_l);
+     372         513 :           if(tmp_lambda==lambdas_l[0])
+     373             :             break;
+     374         511 :           lambdas_l.push_back(tmp_lambda);
+     375             :         }
+     376          12 :         pntrToECVsClass_[l]->initECVs_restart(lambdas_l);
+     377          12 :         sizeSkip*=lambdas_l.size();
+     378          12 :       }
+     379          10 :       plumed_massert(sizeSkip==deltaF_size_,"RESTART - this should not happen");
+     380          10 :       init_linkECVs(); //link ECVs and initializes index_k_
+     381          10 :       log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     382          10 :       obs_steps_=0; //avoid initializing again
+     383          10 :       if(stateRestart)
+     384             :       {
+     385           2 :         if(NumParallel_>1)
+     386             :         {
+     387           2 :           const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     388             :           unsigned iter=0;
+     389          34 :           for(unsigned i=start; i<start+deltaF_.size(); i++)
+     390          32 :             deltaF_[iter++]=all_deltaF_[i];
+     391             :         }
+     392             :       }
+     393             :       else //read each step
+     394             :       {
+     395           8 :         counter_=1;
+     396             :         unsigned count_lines=0;
+     397           8 :         ifile.allowIgnoredFields(); //this allows for multiple restart, but without checking for consistency between them!
+     398             :         double time;
+     399          48 :         while(ifile.scanField("time",time)) //only number of lines and last line is important
+     400             :         {
+     401             :           unsigned restart_stride;
+     402          16 :           ifile.scanField("print_stride",restart_stride);
+     403          16 :           ifile.scanField("rct",rct_);
+     404          16 :           if(NumParallel_==1)
+     405             :           {
+     406        1014 :             for(unsigned i=0; i<deltaF_size_; i++)
+     407         998 :               ifile.scanField(deltaF_name_[i],deltaF_[i]);
+     408             :           }
+     409             :           else
+     410             :           {
+     411           0 :             const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     412             :             unsigned iter=0;
+     413           0 :             for(unsigned i=start; i<start+deltaF_.size(); i++)
+     414           0 :               ifile.scanField(deltaF_name_[i],deltaF_[iter++]);
+     415             :           }
+     416          16 :           ifile.scanField();
+     417          16 :           if(count_lines>0)
+     418           8 :             counter_+=restart_stride;
+     419          16 :           count_lines++;
+     420             :         }
+     421           8 :         counter_*=NumWalkers_;
+     422           8 :         log.printf("  successfully read %u lines, up to t=%g\n",count_lines,time);
+     423             :       }
+     424          10 :       ifile.reset(false);
+     425          10 :       ifile.close();
+     426             :     }
+     427             :     else //same behaviour as METAD
+     428           0 :       plumed_merror("RESTART requested, but file '"+restartFileName+"' was not found!\n  Set RESTART=NO or provide a restart file");
+     429          10 :     if(NumWalkers_>1) //make sure that all walkers are doing the same thing
+     430             :     {
+     431           2 :       std::vector<unsigned long> all_counter(NumWalkers_);
+     432           2 :       if(comm.Get_rank()==0)
+     433           2 :         multi_sim_comm.Allgather(counter_,all_counter);
+     434           2 :       comm.Bcast(all_counter,0);
+     435             :       bool same_number_of_steps=true;
+     436           4 :       for(unsigned w=1; w<NumWalkers_; w++)
+     437           2 :         if(all_counter[0]!=all_counter[w])
+     438             :           same_number_of_steps=false;
+     439           2 :       plumed_massert(same_number_of_steps,"RESTART - not all walkers are reading the same file!");
+     440             :     }
+     441          10 :   }
+     442          20 :   else if(restartFileName.length()>0)
+     443           0 :     log.printf(" +++ WARNING +++ the provided STATE_RFILE will be ignored, since RESTART was not requested\n");
+     444             : 
+     445             : //sync all walkers to avoid opening files before reding is over (see also METAD)
+     446          30 :   comm.Barrier();
+     447          30 :   if(comm.Get_rank()==0 && walkers_mpi)
+     448           4 :     multi_sim_comm.Barrier();
+     449             : 
+     450             : //setup DeltaFs file
+     451          30 :   deltaFsOfile_.link(*this);
+     452          30 :   if(NumWalkers_>1)
+     453             :   {
+     454           4 :     if(walker_rank_>0)
+     455             :       deltaFsFileName="/dev/null"; //only first walker writes on file
+     456           8 :     deltaFsOfile_.enforceSuffix("");
+     457             :   }
+     458          30 :   deltaFsOfile_.open(deltaFsFileName);
+     459          30 :   if(fmt.length()>0)
+     460          60 :     deltaFsOfile_.fmtField(" "+fmt);
+     461             :   deltaFsOfile_.setHeavyFlush(); //do I need it?
+     462          30 :   deltaFsOfile_.addConstantField("print_stride");
+     463          30 :   deltaFsOfile_.printField("print_stride",print_stride_);
+     464             : 
+     465             : //open file for storing state
+     466          30 :   if(wStateStride_!=0)
+     467             :   {
+     468           6 :     stateOfile_.link(*this);
+     469           6 :     if(NumWalkers_>1)
+     470             :     {
+     471           0 :       if(walker_rank_>0)
+     472             :         stateFileName="/dev/null"; //only first walker writes on file
+     473           0 :       stateOfile_.enforceSuffix("");
+     474             :     }
+     475           6 :     stateOfile_.open(stateFileName);
+     476           6 :     if(fmt.length()>0)
+     477          12 :       stateOfile_.fmtField(" "+fmt);
+     478             :   }
+     479             : 
+     480             : //add output components
+     481          30 :   if(calc_work_)
+     482             :   {
+     483           6 :     addComponent("work");
+     484          12 :     componentIsNotPeriodic("work");
+     485             :   }
+     486             : 
+     487             : //printing some info
+     488          30 :   log.printf("  updating the bias with PACE = %u\n",stride_);
+     489          30 :   log.printf("  initial unbiased OBSERVATION_STEPS = %u (in units of PACE)\n",obs_steps_);
+     490          30 :   if(wStateStride_>0)
+     491           5 :     log.printf("  state checkpoints are written on file %s every %d MD steps\n",stateFileName.c_str(),wStateStride_);
+     492          30 :   if(wStateStride_==-1)
+     493           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());
+     494          30 :   if(walkers_mpi)
+     495           4 :     log.printf(" -- WALKERS_MPI: if multiple replicas are present, they will share the same bias via MPI\n");
+     496          30 :   if(NumWalkers_>1)
+     497             :   {
+     498           4 :     log.printf("  using multiple walkers\n");
+     499           4 :     log.printf("    number of walkers: %u\n",NumWalkers_);
+     500           4 :     log.printf("    walker rank: %u\n",walker_rank_);
+     501             :   }
+     502          30 :   int mw_warning=0;
+     503          30 :   if(!walkers_mpi && comm.Get_rank()==0 && multi_sim_comm.Get_size()>(int)NumWalkers_)
+     504           0 :     mw_warning=1;
+     505          30 :   comm.Bcast(mw_warning,0);
+     506          30 :   if(mw_warning) //log.printf messes up with comm, so never use it without Bcast!
+     507           0 :     log.printf(" +++ WARNING +++ multiple replicas will NOT communicate unless the flag WALKERS_MPI is used\n");
+     508          30 :   if(NumParallel_>1)
+     509           2 :     log.printf("  using multiple MPI processes per simulation: %u\n",NumParallel_);
+     510          30 :   if(NumOMP_>1)
+     511          25 :     log.printf("  using multiple OpenMP threads per simulation: %u\n",NumOMP_);
+     512          30 :   if(serial)
+     513           5 :     log.printf(" -- SERIAL: no loop parallelization, despite %d MPI processes and %u OpenMP threads available\n",comm.Get_size(),OpenMP::getNumThreads());
+     514          30 :   log.printf("  Bibliography: ");
+     515          60 :   log<<plumed.cite("M. Invernizzi, P.M. Piaggi, and M. Parrinello, Phys. Rev. X 10, 041034 (2020)");
+     516          30 :   log.printf("\n");
+     517          30 : }
+     518             : 
+     519        1490 : void OPESexpanded::calculate()
+     520             : {
+     521        1490 :   if(deltaF_size_==0) //no bias before initialization
+     522         325 :     return;
+     523             : 
+     524             : //get diffMax, to avoid over/underflow
+     525        1165 :   double diffMax=-std::numeric_limits<double>::max();
+     526        1165 :   #pragma omp parallel num_threads(NumOMP_)
+     527             :   {
+     528             :     #pragma omp for reduction(max:diffMax)
+     529             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     530             :     {
+     531             :       diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     532             :       if(diff_[i]>diffMax)
+     533             :         diffMax=diff_[i];
+     534             :     }
+     535             :   }
+     536        1165 :   if(NumParallel_>1)
+     537         102 :     comm.Max(diffMax);
+     538             : 
+     539             : //calculate the bias and the forces
+     540        1165 :   double sum=0;
+     541        1165 :   std::vector<double> der_sum_cv(ncv_,0);
+     542        1165 :   if(NumOMP_==1)
+     543             :   {
+     544        2730 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     545             :     {
+     546        2520 :       double add_i=std::exp(diff_[i]-diffMax);
+     547        2520 :       sum+=add_i;
+     548             :       //set derivatives
+     549        6960 :       for(unsigned j=0; j<ncv_; j++)
+     550        4440 :         der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     551             :     }
+     552             :   }
+     553             :   else
+     554             :   {
+     555         955 :     #pragma omp parallel num_threads(NumOMP_)
+     556             :     {
+     557             :       std::vector<double> omp_der_sum_cv(ncv_,0);
+     558             :       #pragma omp for reduction(+:sum) nowait
+     559             :       for(unsigned i=0; i<deltaF_.size(); i++)
+     560             :       {
+     561             :         double add_i=std::exp(diff_[i]-diffMax);
+     562             :         sum+=add_i;
+     563             :         //set derivatives
+     564             :         for(unsigned j=0; j<ncv_; j++)
+     565             :           omp_der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     566             :       }
+     567             :       #pragma omp critical
+     568             :       for(unsigned j=0; j<ncv_; j++)
+     569             :         der_sum_cv[j]+=omp_der_sum_cv[j];
+     570             :     }
+     571             :   }
+     572        1165 :   if(NumParallel_>1)
+     573             :   { //each MPI process has part of the full deltaF_ vector, so must Sum
+     574         102 :     comm.Sum(sum);
+     575         102 :     comm.Sum(der_sum_cv);
+     576             :   }
+     577             : 
+     578             : //set bias and forces
+     579        1165 :   const double bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     580             :   setBias(bias);
+     581        3163 :   for(unsigned j=0; j<ncv_; j++)
+     582        1998 :     setOutputForce(j,kbt_*der_sum_cv[j]/sum);
+     583             : }
+     584             : 
+     585        1490 : void OPESexpanded::update()
+     586             : {
+     587        1490 :   if(isFirstStep_) //skip very first step, as in METAD
+     588             :   {
+     589          30 :     isFirstStep_=false;
+     590          30 :     if(obs_steps_!=1) //if obs_steps_==1 go on with initialization
+     591             :       return;
+     592             :   }
+     593        1464 :   if(getStep()%stride_==0)
+     594             :   {
+     595         739 :     if(obs_steps_>0)
+     596             :     {
+     597         463 :       for(unsigned j=0; j<ncv_; j++)
+     598         304 :         obs_cvs_[counter_*ncv_+j]=getArgument(j);
+     599         159 :       counter_++;
+     600         159 :       if(counter_==obs_steps_)
+     601             :       {
+     602          20 :         log.printf("\nAction %s\n",getName().c_str());
+     603          20 :         init_fromObs();
+     604          20 :         log.printf("Finished initialization\n\n");
+     605          20 :         counter_=NumWalkers_; //all preliminary observations count 1
+     606          20 :         obs_steps_=0; //no more observation
+     607             :       }
+     608         159 :       return;
+     609             :     }
+     610             : 
+     611             :     //update averages
+     612         580 :     const double current_bias=getOutputQuantity(0); //the first value is always the bias
+     613         580 :     if(NumWalkers_==1)
+     614         500 :       updateDeltaF(current_bias);
+     615             :     else
+     616             :     {
+     617          80 :       std::vector<double> cvs(ncv_);
+     618         240 :       for(unsigned j=0; j<ncv_; j++)
+     619         160 :         cvs[j]=getArgument(j);
+     620          80 :       std::vector<double> all_bias(NumWalkers_);
+     621          80 :       std::vector<double> all_cvs(NumWalkers_*ncv_);
+     622          80 :       if(comm.Get_rank()==0)
+     623             :       {
+     624          80 :         multi_sim_comm.Allgather(current_bias,all_bias);
+     625          80 :         multi_sim_comm.Allgather(cvs,all_cvs);
+     626             :       }
+     627          80 :       comm.Bcast(all_bias,0);
+     628          80 :       comm.Bcast(all_cvs,0);
+     629         240 :       for(unsigned w=0; w<NumWalkers_; w++)
+     630             :       {
+     631             :         //calculate ECVs
+     632         160 :         unsigned index_wj=w*ncv_;
+     633         380 :         for(unsigned k=0; k<pntrToECVsClass_.size(); k++)
+     634             :         {
+     635         220 :           pntrToECVsClass_[k]->calculateECVs(&all_cvs[index_wj]);
+     636         220 :           index_wj+=pntrToECVsClass_[k]->getNumberOfArguments();
+     637             :         }
+     638         160 :         updateDeltaF(all_bias[w]);
+     639             :       }
+     640             :     }
+     641             : 
+     642             :     //write DeltaFs to file
+     643         580 :     if((counter_/NumWalkers_-1)%print_stride_==0)
+     644          44 :       printDeltaF();
+     645             : 
+     646             :     //calculate work if requested
+     647         580 :     if(calc_work_)
+     648             :     { //some copy and paste from calculate()
+     649             :       //get diffMax, to avoid over/underflow
+     650         110 :       double diffMax=-std::numeric_limits<double>::max();
+     651         110 :       #pragma omp parallel num_threads(NumOMP_)
+     652             :       {
+     653             :         #pragma omp for reduction(max:diffMax)
+     654             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     655             :         {
+     656             :           diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     657             :           if(diff_[i]>diffMax)
+     658             :             diffMax=diff_[i];
+     659             :         }
+     660             :       }
+     661         110 :       if(NumParallel_>1)
+     662          50 :         comm.Max(diffMax);
+     663             :       //calculate the bias
+     664         110 :       double sum=0;
+     665         110 :       #pragma omp parallel num_threads(NumOMP_)
+     666             :       {
+     667             :         #pragma omp for reduction(+:sum) nowait
+     668             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     669             :           sum+=std::exp(diff_[i]-diffMax);
+     670             :       }
+     671         110 :       if(NumParallel_>1)
+     672          50 :         comm.Sum(sum);
+     673         110 :       const double new_bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     674             :       //accumulate work
+     675         110 :       work_+=new_bias-current_bias;
+     676         220 :       getPntrToComponent("work")->set(work_);
+     677             :     }
+     678             :   }
+     679             : 
+     680             : //dump state if requested
+     681        1305 :   if( (wStateStride_>0 && getStep()%wStateStride_==0) || (wStateStride_==-1 && getCPT()) )
+     682          11 :     dumpStateToFile();
+     683             : }
+     684             : 
+     685          30 : void OPESexpanded::init_pntrToECVsClass()
+     686             : {
+     687          30 :   std::vector<opes::ExpansionCVs*> all_pntrToECVsClass=plumed.getActionSet().select<opes::ExpansionCVs*>();
+     688          30 :   plumed_massert(all_pntrToECVsClass.size()>0,"no Expansion CVs found");
+     689          67 :   for(unsigned j=0; j<ncv_; j++)
+     690             :   {
+     691          74 :     std::string error_notECV("all the ARGs of "+getName()+" must be Expansion Collective Variables (ECV)");
+     692          37 :     const unsigned dot_pos=getPntrToArgument(j)->getName().find(".");
+     693          37 :     plumed_massert(dot_pos<getPntrToArgument(j)->getName().size(),error_notECV+", thus contain a dot in the name");
+     694          37 :     unsigned foundECV_l=all_pntrToECVsClass.size();
+     695          44 :     for(unsigned l=0; l<all_pntrToECVsClass.size(); l++)
+     696             :     {
+     697          44 :       if(getPntrToArgument(j)->getName().substr(0,dot_pos)==all_pntrToECVsClass[l]->getLabel())
+     698             :       {
+     699             :         foundECV_l=l;
+     700          37 :         pntrToECVsClass_.push_back(all_pntrToECVsClass[l]);
+     701          37 :         std::string missing_arg="some ECV component is missing from ARG";
+     702          37 :         plumed_massert(j+all_pntrToECVsClass[l]->getNumberOfArguments()<=getNumberOfArguments(),missing_arg);
+     703          90 :         for(unsigned h=0; h<all_pntrToECVsClass[l]->getNumberOfArguments(); h++)
+     704             :         {
+     705          53 :           std::string argName=getPntrToArgument(j+h)->getName();
+     706          53 :           std::string expectedECVname=all_pntrToECVsClass[l]->getComponentsVector()[h];
+     707          53 :           plumed_massert(argName==expectedECVname,missing_arg+", or is in wrong order: given ARG="+argName+" expected ARG="+expectedECVname);
+     708             :         }
+     709          37 :         j+=all_pntrToECVsClass[l]->getNumberOfArguments()-1;
+     710             :         break;
+     711             :       }
+     712             :     }
+     713          37 :     plumed_massert(foundECV_l<all_pntrToECVsClass.size(),error_notECV);
+     714             :   }
+     715          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     716          44 :     for(unsigned ll=l+1; ll<pntrToECVsClass_.size(); ll++)
+     717           7 :       plumed_massert(pntrToECVsClass_[l]->getLabel()!=pntrToECVsClass_[ll]->getLabel(),"cannot use same ECV twice");
+     718          30 : }
+     719             : 
+     720          30 : void OPESexpanded::init_linkECVs()
+     721             : {
+     722             :   //TODO It should be possible to make all of this more straightforward (and probably also faster):
+     723             :   //     - get rid of index_k_, making it trivial for each ECV
+     724             :   //     - store the ECVs_ and derECVs_ vectors here as a contiguous vector, and use pointers in the ECV classes
+     725             :   //     Some caveats:
+     726             :   //     - ECVmultiThermalBaric has a nontrivial index_k_ to avoid duplicates. use duplicates instead
+     727             :   //     - can the ECVs be MPI parallel or it's too complicated?
+     728          30 :   plumed_massert(deltaF_size_>0,"must set deltaF_size_ before calling init_linkECVs()");
+     729          30 :   if(NumParallel_==1)
+     730          28 :     deltaF_.resize(deltaF_size_);
+     731             :   else
+     732             :   {
+     733           2 :     const unsigned extra=(rank_<(deltaF_size_%NumParallel_)?1:0);
+     734           2 :     deltaF_.resize(deltaF_size_/NumParallel_+extra);
+     735             :     //these are used when printing deltaF_ to file
+     736           2 :     all_deltaF_.resize(deltaF_size_);
+     737           2 :     all_size_.resize(NumParallel_,deltaF_size_/NumParallel_);
+     738           2 :     disp_.resize(NumParallel_);
+     739           4 :     for(unsigned r=0; r<NumParallel_-1; r++)
+     740             :     {
+     741           2 :       if(r<deltaF_size_%NumParallel_)
+     742           0 :         all_size_[r]++;
+     743           2 :       disp_[r+1]=disp_[r]+all_size_[r];
+     744             :     }
+     745             :   }
+     746          30 :   diff_.resize(deltaF_.size());
+     747          30 :   ECVs_.resize(ncv_);
+     748          30 :   derECVs_.resize(ncv_);
+     749          30 :   index_k_.resize(deltaF_.size(),std::vector<unsigned>(ncv_));
+     750             :   unsigned index_j=0;
+     751          30 :   unsigned sizeSkip=deltaF_size_;
+     752          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     753             :   {
+     754          37 :     std::vector< std::vector<unsigned> > l_index_k(pntrToECVsClass_[l]->getIndex_k());
+     755          37 :     plumed_massert(deltaF_size_%l_index_k.size()==0,"buggy ECV: mismatch between getTotNumECVs() and getIndex_k().size()");
+     756          37 :     plumed_massert(l_index_k[0].size()==pntrToECVsClass_[l]->getNumberOfArguments(),"buggy ECV: mismatch between number of ARG and underlying CVs");
+     757          37 :     sizeSkip/=l_index_k.size();
+     758          90 :     for(unsigned h=0; h<pntrToECVsClass_[l]->getNumberOfArguments(); h++)
+     759             :     {
+     760          53 :       ECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToECVs(h);
+     761          53 :       derECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToDerECVs(h);
+     762          53 :       if(NumParallel_==1)
+     763             :       {
+     764       45589 :         for(unsigned i=0; i<deltaF_size_; i++)
+     765       45540 :           index_k_[i][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     766             :       }
+     767             :       else
+     768             :       {
+     769           4 :         const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     770             :         unsigned iter=0;
+     771          68 :         for(unsigned i=start; i<start+deltaF_.size(); i++)
+     772          64 :           index_k_[iter++][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     773             :       }
+     774             :     }
+     775          37 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     776          37 :   }
+     777          30 :   plumed_massert(sizeSkip==1,"this should not happen!");
+     778          30 : }
+     779             : 
+     780          20 : void OPESexpanded::init_fromObs() //This could probably be faster and/or require less memory...
+     781             : {
+     782             : //in case of multiple walkers gather all the statistics
+     783          20 :   if(NumWalkers_>1)
+     784             :   {
+     785           2 :     std::vector<double> all_obs_cv(ncv_*obs_steps_*NumWalkers_);
+     786           2 :     if(comm.Get_rank()==0)
+     787           2 :       multi_sim_comm.Allgather(obs_cvs_,all_obs_cv);
+     788           2 :     comm.Bcast(all_obs_cv,0);
+     789           2 :     obs_cvs_=all_obs_cv; //could this lead to memory issues?
+     790           2 :     obs_steps_*=NumWalkers_;
+     791             :   }
+     792             : 
+     793             : //initialize ECVs from observations
+     794             :   unsigned index_j=0;
+     795          20 :   deltaF_size_=1;
+     796          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     797             :   {
+     798          25 :     pntrToECVsClass_[l]->initECVs_observ(obs_cvs_,ncv_,index_j);
+     799          25 :     deltaF_size_*=pntrToECVsClass_[l]->getTotNumECVs(); //ECVs from different exansions will be combined
+     800          25 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     801             :   }
+     802          20 :   plumed_massert(index_j==getNumberOfArguments(),"mismatch between number of linked CVs and number of ARG");
+     803             : //link ECVs and initialize index_k_, mapping each deltaF to a single ECVs set
+     804          20 :   init_linkECVs();
+     805             : 
+     806             : //initialize deltaF_ from obs
+     807             : //for the first point, t=0, the ECVs are calculated by initECVs_observ, setting also any initial guess
+     808             :   index_j=0;
+     809       12379 :   for(unsigned i=0; i<deltaF_.size(); i++)
+     810       56923 :     for(unsigned j=0; j<ncv_; j++)
+     811       44564 :       deltaF_[i]+=kbt_*ECVs_[j][index_k_[i][j]];
+     812         179 :   for(unsigned t=1; t<obs_steps_; t++) //starts from t=1
+     813             :   {
+     814             :     unsigned index_j=0;
+     815         383 :     for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     816             :     {
+     817         224 :       pntrToECVsClass_[l]->calculateECVs(&obs_cvs_[t*ncv_+index_j]);
+     818         224 :       index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     819             :     }
+     820      102677 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     821             :     {
+     822      102518 :       const double diff_i=(-getExpansion(i)+deltaF_[i]/kbt_-std::log(t));
+     823      102518 :       if(diff_i>0) //save exp from overflow
+     824       16071 :         deltaF_[i]-=kbt_*(diff_i+std::log1p(std::exp(-diff_i))+std::log1p(-1./(1.+t)));
+     825             :       else
+     826       86447 :         deltaF_[i]-=kbt_*(std::log1p(std::exp(diff_i))+std::log1p(-1./(1.+t)));
+     827             :     }
+     828             :   }
+     829             :   obs_cvs_.clear();
+     830             : 
+     831             : //set deltaF_name_
+     832          20 :   deltaF_name_.resize(deltaF_size_,"DeltaF");
+     833          20 :   unsigned sizeSkip=deltaF_size_;
+     834          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     835             :   {
+     836          25 :     std::vector<std::string> lambdas_l=pntrToECVsClass_[l]->getLambdas();
+     837          25 :     plumed_massert(lambdas_l.size()==pntrToECVsClass_[l]->getTotNumECVs(),"buggy ECV: mismatch between getTotNumECVs() and getLambdas().size()");
+     838          25 :     sizeSkip/=lambdas_l.size();
+     839       22457 :     for(unsigned i=0; i<deltaF_size_; i++)
+     840       44864 :       deltaF_name_[i]+="_"+lambdas_l[(i/sizeSkip)%lambdas_l.size()];
+     841          25 :   }
+     842             : 
+     843             : //print initialization to file
+     844          20 :   log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     845          20 :   printDeltaF();
+     846          20 : }
+     847             : 
+     848          64 : void OPESexpanded::printDeltaF()
+     849             : {
+     850          64 :   deltaFsOfile_.printField("time",getTime());
+     851          64 :   deltaFsOfile_.printField("rct",rct_);
+     852          64 :   if(NumParallel_==1)
+     853             :   {
+     854       23988 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     855       23926 :       deltaFsOfile_.printField(deltaF_name_[i],deltaF_[i]);
+     856             :   }
+     857             :   else
+     858             :   {
+     859           2 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     860          66 :     for(unsigned i=0; i<deltaF_size_; i++)
+     861          64 :       deltaFsOfile_.printField(deltaF_name_[i],all_deltaF_[i]);
+     862             :   }
+     863          64 :   deltaFsOfile_.printField();
+     864          64 : }
+     865             : 
+     866          11 : void OPESexpanded::dumpStateToFile()
+     867             : {
+     868             : //rewrite header or rewind file
+     869          11 :   if(storeOldStates_)
+     870           3 :     stateOfile_.clearFields();
+     871           8 :   else if(walker_rank_==0)
+     872           8 :     stateOfile_.rewind();
+     873             : //define fields
+     874          11 :   stateOfile_.addConstantField("time");
+     875          11 :   stateOfile_.addConstantField("counter");
+     876          11 :   stateOfile_.addConstantField("rct");
+     877             : //print
+     878          11 :   stateOfile_.printField("time",getTime());
+     879          11 :   stateOfile_.printField("counter",counter_);
+     880          11 :   stateOfile_.printField("rct",rct_);
+     881          11 :   if(NumParallel_>1)
+     882           0 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     883         240 :   for(unsigned i=0; i<deltaF_size_; i++)
+     884             :   {
+     885             :     std::size_t pos_start=7; //skip "DeltaF_"
+     886         687 :     for(unsigned j=0; j<ncv_; j++)
+     887             :     {
+     888             :       plumed_dbg_massert(pos_start>6,"not enought _ in deltaF_name_"+std::to_string(i-1)+" string?");
+     889         458 :       const std::size_t pos_end=deltaF_name_[i].find("_",pos_start);
+     890         916 :       stateOfile_.printField(getPntrToArgument(j)->getName(),"  "+deltaF_name_[i].substr(pos_start,pos_end-pos_start));
+     891         458 :       pos_start=pos_end+1;
+     892             :     }
+     893         229 :     if(NumParallel_==1)
+     894         458 :       stateOfile_.printField("DeltaF",deltaF_[i]);
+     895             :     else
+     896           0 :       stateOfile_.printField("DeltaF",all_deltaF_[i]);
+     897         229 :     stateOfile_.printField();
+     898             :   }
+     899             : //make sure file is written even if small
+     900          11 :   if(!storeOldStates_)
+     901           8 :     stateOfile_.flush();
+     902          11 : }
+     903             : 
+     904         660 : void OPESexpanded::updateDeltaF(double bias)
+     905             : {
+     906             :   plumed_dbg_massert(counter_>0,"deltaF_ must be initialized");
+     907         660 :   counter_++;
+     908         660 :   const double arg=(bias-rct_)/kbt_-std::log(counter_-1.);
+     909             :   double increment;
+     910         660 :   if(arg>0) //save exp from overflow
+     911          28 :     increment=kbt_*(arg+std::log1p(std::exp(-arg)));
+     912             :   else
+     913         632 :     increment=kbt_*(std::log1p(std::exp(arg)));
+     914         660 :   #pragma omp parallel num_threads(NumOMP_)
+     915             :   {
+     916             :     #pragma omp for
+     917             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     918             :     {
+     919             :       const double diff_i=(-getExpansion(i)+(bias-rct_+deltaF_[i])/kbt_-std::log(counter_-1.));
+     920             :       if(diff_i>0) //save exp from overflow
+     921             :         deltaF_[i]+=increment-kbt_*(diff_i+std::log1p(std::exp(-diff_i)));
+     922             :       else
+     923             :         deltaF_[i]+=increment-kbt_*std::log1p(std::exp(diff_i));
+     924             :     }
+     925             :   }
+     926         660 :   rct_+=increment+kbt_*std::log1p(-1./counter_);
+     927         660 : }
+     928             : 
+     929      644469 : double OPESexpanded::getExpansion(unsigned i) const
+     930             : {
+     931             :   double expansion=0;
+     932     3003062 :   for(unsigned j=0; j<ncv_; j++)
+     933     2358593 :     expansion+=ECVs_[j][index_k_[i][j]]; //the index_k could be trivially guessed for most ECVs, but unfourtunately not all
+     934      644469 :   return expansion;
+     935             : }
+     936             : 
+     937             : }
+     938             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..66d3b03f4d --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func-sort-c.html @@ -0,0 +1,209 @@ + + + + + + + + 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:79282795.8 %
Date:2024-06-10 08:19:14Functions:333497.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE11updateNlistERKSt6vectorIdSaIdEE0
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe2986createERKNS_13ActionOptionsE7
_ZN4PLMD4opes9OPESmetadINS0_11explorationEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE15dumpStateToFileEv8
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE15dumpStateToFileEv10
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe2546createERKNS_13ActionOptionsE14
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE16registerKeywordsERNS_8KeywordsE15
_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
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe254C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe254D2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe298C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe298D2Ev3473
_ZNK4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE5821
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.func.html b/coverage/opes/OPESmetad.cpp.func.html new file mode 100644 index 0000000000..9b748db2ec --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func.html @@ -0,0 +1,209 @@ + + + + + + + + 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:79282795.8 %
Date:2024-06-10 08:19:14Functions:333497.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe2546createERKNS_13ActionOptionsE14
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe254C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe254D2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe2986createERKNS_13ActionOptionsE7
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe298C2Ev3473
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe298D2Ev3473
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE11updateNlistERKSt6vectorIdSaIdEE250
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE12mergeKernelsERNS3_6kernelERKS4_277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_2760
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE15dumpStateToFileEv10
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE16registerKeywordsERNS_8KeywordsE15
_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_8KeywordsE8
_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.15
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.gcov.html b/coverage/opes/OPESmetad.cpp.gcov.html new file mode 100644 index 0000000000..ad176fec29 --- /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:79282795.8 %
Date:2024-06-10 08:19:14Functions:333497.1 %
+
+ + + + + + + + +

+
          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/Atoms.h"
+      23             : #include "tools/Communicator.h"
+      24             : #include "tools/File.h"
+      25             : #include "tools/OpenMP.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace opes {
+      29             : 
+      30             : //+PLUMEDOC OPES_BIAS OPES_METAD
+      31             : /*
+      32             : On-the-fly probability enhanced sampling (\ref OPES "OPES") with metadynamics-like target distribution \cite Invernizzi2020rethinking.
+      33             : 
+      34             : 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$.
+      35             : 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.
+      36             : Similarly to \ref METAD, \ref OPES_METAD optimizes the bias on-the-fly, with a given PACE.
+      37             : It does so by reweighting via kernel density estimation the unbiased distribution in the CV space, \f$P(\mathbf{s})\f$.
+      38             : A compression algorithm is used to prevent the number of kernels from growing linearly with the simulation time.
+      39             : The bias at step \f$n\f$ is
+      40             : \f[
+      41             : V_n(\mathbf{s}) = (1-1/\gamma)\frac{1}{\beta}\log\left(\frac{P_n(\mathbf{s})}{Z_n}+\epsilon\right)\, .
+      42             : \f]
+      43             : See Ref.\cite Invernizzi2020rethinking for a complete description of the method.
+      44             : 
+      45             : 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.
+      46             : 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.
+      47             : For this reason, it is possible to use standard umbrella sampling reweighting (see \ref REWEIGHT_BIAS) to analyse the trajectory.
+      48             : 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).
+      49             : The estimated \f$c(t)\f$ is printed for reference only, since it should converge to a fixed value as the bias converges.
+      50             : This \f$c(t)\f$ should NOT be used for reweighting.
+      51             : 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.
+      52             : 
+      53             : Notice that \ref OPES_METAD is more sensitive to degenerate CVs than \ref METAD.
+      54             : 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.
+      55             : This can be useful to diagnose problems with your collective variable.
+      56             : 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.
+      57             : 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).
+      58             : 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.
+      59             : 
+      60             : The parameter BARRIER should be set to be at least equal to the highest free energy barrier you wish to overcome.
+      61             : If it is much lower than that, you will not cross the barrier, if it is much higher, convergence might take a little longer.
+      62             : If the system has a basin that is clearly more stable than the others, it is better to start the simulation from there.
+      63             : 
+      64             : 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).
+      65             : However, notice that depending on the system this might not be the optimal choice for SIGMA.
+      66             : 
+      67             : You can target a uniform flat distribution by explicitly setting BIASFACTOR=inf.
+      68             : However, this should be useful only in very specific cases.
+      69             : 
+      70             : 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.
+      71             : To do so, one has to add those biases with the EXTRA_BIAS keyword, as in the example below.
+      72             : 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).
+      73             : 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).
+      74             : 
+      75             : Through the EXCLUDED_REGION keywork, it is possible to specify a region of CV space where no kernels will be deposited.
+      76             : This can be useful for example for making sure the bias does not modify the transition region, thus allowing for rate calculation.
+      77             : See below for an example of how to use this keyword.
+      78             : 
+      79             : 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).
+      80             : For an exact restart you must use STATE_RFILE to read a checkpoint with all the needed info.
+      81             : To save such checkpoints, define a STATE_WFILE and choose how often to print them with STATE_WSTRIDE.
+      82             : By default this file is overwritten, but you can instead append to it using the flag STORE_STATES.
+      83             : 
+      84             : Multiple walkers are supported only with MPI communication, via the keyword WALKERS_MPI.
+      85             : 
+      86             : \par Examples
+      87             : 
+      88             : 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.
+      89             : The \ref opes-metad can also be useful to get started with the method.
+      90             : 
+      91             : The following is a minimal working example:
+      92             : 
+      93             : \plumedfile
+      94             : cv: DISTANCE ATOMS=1,2
+      95             : opes: OPES_METAD ARG=cv PACE=200 BARRIER=40
+      96             : PRINT STRIDE=200 FILE=COLVAR ARG=*
+      97             : \endplumedfile
+      98             : 
+      99             : Another more articulated one:
+     100             : 
+     101             : \plumedfile
+     102             : phi: TORSION ATOMS=5,7,9,15
+     103             : psi: TORSION ATOMS=7,9,15,17
+     104             : opes: OPES_METAD ...
+     105             :   FILE=Kernels.data
+     106             :   TEMP=300
+     107             :   ARG=phi,psi
+     108             :   PACE=500
+     109             :   BARRIER=50
+     110             :   SIGMA=0.15,0.15
+     111             :   SIGMA_MIN=0.01,0.01
+     112             :   STATE_RFILE=Restart.data
+     113             :   STATE_WFILE=State.data
+     114             :   STATE_WSTRIDE=500*100
+     115             :   STORE_STATES
+     116             :   WALKERS_MPI
+     117             :   NLIST
+     118             : ...
+     119             : PRINT FMT=%g STRIDE=500 FILE=Colvar.data ARG=phi,psi,opes.*
+     120             : \endplumedfile
+     121             : 
+     122             : Next is an example of how to define a custom target distribution different from the well-tempered one.
+     123             : Here we chose to focus more on the transition state, that is around \f$\phi=0\f$.
+     124             : 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$.
+     125             : 
+     126             : \plumedfile
+     127             : phi: TORSION ATOMS=5,7,9,15
+     128             : FtgValue: CUSTOM ARG=phi PERIODIC=NO FUNC=(x/0.4)^2
+     129             : Ftg: BIASVALUE ARG=FtgValue
+     130             : opes: OPES_METAD ...
+     131             :   ARG=phi
+     132             :   PACE=500
+     133             :   BARRIER=50
+     134             :   SIGMA=0.2
+     135             :   BIASFACTOR=inf
+     136             :   EXTRA_BIAS=Ftg.bias
+     137             : ...
+     138             : PRINT FMT=%g STRIDE=500 FILE=COLVAR ARG=phi,Ftg.bias,opes.bias
+     139             : \endplumedfile
+     140             : 
+     141             : 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.
+     142             : 
+     143             : Finally, an example of how to use the EXCLUDED_REGION keyword.
+     144             : It expects a characteristic function that is different from zero in the region to be excluded.
+     145             : You can use \ref CUSTOM and a combination of the step function to define it.
+     146             : 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$:
+     147             : 
+     148             : \plumedfile
+     149             : phi: TORSION ATOMS=5,7,9,15
+     150             : psi: TORSION ATOMS=7,9,15,17
+     151             : xx: CUSTOM PERIODIC=NO ARG=phi FUNC=step(x+0.6)-step(x-0.7)
+     152             : opes: OPES_METAD ...
+     153             :   ARG=phi,psi
+     154             :   PACE=500
+     155             :   BARRIER=30
+     156             :   EXCLUDED_REGION=xx
+     157             :   NLIST
+     158             : ...
+     159             : PRINT FMT=%g STRIDE=500 FILE=COLVAR ARG=phi,psi,xx,opes.*
+     160             : \endplumedfile
+     161             : 
+     162             : */
+     163             : //+ENDPLUMEDOC
+     164             : 
+     165             : template <class mode>
+     166             : class OPESmetad : public bias::Bias {
+     167             : 
+     168             : private:
+     169             :   bool isFirstStep_;
+     170             :   unsigned NumOMP_;
+     171             :   unsigned NumParallel_;
+     172             :   unsigned rank_;
+     173             :   unsigned NumWalkers_;
+     174             :   unsigned walker_rank_;
+     175             :   unsigned long counter_;
+     176             :   std::size_t ncv_;
+     177             : 
+     178             :   double kbt_;
+     179             :   double biasfactor_;
+     180             :   double bias_prefactor_;
+     181             :   unsigned stride_;
+     182             :   std::vector<double> sigma0_;
+     183             :   std::vector<double> sigma_min_;
+     184             :   unsigned adaptive_sigma_stride_;
+     185             :   unsigned long adaptive_counter_;
+     186             :   std::vector<double> av_cv_;
+     187             :   std::vector<double> av_M2_;
+     188             :   bool fixed_sigma_;
+     189             :   bool adaptive_sigma_;
+     190             :   double epsilon_;
+     191             :   double sum_weights_;
+     192             :   double sum_weights2_;
+     193             : 
+     194             :   bool no_Zed_;
+     195             :   double Zed_;
+     196             :   double KDEnorm_;
+     197             : 
+     198             :   double threshold2_;
+     199             :   bool recursive_merge_;
+     200             : //kernels are truncated diagonal Gaussians
+     201             :   struct kernel
+     202             :   {
+     203             :     double height;
+     204             :     std::vector<double> center;
+     205             :     std::vector<double> sigma;
+     206        1050 :     kernel(double h, const std::vector<double>& c,const std::vector<double>& s):
+     207        1050 :       height(h),center(c),sigma(s) {}
+     208             :   };
+     209             :   double cutoff2_;
+     210             :   double val_at_cutoff_;
+     211             :   void mergeKernels(kernel&,const kernel&); //merge the second one into the first one
+     212             :   double evaluateKernel(const kernel&,const std::vector<double>&) const;
+     213             :   double evaluateKernel(const kernel&,const std::vector<double>&,std::vector<double>&,std::vector<double>&);
+     214             :   std::vector<kernel> kernels_; //all compressed kernels
+     215             :   OFile kernelsOfile_;
+     216             : //neighbour list stuff
+     217             :   bool nlist_;
+     218             :   double nlist_param_[2];
+     219             :   std::vector<unsigned> nlist_index_;
+     220             :   std::vector<double> nlist_center_;
+     221             :   std::vector<double> nlist_dev2_;
+     222             :   unsigned nlist_steps_;
+     223             :   bool nlist_update_;
+     224             :   bool nlist_pace_reset_;
+     225             : 
+     226             :   bool calc_work_;
+     227             :   double work_;
+     228             :   double old_KDEnorm_;
+     229             :   std::vector<kernel> delta_kernels_;
+     230             : 
+     231             :   Value* excluded_region_;
+     232             :   std::vector<Value*> extra_biases_;
+     233             : 
+     234             :   OFile stateOfile_;
+     235             :   int wStateStride_;
+     236             :   bool storeOldStates_;
+     237             : 
+     238             :   double getProbAndDerivatives(const std::vector<double>&,std::vector<double>&);
+     239             :   void addKernel(const double,const std::vector<double>&,const std::vector<double>&);
+     240             :   void addKernel(const double,const std::vector<double>&,const std::vector<double>&,const double); //also print to file
+     241             :   unsigned getMergeableKernel(const std::vector<double>&,const unsigned);
+     242             :   void updateNlist(const std::vector<double>&);
+     243             :   void dumpStateToFile();
+     244             : 
+     245             : public:
+     246             :   explicit OPESmetad(const ActionOptions&);
+     247             :   void calculate() override;
+     248             :   void update() override;
+     249             :   static void registerKeywords(Keywords& keys);
+     250             : };
+     251             : 
+     252             : struct convergence { static const bool explore=false; };
+     253             : typedef OPESmetad<convergence> OPESmetad_c;
+     254       10447 : PLUMED_REGISTER_ACTION(OPESmetad_c,"OPES_METAD")
+     255             : 
+     256             : //OPES_METAD_EXPLORE is very similar from the point of view of the code,
+     257             : //but conceptually it is better to make it a separate BIAS action
+     258             : 
+     259             : //+PLUMEDOC OPES_BIAS OPES_METAD_EXPLORE
+     260             : /*
+     261             : On-the-fly probability enhanced sampling (\ref OPES "OPES") with well-tempered target distribution, exploration mode \cite Invernizzi2022explore .
+     262             : 
+     263             : 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$.
+     264             : 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.
+     265             : The bias at step \f$n\f$ is
+     266             : \f[
+     267             : V_n(\mathbf{s}) = (\gamma-1)\frac{1}{\beta}\log\left(\frac{p^{\text{WT}}_n(\mathbf{s})}{Z_n}+\epsilon\right)\, .
+     268             : \f]
+     269             : See Ref.\cite Invernizzi2022explore for a complete description of the method.
+     270             : 
+     271             : 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.
+     272             : Given enough simulation time, both will converge to the same bias potential but they do so in a qualitatively different way.
+     273             : 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.
+     274             : This goes at the expenses of a typically slower convergence of the reweight estimate.
+     275             : \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.
+     276             : 
+     277             : Similarly to \ref OPES_METAD, also \ref OPES_METAD_EXPLORE uses a kernel density estimation with the same on-the-fly compression algorithm.
+     278             : The only difference is that the kernels are not weighted, since it estimates the sampled distribution and not the reweighted unbiased one.
+     279             : 
+     280             : 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.
+     281             : 
+     282             : \par Examples
+     283             : 
+     284             : The following is a minimal working example:
+     285             : 
+     286             : \plumedfile
+     287             : cv: DISTANCE ATOMS=1,2
+     288             : opes: OPES_METAD_EXPLORE ARG=cv PACE=500 BARRIER=40
+     289             : PRINT STRIDE=100 FILE=COLVAR ARG=cv,opes.*
+     290             : \endplumedfile
+     291             : */
+     292             : //+ENDPLUMEDOC
+     293             : 
+     294             : struct exploration { static const bool explore=true; };
+     295             : typedef OPESmetad<exploration> OPESmetad_e;
+     296             : // For some reason, this is not seen correctly by cppcheck
+     297             : // cppcheck-suppress unknownMacro
+     298       10433 : PLUMED_REGISTER_ACTION(OPESmetad_e,"OPES_METAD_EXPLORE")
+     299             : 
+     300             : template <class mode>
+     301          23 : void OPESmetad<mode>::registerKeywords(Keywords& keys)
+     302             : {
+     303          23 :   Bias::registerKeywords(keys);
+     304          23 :   keys.use("ARG");
+     305          46 :   keys.add("compulsory","TEMP","-1","temperature. If not set, it is taken from MD engine, but not all MD codes provide it");
+     306          46 :   keys.add("compulsory","PACE","the frequency for kernel deposition");
+     307          46 :   keys.add("compulsory","SIGMA","ADAPTIVE","the initial widths of the kernels. If not set, adaptive sigma will be used with the given ADAPTIVE_SIGMA_STRIDE");
+     308          46 :   keys.add("compulsory","BARRIER","the free energy barrier to be overcome. It is used to set BIASFACTOR, EPSILON, and KERNEL_CUTOFF to reasonable values");
+     309          69 :   keys.add("compulsory","COMPRESSION_THRESHOLD","1","merge kernels if closer than this threshold, in units of sigma");
+     310             : //extra options
+     311          69 :   keys.add("optional","ADAPTIVE_SIGMA_STRIDE","number of steps for measuring adaptive sigma. Default is 10xPACE");
+     312          46 :   keys.add("optional","SIGMA_MIN","never reduce SIGMA below this value");
+     313          23 :   std::string info_biasfactor("the \\f$\\gamma\\f$ bias factor used for the well-tempered target distribution. ");
+     314             :   if(mode::explore)
+     315             :     info_biasfactor+="Cannot be 'inf'";
+     316             :   else
+     317             :     info_biasfactor+="Set to 'inf' for uniform flat target";
+     318          46 :   keys.add("optional","BIASFACTOR",info_biasfactor);
+     319          46 :   keys.add("optional","EPSILON","the value of the regularization constant for the probability");
+     320          46 :   keys.add("optional","KERNEL_CUTOFF","truncate kernels at this distance, in units of sigma");
+     321          69 :   keys.add("optional","NLIST_PARAMETERS","( default=3.0,0.5 ) the two cutoff parameters for the kernels neighbor list");
+     322          46 :   keys.addFlag("NLIST",false,"use neighbor list for kernels summation, faster but experimental");
+     323          46 :   keys.addFlag("NLIST_PACE_RESET",false,"force the reset of the neighbor list at each PACE. Can be useful with WALKERS_MPI");
+     324          46 :   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");
+     325          46 :   keys.addFlag("RECURSIVE_MERGE_OFF",false,"do not recursively attempt kernel merging when a new one is added");
+     326          46 :   keys.addFlag("NO_ZED",false,"do not normalize over the explored CV space, \\f$Z_n=1\\f$");
+     327             : //kernels and state files
+     328          46 :   keys.add("compulsory","FILE","KERNELS","a file in which the list of all deposited kernels is stored");
+     329          46 :   keys.add("optional","FMT","specify format for KERNELS file");
+     330          46 :   keys.add("optional","STATE_RFILE","read from this file the compressed kernels and all the info needed to RESTART the simulation");
+     331          46 :   keys.add("optional","STATE_WFILE","write to this file the compressed kernels and all the info needed to RESTART the simulation");
+     332          46 :   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)");
+     333          46 :   keys.addFlag("STORE_STATES",false,"append to STATE_WFILE instead of ovewriting it each time");
+     334             : //miscellaneous
+     335          46 :   keys.add("optional","EXCLUDED_REGION","kernels are not deposited when the action provided here has a nonzero value, see example above");
+     336             :   if(!mode::explore)
+     337          30 :     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)");
+     338          46 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     339          46 :   keys.addFlag("WALKERS_MPI",false,"switch on MPI version of multiple walkers");
+     340          46 :   keys.addFlag("SERIAL",false,"perform calculations in serial");
+     341          23 :   keys.use("RESTART");
+     342          23 :   keys.use("UPDATE_FROM");
+     343          23 :   keys.use("UPDATE_UNTIL");
+     344             : 
+     345             : //output components
+     346          46 :   keys.addOutputComponent("rct","default","estimate of \\f$c(t)\\f$: \\f$\\frac{1}{\\beta}\\log \\langle e^{\\beta V} \\rangle\\f$, should become flat as the simulation converges. Do NOT use for reweighting");
+     347          46 :   keys.addOutputComponent("zed","default","estimate of \\f$Z_n\\f$, should become flat once no new CV-space region is explored");
+     348          46 :   keys.addOutputComponent("neff","default","effective sample size");
+     349          46 :   keys.addOutputComponent("nker","default","total number of compressed kernels used to represent the bias");
+     350          46 :   keys.addOutputComponent("work","CALC_WORK","total accumulated work done by the bias");
+     351          46 :   keys.addOutputComponent("nlker","NLIST","number of kernels in the neighbor list");
+     352          69 :   keys.addOutputComponent("nlsteps","NLIST","number of steps from last neighbor list update");
+     353          23 : }
+     354             : 
+     355             : template <class mode>
+     356          21 : OPESmetad<mode>::OPESmetad(const ActionOptions& ao)
+     357             :   : PLUMED_BIAS_INIT(ao)
+     358          21 :   , isFirstStep_(true)
+     359          21 :   , counter_(1)
+     360          21 :   , ncv_(getNumberOfArguments())
+     361          21 :   , Zed_(1)
+     362          21 :   , work_(0)
+     363          21 :   , excluded_region_(NULL)
+     364             : {
+     365          42 :   std::string error_in_input1("Error in input in action "+getName()+" with label "+getLabel()+": the keyword ");
+     366          21 :   std::string error_in_input2(" could not be read correctly");
+     367             : 
+     368             : //set kbt_
+     369          21 :   const double kB=plumed.getAtoms().getKBoltzmann();
+     370          21 :   kbt_=plumed.getAtoms().getKbT();
+     371          21 :   double temp=-1;
+     372          21 :   parse("TEMP",temp);
+     373          21 :   if(temp>0)
+     374             :   {
+     375          21 :     if(kbt_>0 && std::abs(kbt_-kB*temp)>1e-4)
+     376           0 :       log.printf(" +++ WARNING +++ using TEMP=%g while MD engine uses %g\n",temp,kbt_/kB);
+     377          21 :     kbt_=kB*temp;
+     378             :   }
+     379          21 :   plumed_massert(kbt_>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     380             : 
+     381             : //other compulsory input
+     382          21 :   parse("PACE",stride_);
+     383             : 
+     384          21 :   double barrier=0;
+     385          21 :   parse("BARRIER",barrier);
+     386          21 :   plumed_massert(barrier>=0,"the BARRIER should be greater than zero");
+     387             : 
+     388          21 :   biasfactor_=barrier/kbt_;
+     389             :   std::string biasfactor_str;
+     390          42 :   parse("BIASFACTOR",biasfactor_str);
+     391          38 :   if(biasfactor_str=="inf" || biasfactor_str=="INF")
+     392             :   {
+     393           4 :     biasfactor_=std::numeric_limits<double>::infinity();
+     394           4 :     bias_prefactor_=1;
+     395             :   }
+     396             :   else
+     397             :   {
+     398          17 :     if(biasfactor_str.length()>0)
+     399           3 :       plumed_massert(Tools::convertNoexcept(biasfactor_str,biasfactor_),error_in_input1+"BIASFACTOR"+error_in_input2);
+     400          17 :     plumed_massert(biasfactor_>1,"BIASFACTOR must be greater than one (use 'inf' for uniform target)");
+     401          17 :     bias_prefactor_=1-1./biasfactor_;
+     402             :   }
+     403             :   if(mode::explore)
+     404             :   {
+     405           7 :     plumed_massert(!std::isinf(biasfactor_),"BIASFACTOR=inf is not compatible with EXPLORE mode");
+     406           7 :     bias_prefactor_=biasfactor_-1;
+     407             :   }
+     408             : 
+     409          21 :   adaptive_sigma_=false;
+     410          21 :   adaptive_sigma_stride_=0;
+     411          42 :   parse("ADAPTIVE_SIGMA_STRIDE",adaptive_sigma_stride_);
+     412             :   std::vector<std::string> sigma_str;
+     413          21 :   parseVector("SIGMA",sigma_str);
+     414          21 :   sigma0_.resize(ncv_);
+     415             :   double dummy;
+     416          21 :   if(sigma_str.size()==1 && !Tools::convertNoexcept(sigma_str[0],dummy))
+     417             :   {
+     418          11 :     plumed_massert(sigma_str[0]=="ADAPTIVE" || sigma_str[0]=="adaptive",error_in_input1+"SIGMA"+error_in_input2);
+     419          11 :     plumed_massert(!std::isinf(biasfactor_),"cannot use BIASFACTOR=inf with adaptive SIGMA");
+     420          11 :     adaptive_counter_=0;
+     421          11 :     if(adaptive_sigma_stride_==0)
+     422           2 :       adaptive_sigma_stride_=10*stride_; //NB: this is arbitrary, chosen from few tests
+     423          11 :     av_cv_.resize(ncv_,0);
+     424          11 :     av_M2_.resize(ncv_,0);
+     425          11 :     plumed_massert(adaptive_sigma_stride_>=stride_,"better to chose ADAPTIVE_SIGMA_STRIDE > PACE");
+     426          11 :     adaptive_sigma_=true;
+     427             :   }
+     428             :   else
+     429             :   {
+     430          10 :     plumed_massert(sigma_str.size()==ncv_,"number of SIGMA parameters does not match number of arguments");
+     431          10 :     plumed_massert(adaptive_sigma_stride_==0,"if SIGMA is not ADAPTIVE you cannot set an ADAPTIVE_SIGMA_STRIDE");
+     432          29 :     for(unsigned i=0; i<ncv_; i++)
+     433             :     {
+     434          19 :       plumed_massert(Tools::convertNoexcept(sigma_str[i],sigma0_[i]),error_in_input1+"SIGMA"+error_in_input2);
+     435             :       if(mode::explore)
+     436           6 :         sigma0_[i]*=std::sqrt(biasfactor_); //the sigma of the target is broader Ftg(s)=1/gamma*F(s)
+     437             :     }
+     438             :   }
+     439          42 :   parseVector("SIGMA_MIN",sigma_min_);
+     440          21 :   plumed_massert(sigma_min_.size()==0 || sigma_min_.size()==ncv_,"number of SIGMA_MIN does not match number of arguments");
+     441          21 :   if(sigma_min_.size()>0 && !adaptive_sigma_)
+     442             :   {
+     443           3 :     for(unsigned i=0; i<ncv_; i++)
+     444           2 :       plumed_massert(sigma_min_[i]<=sigma0_[i],"SIGMA_MIN should be smaller than SIGMA");
+     445             :   }
+     446             : 
+     447          21 :   epsilon_=std::exp(-barrier/bias_prefactor_/kbt_);
+     448          21 :   parse("EPSILON",epsilon_);
+     449          21 :   plumed_massert(epsilon_>0,"you must choose a value for EPSILON greater than zero. Is your BARRIER too high?");
+     450          21 :   sum_weights_=std::pow(epsilon_,bias_prefactor_); //to avoid NANs we start with counter_=1 and w0=exp(beta*V0)
+     451          21 :   sum_weights2_=sum_weights_*sum_weights_;
+     452             : 
+     453          21 :   double cutoff=sqrt(2.*barrier/bias_prefactor_/kbt_);
+     454             :   if(mode::explore)
+     455           7 :     cutoff=sqrt(2.*barrier/kbt_); //otherwise it is too small
+     456          21 :   parse("KERNEL_CUTOFF",cutoff);
+     457          21 :   plumed_massert(cutoff>0,"you must choose a value for KERNEL_CUTOFF greater than zero");
+     458          21 :   cutoff2_=cutoff*cutoff;
+     459          21 :   val_at_cutoff_=std::exp(-0.5*cutoff2_);
+     460             : 
+     461          21 :   threshold2_=1;
+     462          21 :   parse("COMPRESSION_THRESHOLD",threshold2_);
+     463          21 :   threshold2_*=threshold2_;
+     464          21 :   if(threshold2_!=0)
+     465          21 :     plumed_massert(threshold2_>0 && threshold2_<cutoff2_,"COMPRESSION_THRESHOLD cannot be bigger than the KERNEL_CUTOFF");
+     466             : 
+     467             : //setup neighbor list
+     468          21 :   nlist_=false;
+     469          21 :   parseFlag("NLIST",nlist_);
+     470          21 :   nlist_pace_reset_=false;
+     471          21 :   parseFlag("NLIST_PACE_RESET",nlist_pace_reset_);
+     472          21 :   if(nlist_pace_reset_)
+     473           2 :     nlist_=true;
+     474             :   std::vector<double> nlist_param;
+     475          42 :   parseVector("NLIST_PARAMETERS",nlist_param);
+     476          21 :   if(nlist_param.size()==0)
+     477             :   {
+     478          17 :     nlist_param_[0]=3.0;//*cutoff2_ -> max distance of neighbors
+     479          17 :     nlist_param_[1]=0.5;//*nlist_dev2_[i] -> condition for rebuilding
+     480             :   }
+     481             :   else
+     482             :   {
+     483           4 :     nlist_=true;
+     484           4 :     plumed_massert(nlist_param.size()==2,"two cutoff parameters are needed for the neighbor list");
+     485           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");
+     486           4 :     const double min_PARAM_1=(1.-1./std::sqrt(nlist_param[0]))+0.16;
+     487           4 :     plumed_massert(nlist_param[1]>0,"the second of NLIST_PARAMETERS must be greater than 0");
+     488           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));
+     489           4 :     nlist_param_[0]=nlist_param[0];
+     490           4 :     nlist_param_[1]=nlist_param[1];
+     491             :   }
+     492          21 :   nlist_center_.resize(ncv_);
+     493          21 :   nlist_dev2_.resize(ncv_,0.);
+     494          21 :   nlist_steps_=0;
+     495          21 :   nlist_update_=true;
+     496             : 
+     497             : //optional stuff
+     498          21 :   no_Zed_=false;
+     499          21 :   parseFlag("NO_ZED",no_Zed_);
+     500          21 :   if(no_Zed_)
+     501             :   { //this makes it more gentle in the initial phase
+     502           6 :     sum_weights_=1;
+     503           6 :     sum_weights2_=1;
+     504             :   }
+     505          21 :   fixed_sigma_=false;
+     506          21 :   parseFlag("FIXED_SIGMA",fixed_sigma_);
+     507          21 :   bool recursive_merge_off=false;
+     508          21 :   parseFlag("RECURSIVE_MERGE_OFF",recursive_merge_off);
+     509          21 :   recursive_merge_=!recursive_merge_off;
+     510          42 :   parseFlag("CALC_WORK",calc_work_);
+     511             : 
+     512             : //options involving extra arguments
+     513             :   std::vector<Value*> args;
+     514          42 :   parseArgumentList("EXCLUDED_REGION",args);
+     515          21 :   if(args.size()>0)
+     516             :   {
+     517           2 :     plumed_massert(args.size()==1,"only one characteristic function should define the region to be excluded");
+     518           2 :     requestExtraDependencies(args);
+     519           2 :     excluded_region_=args[0];
+     520             :   }
+     521             :   if(!mode::explore)
+     522             :   {
+     523          28 :     parseArgumentList("EXTRA_BIAS",extra_biases_);
+     524          14 :     if(extra_biases_.size()>0)
+     525           2 :       requestExtraDependencies(extra_biases_);
+     526             :   }
+     527             : 
+     528             : //kernels file
+     529             :   std::string kernelsFileName;
+     530          42 :   parse("FILE",kernelsFileName);
+     531             :   std::string fmt;
+     532          42 :   parse("FMT",fmt);
+     533             : 
+     534             : //output checkpoint of current state
+     535             :   std::string restartFileName;
+     536          42 :   parse("STATE_RFILE",restartFileName);
+     537             :   std::string stateFileName;
+     538          21 :   parse("STATE_WFILE",stateFileName);
+     539          21 :   wStateStride_=0;
+     540          21 :   parse("STATE_WSTRIDE",wStateStride_);
+     541          21 :   storeOldStates_=false;
+     542          21 :   parseFlag("STORE_STATES",storeOldStates_);
+     543          21 :   if(wStateStride_!=0 || storeOldStates_)
+     544          10 :     plumed_massert(stateFileName.length()>0,"filename for storing simulation status not specified, use STATE_WFILE");
+     545          21 :   if(wStateStride_>0)
+     546          10 :     plumed_massert(wStateStride_>=(int)stride_,"STATE_WSTRIDE is in units of MD steps, thus it is suggested to use a multiple of PACE");
+     547          21 :   if(stateFileName.length()>0 && wStateStride_==0)
+     548           1 :     wStateStride_=-1;//will print only on CPT events (checkpoints set by some MD engines, like gromacs)
+     549             : 
+     550             : //multiple walkers //TODO implement also external mw for cp2k
+     551          21 :   bool walkers_mpi=false;
+     552          21 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     553          21 :   if(walkers_mpi)
+     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 %lu 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          21 :   addComponent("rct");
+     829          21 :   componentIsNotPeriodic("rct");
+     830          21 :   getPntrToComponent("rct")->set(kbt_*std::log(sum_weights_/counter_));
+     831          21 :   addComponent("zed");
+     832          21 :   componentIsNotPeriodic("zed");
+     833          21 :   getPntrToComponent("zed")->set(Zed_);
+     834          21 :   addComponent("neff");
+     835          21 :   componentIsNotPeriodic("neff");
+     836          21 :   getPntrToComponent("neff")->set(std::pow(1+sum_weights_,2)/(1+sum_weights2_));
+     837          21 :   addComponent("nker");
+     838          21 :   componentIsNotPeriodic("nker");
+     839          21 :   getPntrToComponent("nker")->set(kernels_.size());
+     840          21 :   if(calc_work_)
+     841             :   {
+     842           7 :     addComponent("work");
+     843          14 :     componentIsNotPeriodic("work");
+     844             :   }
+     845          21 :   if(nlist_)
+     846             :   {
+     847           5 :     addComponent("nlker");
+     848           5 :     componentIsNotPeriodic("nlker");
+     849           5 :     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          35 :     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             :   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         388 :       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             :           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         134 :     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.15
+
+ + + diff --git a/coverage/opes/index-sort-f.html b/coverage/opes/index-sort-f.html new file mode 100644 index 0000000000..d127bd18e7 --- /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:2157224496.1 %
Date:2024-06-10 08:19:14Functions:13514493.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ExpansionCVs.cpp +
91.9%91.9%
+
91.9 %102 / 11190.0 %9 / 10
ECVlinear.cpp +
95.8%95.8%
+
95.8 %115 / 12092.3 %12 / 13
ECVmultiThermal.cpp +
95.6%95.6%
+
95.6 %108 / 11392.3 %12 / 13
ECVumbrellasFile.cpp +
98.3%98.3%
+
98.3 %119 / 12192.3 %12 / 13
ECVumbrellasLine.cpp +
98.5%98.5%
+
98.5 %130 / 13292.3 %12 / 13
ECVcustom.cpp +
92.1%92.1%
+
92.1 %93 / 10192.9 %13 / 14
ECVmultiThermalBaric.cpp +
96.7%96.7%
+
96.7 %264 / 27393.3 %14 / 15
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %430 / 44293.8 %15 / 16
OPESmetad.cpp +
95.8%95.8%
+
95.8 %792 / 82797.1 %33 / 34
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/index-sort-l.html b/coverage/opes/index-sort-l.html new file mode 100644 index 0000000000..e4fdcfd33f --- /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:2157224496.1 %
Date:2024-06-10 08:19:14Functions:13514493.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ExpansionCVs.cpp +
91.9%91.9%
+
91.9 %102 / 11190.0 %9 / 10
ECVcustom.cpp +
92.1%92.1%
+
92.1 %93 / 10192.9 %13 / 14
ECVmultiThermal.cpp +
95.6%95.6%
+
95.6 %108 / 11392.3 %12 / 13
OPESmetad.cpp +
95.8%95.8%
+
95.8 %792 / 82797.1 %33 / 34
ECVlinear.cpp +
95.8%95.8%
+
95.8 %115 / 12092.3 %12 / 13
ECVmultiThermalBaric.cpp +
96.7%96.7%
+
96.7 %264 / 27393.3 %14 / 15
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %430 / 44293.8 %15 / 16
ECVumbrellasFile.cpp +
98.3%98.3%
+
98.3 %119 / 12192.3 %12 / 13
ECVumbrellasLine.cpp +
98.5%98.5%
+
98.5 %130 / 13292.3 %12 / 13
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/opes/index.html b/coverage/opes/index.html new file mode 100644 index 0000000000..ec522c371c --- /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:2157224496.1 %
Date:2024-06-10 08:19:14Functions:13514493.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ECVcustom.cpp +
92.1%92.1%
+
92.1 %93 / 10192.9 %13 / 14
ECVlinear.cpp +
95.8%95.8%
+
95.8 %115 / 12092.3 %12 / 13
ECVmultiThermal.cpp +
95.6%95.6%
+
95.6 %108 / 11392.3 %12 / 13
ECVmultiThermalBaric.cpp +
96.7%96.7%
+
96.7 %264 / 27393.3 %14 / 15
ECVumbrellasFile.cpp +
98.3%98.3%
+
98.3 %119 / 12192.3 %12 / 13
ECVumbrellasLine.cpp +
98.5%98.5%
+
98.5 %130 / 13292.3 %12 / 13
ExpansionCVs.cpp +
91.9%91.9%
+
91.9 %102 / 11190.0 %9 / 10
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %430 / 44293.8 %15 / 16
OPESmetad.cpp +
95.8%95.8%
+
95.8 %792 / 82797.1 %33 / 34
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..772b584039 --- /dev/null +++ b/coverage/pamm/HBPammHydrogens.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:527470.3 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm15HBPammHydrogens10isPeriodicEv0
_ZN4PLMD4pamm15HBPammHydrogensC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe606createERKNS_13ActionOptionsE2
_ZN4PLMD4pamm15HBPammHydrogensC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm15HBPammHydrogens16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD4pamm15HBPammHydrogens7computeERKjRNS_11multicolvar13AtomValuePackE134
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe60C2Ev3473
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe60D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/HBPammHydrogens.cpp.func.html b/coverage/pamm/HBPammHydrogens.cpp.func.html new file mode 100644 index 0000000000..4aaebe0aef --- /dev/null +++ b/coverage/pamm/HBPammHydrogens.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:527470.3 %
Date:2024-06-10 08:19:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe606createERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe60C2Ev3473
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe60D2Ev3473
_ZN4PLMD4pamm15HBPammHydrogens10isPeriodicEv0
_ZN4PLMD4pamm15HBPammHydrogens16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4pamm15HBPammHydrogensC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm15HBPammHydrogensC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4pamm15HBPammHydrogens7computeERKjRNS_11multicolvar13AtomValuePackE134
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/HBPammHydrogens.cpp.gcov.html b/coverage/pamm/HBPammHydrogens.cpp.gcov.html new file mode 100644 index 0000000000..c43aca79ae --- /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:527470.3 %
Date:2024-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_ACTION(HBPammHydrogens,"HBPAMM_SH")
+      61             : 
+      62           3 : void HBPammHydrogens::registerKeywords( Keywords& keys ) {
+      63           3 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      64           6 :   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           6 :   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           6 :   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           6 :   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           6 :   keys.add("numbered","CLUSTERS","the name of the file that contains the definitions of all the kernels for PAMM");
+      82           6 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+      83           6 :   keys.reset_style("CLUSTERS","compulsory");
+      84             :   // Use actionWithDistributionKeywords
+      85          12 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+      86          12 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      87          12 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("SUM");
+      88           3 : }
+      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.15
+
+ + + 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 0000000000..6282645fd2 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:394390.7 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm12HBPammMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE2
_ZN4PLMD4pamm12HBPammMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe616createERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12HBPammMatrix16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe61C2Ev3473
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe61D2Ev3473
_ZNK4PLMD4pamm12HBPammMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.func.html b/coverage/pamm/HBPammMatrix.cpp.func.html new file mode 100644 index 0000000000..de593abb34 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:394390.7 %
Date:2024-06-10 08:19:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE2
_ZN4PLMD4pamm12HBPammMatrix16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4pamm12HBPammMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12HBPammMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe616createERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe61C2Ev3473
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe61D2Ev3473
_ZNK4PLMD4pamm12HBPammMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.gcov.html b/coverage/pamm/HBPammMatrix.cpp.gcov.html new file mode 100644 index 0000000000..d95dd7eaab --- /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:394390.7 %
Date:2024-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_ACTION(HBPammMatrix,"HBPAMM_MATRIX")
+      62             : 
+      63           3 : void HBPammMatrix::registerKeywords( Keywords& keys ) {
+      64           3 :   adjmat::AdjacencyMatrixBase::registerKeywords( keys );
+      65           6 :   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           6 :   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           6 :   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           6 :   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           6 :   keys.add("numbered","CLUSTERS","the name of the file that contains the definitions of all the kernels for PAMM");
+      84           6 :   keys.reset_style("CLUSTERS","compulsory"); keys.use("SUM");
+      85           6 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+      86           3 : }
+      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.15
+
+ + + 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 0000000000..64a73849a4 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/pamm/HBPammObject.cpp.func.html b/coverage/pamm/HBPammObject.cpp.func.html new file mode 100644 index 0000000000..9340b924ad --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/pamm/HBPammObject.cpp.gcov.html b/coverage/pamm/HBPammObject.cpp.gcov.html new file mode 100644 index 0000000000..6d7a0ab069 --- /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-06-10 08:19:14Functions: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          88 :     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.15
+
+ + + 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 0000000000..d1ac9d3e5d --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/HBPammObject.h.func.html b/coverage/pamm/HBPammObject.h.func.html new file mode 100644 index 0000000000..74d0394704 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/HBPammObject.h.gcov.html b/coverage/pamm/HBPammObject.h.gcov.html new file mode 100644 index 0000000000..e2c2900c21 --- /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-06-10 08:19:14Functions: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;
+      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.15
+
+ + + 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 0000000000..e80931055d --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:506576.9 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm4PAMM14getCentralAtomEv0
_ZN4PLMD4pamm4PAMM15calculateWeightERNS_11multicolvar13AtomValuePackE0
_ZN4PLMD4pamm4PAMMC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe1326createERKNS_13ActionOptionsE2
_ZN4PLMD4pamm4PAMMC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm4PAMM16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4pamm4PAMM10isPeriodicEv16
_ZNK4PLMD4pamm4PAMM7computeERKjRNS_11multicolvar13AtomValuePackE28
_ZNK4PLMD4pamm4PAMM21getNumberOfQuantitiesEv86
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe132C2Ev3473
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe132D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.func.html b/coverage/pamm/PAMM.cpp.func.html new file mode 100644 index 0000000000..b1c195ffe2 --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:506576.9 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe1326createERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe132C2Ev3473
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe132D2Ev3473
_ZN4PLMD4pamm4PAMM10isPeriodicEv16
_ZN4PLMD4pamm4PAMM14getCentralAtomEv0
_ZN4PLMD4pamm4PAMM15calculateWeightERNS_11multicolvar13AtomValuePackE0
_ZN4PLMD4pamm4PAMM16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4pamm4PAMMC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm4PAMMC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4pamm4PAMM21getNumberOfQuantitiesEv86
_ZNK4PLMD4pamm4PAMM7computeERKjRNS_11multicolvar13AtomValuePackE28
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.gcov.html b/coverage/pamm/PAMM.cpp.gcov.html new file mode 100644 index 0000000000..d4fc528ef0 --- /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:506576.9 %
Date:2024-06-10 08:19:14Functions:81172.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 "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       10423 : PLUMED_REGISTER_ACTION(PAMM,"PAMM")
+     133             : 
+     134           3 : void PAMM::registerKeywords( Keywords& keys ) {
+     135           3 :   MultiColvarBase::registerKeywords( keys );
+     136           6 :   keys.add("compulsory","DATA","the multicolvars from which the pamm coordinates are calculated");
+     137           6 :   keys.add("compulsory","CLUSTERS","the name of the file that contains the definitions of all the clusters");
+     138           6 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+     139          15 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("SUM"); keys.use("LESS_THAN"); keys.use("HISTOGRAM");
+     140          21 :   keys.use("MIN"); keys.use("MAX"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("ALT_MIN"); keys.use("BETWEEN"); keys.use("MOMENTS");
+     141           3 :   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           3 :   keys.remove("ALL_INPUT_SAME_TYPE");
+     157           3 : }
+     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 :       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.15
+
+ + + 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 0000000000..37ef194fef --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/pamm/PammObject.cpp.func.html b/coverage/pamm/PammObject.cpp.func.html new file mode 100644 index 0000000000..c3d9f305b5 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/pamm/PammObject.cpp.gcov.html b/coverage/pamm/PammObject.cpp.gcov.html new file mode 100644 index 0000000000..37e2890085 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..cb292005cd --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/PammObject.h.func.html b/coverage/pamm/PammObject.h.func.html new file mode 100644 index 0000000000..0391588f22 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/pamm/PammObject.h.gcov.html b/coverage/pamm/PammObject.h.gcov.html new file mode 100644 index 0000000000..366e9982db --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/pamm/index-sort-f.html b/coverage/pamm/index-sort-f.html new file mode 100644 index 0000000000..fd49d03e2c --- /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:21526481.4 %
Date:2024-06-10 08:19:14Functions:273479.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PAMM.cpp +
76.9%76.9%
+
76.9 %50 / 6572.7 %8 / 11
PammObject.cpp +
82.6%82.6%
+
82.6 %38 / 4675.0 %3 / 4
HBPammHydrogens.cpp +
70.3%70.3%
+
70.3 %52 / 7475.0 %6 / 8
HBPammMatrix.cpp +
90.7%90.7%
+
90.7 %39 / 4387.5 %7 / 8
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.15
+
+ + + diff --git a/coverage/pamm/index-sort-l.html b/coverage/pamm/index-sort-l.html new file mode 100644 index 0000000000..47c3e91490 --- /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:21526481.4 %
Date:2024-06-10 08:19:14Functions:273479.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
HBPammHydrogens.cpp +
70.3%70.3%
+
70.3 %52 / 7475.0 %6 / 8
PAMM.cpp +
76.9%76.9%
+
76.9 %50 / 6572.7 %8 / 11
PammObject.cpp +
82.6%82.6%
+
82.6 %38 / 4675.0 %3 / 4
HBPammMatrix.cpp +
90.7%90.7%
+
90.7 %39 / 4387.5 %7 / 8
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.15
+
+ + + diff --git a/coverage/pamm/index.html b/coverage/pamm/index.html new file mode 100644 index 0000000000..b9c118801b --- /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:21526481.4 %
Date:2024-06-10 08:19:14Functions:273479.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
HBPammHydrogens.cpp +
70.3%70.3%
+
70.3 %52 / 7475.0 %6 / 8
HBPammMatrix.cpp +
90.7%90.7%
+
90.7 %39 / 4387.5 %7 / 8
HBPammObject.cpp +
100.0%
+
100.0 %32 / 32100.0 %3 / 3
HBPammObject.h +
100.0%
+
100.0 %1 / 1-0 / 0
PAMM.cpp +
76.9%76.9%
+
76.9 %50 / 6572.7 %8 / 11
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.15
+
+ + + 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 0000000000..9b1319bc2c --- /dev/null +++ b/coverage/piv/PIV.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:42559571.4 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3piv3PIV18checkFieldsAllowedEv0
_ZN4PLMD3piv3PIVC2ERKNS_13ActionOptionsE0
_ZN4PLMD3piv3PIVD2Ev0
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe2186createERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIVC1ERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIVD0Ev12
_ZN4PLMD3piv3PIVD1Ev12
_ZN4PLMD3piv3PIV16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD3piv3PIV9calculateEv327
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe218C2Ev3473
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe218D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/piv/PIV.cpp.func.html b/coverage/piv/PIV.cpp.func.html new file mode 100644 index 0000000000..cbb1e188e8 --- /dev/null +++ b/coverage/piv/PIV.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:42559571.4 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe2186createERKNS_13ActionOptionsE12
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe218C2Ev3473
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe218D2Ev3473
_ZN4PLMD3piv3PIV16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD3piv3PIV18checkFieldsAllowedEv0
_ZN4PLMD3piv3PIV9calculateEv327
_ZN4PLMD3piv3PIVC1ERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIVC2ERKNS_13ActionOptionsE0
_ZN4PLMD3piv3PIVD0Ev12
_ZN4PLMD3piv3PIVD1Ev12
_ZN4PLMD3piv3PIVD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/piv/PIV.cpp.gcov.html b/coverage/piv/PIV.cpp.gcov.html new file mode 100644 index 0000000000..07ec1900d5 --- /dev/null +++ b/coverage/piv/PIV.cpp.gcov.html @@ -0,0 +1,1304 @@ + + + + + + + + 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:42559571.4 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ + + + + + + + +

+
          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 "colvar/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/Stopwatch.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : #include <iostream>
+      30             : 
+      31             : using namespace std;
+      32             : 
+      33             : namespace PLMD
+      34             : {
+      35             : namespace piv
+      36             : {
+      37             : 
+      38             : //+PLUMEDOC PIVMOD_COLVAR PIV
+      39             : /*
+      40             : Calculates the PIV-distance.
+      41             : 
+      42             : PIV distance is the squared Cartesian distance between the PIV \cite gallet2013structural \cite pipolo2017navigating
+      43             : associated to the configuration of the system during the dynamics and a reference configuration provided
+      44             : as input (PDB file format).
+      45             : PIV can be used together with \ref FUNCPATHMSD to define a path in the PIV space.
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : The following example calculates PIV-distances from three reference configurations in Ref1.pdb, Ref2.pdb and Ref3.pdb
+      50             : and prints the results in a file named colvar.
+      51             : 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.
+      52             : SFACTOR is a scaling factor that multiplies the contribution to the PIV-distance given by the single PIV block.
+      53             : NLIST sets the use of neighbor lists for calculating atom-atom distances.
+      54             : The SWITCH keyword specifies the parameters of the switching function that transforms atom-atom distances.
+      55             : SORT=1 means that the PIV block elements are sorted (SORT=0 no sorting.)
+      56             : Values for SORT, SFACTOR and the neighbor list parameters have to be specified for each block.
+      57             : 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).
+      58             : The sorting operation within each PIV block is performed using the counting sort algorithm, PRECISION specifies the size of the counting array.
+      59             : 
+      60             : \plumedfile
+      61             : PIV ...
+      62             : LABEL=Pivd1
+      63             : PRECISION=1000
+      64             : NLIST
+      65             : REF_FILE=Ref1.pdb
+      66             : PIVATOMS=3
+      67             : ATOMTYPES=A,B,C
+      68             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+      69             : SORT=1,1,1,1,1,1
+      70             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+      71             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+      72             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+      73             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+      74             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+      75             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+      76             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+      77             : NL_STRIDE=10,10,10,10,10,10
+      78             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+      79             : ... PIV
+      80             : PIV ...
+      81             : LABEL=Pivd2
+      82             : PRECISION=1000
+      83             : NLIST
+      84             : REF_FILE=Ref2.pdb
+      85             : PIVATOMS=3
+      86             : ATOMTYPES=A,B,C
+      87             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+      88             : SORT=1,1,1,1,1,1
+      89             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+      90             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+      91             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+      92             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+      93             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+      94             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+      95             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+      96             : NL_STRIDE=10,10,10,10,10,10
+      97             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+      98             : ... PIV
+      99             : PIV ...
+     100             : LABEL=Pivd3
+     101             : PRECISION=1000
+     102             : NLIST
+     103             : REF_FILE=Ref3.pdb
+     104             : PIVATOMS=3
+     105             : ATOMTYPES=A,B,C
+     106             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+     107             : SORT=1,1,1,1,1,1
+     108             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     109             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     110             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+     111             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+     112             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+     113             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+     114             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+     115             : NL_STRIDE=10,10,10,10,10,10
+     116             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+     117             : ... PIV
+     118             : 
+     119             : PRINT ARG=Pivd1,Pivd2,Pivd3 FILE=colvar
+     120             : \endplumedfile
+     121             : 
+     122             : WARNING:
+     123             : 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:
+     124             : 
+     125             : \verbatim
+     126             : CRYST1   31.028   36.957   23.143  89.93  92.31  89.99 P 1           1
+     127             : ATOM      1  OW1 wate    1      15.630  19.750   1.520  1.00  0.00
+     128             : \endverbatim
+     129             : 
+     130             : 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.
+     131             : 
+     132             : The following example calculates the PIV-distances from two reference configurations Ref1.pdb and Ref2.pdb
+     133             : and uses PIV-distances to define a Path Collective Variable (\ref FUNCPATHMSD) with only two references (Ref1.pdb and Ref2.pdb).
+     134             : 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.
+     135             : 
+     136             : \plumedfile
+     137             : PIV ...
+     138             : LABEL=c1
+     139             : PRECISION=1000
+     140             : VOLUME=12.15
+     141             : NLIST
+     142             : REF_FILE=Ref1.pdb
+     143             : PIVATOMS=2
+     144             : ATOMTYPES=A,B
+     145             : ONLYDIRECT
+     146             : SFACTOR=1.0,0.2
+     147             : SORT=1,1
+     148             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     149             : SWITCH2={RATIONAL R_0=0.5 MM=10 NN=5}
+     150             : NL_CUTOFF=1.2,1.2
+     151             : NL_STRIDE=10,10
+     152             : NL_SKIN=0.1,0.1
+     153             : ... PIV
+     154             : PIV ...
+     155             : LABEL=c2
+     156             : PRECISION=1000
+     157             : VOLUME=12.15
+     158             : NLIST
+     159             : REF_FILE=Ref2.pdb
+     160             : PIVATOMS=2
+     161             : ATOMTYPES=A,B
+     162             : ONLYDIRECT
+     163             : SFACTOR=1.0,0.2
+     164             : SORT=1,1
+     165             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     166             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     167             : NL_CUTOFF=1.2,1.2
+     168             : NL_STRIDE=10,10
+     169             : NL_SKIN=0.1,0.1
+     170             : ... PIV
+     171             : 
+     172             : p1: FUNCPATHMSD ARG=c1,c2 LAMBDA=0.180338
+     173             : METAD ARG=p1.s,p1.z SIGMA=0.01,0.2 HEIGHT=0.8 PACE=500   LABEL=res
+     174             : PRINT ARG=c1,c2,p1.s,p1.z,res.bias STRIDE=500  FILE=colvar FMT=%15.6f
+     175             : \endplumedfile
+     176             : 
+     177             : When using PIV please cite \cite pipolo2017navigating .
+     178             : 
+     179             : (See also \ref PRINT)
+     180             : 
+     181             : */
+     182             : //+ENDPLUMEDOC
+     183             : 
+     184             : class PIV      : public Colvar
+     185             : {
+     186             : private:
+     187             :   bool pbc, serial, timer;
+     188             :   ForwardDecl<Stopwatch> stopwatch_fwd;
+     189             :   Stopwatch& stopwatch=*stopwatch_fwd;
+     190             :   int updatePIV;
+     191             :   size_t Nprec;
+     192             :   unsigned Natm,Nlist,NLsize;
+     193             :   double Fvol,Vol0,m_PIVdistance;
+     194             :   std::string ref_file;
+     195             :   NeighborList *nlall;
+     196             :   std::vector<SwitchingFunction> sfs;
+     197             :   std::vector<std:: vector<double> > rPIV;
+     198             :   std::vector<double> scaling,r00;
+     199             :   std::vector<double> nl_skin;
+     200             :   std::vector<double> fmass;
+     201             :   std::vector<bool> dosort;
+     202             :   std::vector<Vector> compos;
+     203             :   std::vector<string> sw;
+     204             :   std::vector<NeighborList *> nl;
+     205             :   std::vector<NeighborList *> nlcom;
+     206             :   std::vector<Vector> m_deriv;
+     207             :   Tensor m_virial;
+     208             :   bool Svol,cross,direct,doneigh,test,CompDer,com;
+     209             : public:
+     210             :   static void registerKeywords( Keywords& keys );
+     211             :   explicit PIV(const ActionOptions&);
+     212             :   ~PIV();
+     213             :   // active methods:
+     214             :   virtual void calculate();
+     215           0 :   void checkFieldsAllowed() {}
+     216             : };
+     217             : 
+     218       10443 : PLUMED_REGISTER_ACTION(PIV,"PIV")
+     219             : 
+     220          13 : void PIV::registerKeywords( Keywords& keys )
+     221             : {
+     222          13 :   Colvar::registerKeywords( keys );
+     223          26 :   keys.add("numbered","SWITCH","The switching functions parameter."
+     224             :            "You should specify a Switching function for all PIV blocks."
+     225             :            "Details of the various switching "
+     226             :            "functions you can use are provided on \\ref switchingfunction.");
+     227          26 :   keys.add("compulsory","PRECISION","the precision for approximating reals with integers in sorting.");
+     228          26 :   keys.add("compulsory","REF_FILE","PDB file name that contains the \\f$i\\f$th reference structure.");
+     229          26 :   keys.add("compulsory","PIVATOMS","Number of atoms to use for PIV.");
+     230          26 :   keys.add("compulsory","SORT","Whether to sort or not the PIV block.");
+     231          26 :   keys.add("compulsory","ATOMTYPES","The atom types to use for PIV.");
+     232          26 :   keys.add("optional","SFACTOR","Scale the PIV-distance by such block-specific factor");
+     233          26 :   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. ");
+     234          26 :   keys.add("optional","UPDATEPIV","Frequency (in steps) at which the PIV is updated.");
+     235          26 :   keys.addFlag("TEST",false,"Print the actual and reference PIV and exit");
+     236          26 :   keys.addFlag("COM",false,"Use centers of mass of groups of atoms instead of atoms as specified in the Pdb file");
+     237          26 :   keys.addFlag("ONLYCROSS",false,"Use only cross-terms (A-B, A-C, B-C, ...) in PIV");
+     238          26 :   keys.addFlag("ONLYDIRECT",false,"Use only direct-terms (A-A, B-B, C-C, ...) in PIV");
+     239          26 :   keys.addFlag("DERIVATIVES",false,"Activate the calculation of the PIV for every class (needed for numerical derivatives).");
+     240          26 :   keys.addFlag("NLIST",false,"Use a neighbor list for distance calculations.");
+     241          26 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     242          26 :   keys.addFlag("TIMER",false,"Perform timing analysis on heavy loops.");
+     243          26 :   keys.add("optional","NL_CUTOFF","Neighbor lists cutoff.");
+     244          26 :   keys.add("optional","NL_STRIDE","Update neighbor lists every NL_STRIDE steps.");
+     245          26 :   keys.add("optional","NL_SKIN","The maximum atom displacement tolerated for the neighbor lists update.");
+     246          26 :   keys.reset_style("SWITCH","compulsory");
+     247          13 : }
+     248             : 
+     249          12 : PIV::PIV(const ActionOptions&ao):
+     250             :   PLUMED_COLVAR_INIT(ao),
+     251          12 :   pbc(true),
+     252          12 :   serial(false),
+     253          12 :   timer(false),
+     254          12 :   updatePIV(1),
+     255          12 :   Nprec(1000),
+     256          12 :   Natm(1),
+     257          12 :   Nlist(1),
+     258          12 :   NLsize(1),
+     259          12 :   Fvol(1.),
+     260          12 :   Vol0(0.),
+     261          12 :   m_PIVdistance(0.),
+     262          12 :   rPIV(std:: vector<std:: vector<double> >(Nlist)),
+     263          12 :   scaling(std:: vector<double>(Nlist)),
+     264          12 :   r00(std:: vector<double>(Nlist)),
+     265          12 :   nl_skin(std:: vector<double>(Nlist)),
+     266          12 :   fmass(std:: vector<double>(Nlist)),
+     267          12 :   dosort(std:: vector<bool>(Nlist)),
+     268          12 :   compos(std:: vector<Vector>(NLsize)),
+     269          12 :   sw(std:: vector<string>(Nlist)),
+     270          12 :   nl(std:: vector<NeighborList *>(Nlist)),
+     271          12 :   nlcom(std:: vector<NeighborList *>(NLsize)),
+     272          12 :   m_deriv(std:: vector<Vector>(1)),
+     273          12 :   Svol(false),
+     274          12 :   cross(true),
+     275          12 :   direct(true),
+     276          12 :   doneigh(false),
+     277          12 :   test(false),
+     278          12 :   CompDer(false),
+     279          24 :   com(false)
+     280             : {
+     281          12 :   log << "Starting PIV Constructor\n";
+     282             : 
+     283             :   // Precision on the real-to-integer transformation for the sorting
+     284          12 :   parse("PRECISION",Nprec);
+     285          12 :   if(Nprec<2) error("Precision must be => 2");
+     286             : 
+     287             :   // PBC
+     288          12 :   bool nopbc=!pbc;
+     289          12 :   parseFlag("NOPBC",nopbc);
+     290          12 :   pbc=!nopbc;
+     291          12 :   if(pbc) {
+     292          12 :     log << "Using Periodic Boundary Conditions\n";
+     293             :   } else  {
+     294           0 :     log << "Isolated System (NO PBC)\n";
+     295             :   }
+     296             : 
+     297             :   // SERIAL/PARALLEL
+     298          12 :   parseFlag("SERIAL",serial);
+     299          12 :   if(serial) {
+     300           0 :     log << "Serial PIV construction\n";
+     301             :   } else     {
+     302          12 :     log << "Parallel PIV construction\n";
+     303             :   }
+     304             : 
+     305             :   // Derivatives
+     306          12 :   parseFlag("DERIVATIVES",CompDer);
+     307          12 :   if(CompDer) log << "Computing Derivatives\n";
+     308             : 
+     309             :   // Timing
+     310          12 :   parseFlag("TIMER",timer);
+     311          12 :   if(timer) {
+     312           1 :     log << "Timing analysis\n";
+     313           1 :     stopwatch.start();
+     314           1 :     stopwatch.pause();
+     315             :   }
+     316             : 
+     317             :   // Test
+     318          12 :   parseFlag("TEST",test);
+     319             : 
+     320             :   // UPDATEPIV
+     321          24 :   if(keywords.exists("UPDATEPIV")) {
+     322          24 :     parse("UPDATEPIV",updatePIV);
+     323             :   }
+     324             : 
+     325             :   // Test
+     326          12 :   parseFlag("COM",com);
+     327          12 :   if(com) log << "Building PIV using COMs\n";
+     328             : 
+     329             :   // Volume Scaling
+     330          12 :   parse("VOLUME",Vol0);
+     331          12 :   if (Vol0>0) {
+     332          12 :     Svol=true;
+     333             :   }
+     334             : 
+     335             :   // PIV direct and cross blocks
+     336          12 :   bool oc=false,od=false;
+     337          12 :   parseFlag("ONLYCROSS",oc);
+     338          12 :   parseFlag("ONLYDIRECT",od);
+     339          12 :   if (oc&&od) {
+     340           0 :     error("ONLYCROSS and ONLYDIRECT are incompatible options!");
+     341             :   }
+     342          12 :   if(oc) {
+     343           4 :     direct=false;
+     344           4 :     log << "Using only CROSS-PIV blocks\n";
+     345             :   }
+     346          12 :   if(od) {
+     347           4 :     cross=false;
+     348           4 :     log << "Using only DIRECT-PIV blocks\n";
+     349             :   }
+     350             : 
+     351             :   // Atoms for PIV
+     352          12 :   parse("PIVATOMS",Natm);
+     353          12 :   std:: vector<string> atype(Natm);
+     354          12 :   parseVector("ATOMTYPES",atype);
+     355             :   //if(atype.size()!=getNumberOfArguments() && atype.size()!=0) error("not enough values for ATOMTYPES");
+     356             : 
+     357             :   // Reference PDB file
+     358          12 :   parse("REF_FILE",ref_file);
+     359          12 :   PDB mypdb;
+     360          12 :   FILE* fp=fopen(ref_file.c_str(),"r");
+     361          12 :   if (fp!=NULL) {
+     362          12 :     log<<"Opening PDB file with reference frame: "<<ref_file.c_str()<<"\n";
+     363          24 :     mypdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
+     364          12 :     fclose (fp);
+     365             :   } else {
+     366           0 :     error("Error in reference PDB file");
+     367             :   }
+     368             : 
+     369             :   // Build COM/Atom lists of AtomNumbers (this might be done in PBC.cpp)
+     370             :   // Atomlist or Plist used to build pair lists
+     371          12 :   std:: vector<std:: vector<AtomNumber> > Plist(Natm);
+     372             :   // Atomlist used to build list of atoms for each COM
+     373          12 :   std:: vector<std:: vector<AtomNumber> > comatm(1);
+     374             :   // NLsize is the number of atoms in the pdb cell
+     375          12 :   NLsize=mypdb.getAtomNumbers().size();
+     376             :   // In the following P stands for Point (either an Atom or a COM)
+     377             :   unsigned resnum=0;
+     378             :   // Presind (array size: number of residues) contains the contains the residue number
+     379             :   //   this is because the residue numbers may not always be ordered from 1 to resnum
+     380             :   std:: vector<unsigned> Presind;
+     381             :   // Build Presind
+     382       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     383       19392 :     unsigned rind=mypdb.getResidueNumber(mypdb.getAtomNumbers()[i]);
+     384             :     bool oldres=false;
+     385     7705008 :     for (unsigned j=0; j<Presind.size(); j++) {
+     386     7685616 :       if(rind==Presind[j]) {
+     387             :         oldres=true;
+     388             :       }
+     389             :     }
+     390       19392 :     if(!oldres) {
+     391        4848 :       Presind.push_back(rind);
+     392             :     }
+     393             :   }
+     394          12 :   resnum=Presind.size();
+     395             : 
+     396             :   // Pind0 is the atom/COM used in Nlists (for COM Pind0 is the first atom in the pdb belonging to that COM)
+     397             :   unsigned Pind0size;
+     398          12 :   if(com) {
+     399             :     Pind0size=resnum;
+     400             :   } else {
+     401          12 :     Pind0size=NLsize;
+     402             :   }
+     403          12 :   std:: vector<unsigned> Pind0(Pind0size);
+     404             :   // If COM resize important arrays
+     405          12 :   comatm.resize(NLsize);
+     406          12 :   if(com) {
+     407           0 :     nlcom.resize(NLsize);
+     408           0 :     compos.resize(NLsize);
+     409           0 :     fmass.resize(NLsize,0.);
+     410             :   }
+     411          12 :   log << "Total COM/Atoms: " << Natm*resnum << " \n";
+     412             :   // Build lists of Atoms/COMs for NLists
+     413             :   //   comatm filled also for non_COM calculation for analysis purposes
+     414          36 :   for (unsigned j=0; j<Natm; j++) {
+     415             :     unsigned oind;
+     416       38808 :     for (unsigned i=0; i<Pind0.size(); i++) {
+     417       38784 :       Pind0[i]=0;
+     418             :     }
+     419       38808 :     for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     420             :       // Residue/Atom AtomNumber: used to build NL for COMS/Atoms pairs.
+     421       38784 :       AtomNumber anum=mypdb.getAtomNumbers()[i];
+     422             :       // ResidueName/Atomname associated to atom
+     423       38784 :       string rname=mypdb.getResidueName(anum);
+     424       38784 :       string aname=mypdb.getAtomName(anum);
+     425             :       // Index associated to residue/atom: used to separate COM-lists
+     426       38784 :       unsigned rind=mypdb.getResidueNumber(anum);
+     427             :       unsigned aind=anum.index();
+     428             :       // This builds lists for NL
+     429             :       string Pname;
+     430             :       unsigned Pind;
+     431       38784 :       if(com) {
+     432             :         Pname=rname;
+     433           0 :         for(unsigned l=0; l<resnum; l++) {
+     434           0 :           if(rind==Presind[l]) {
+     435             :             Pind=l;
+     436             :           }
+     437             :         }
+     438             :       } else {
+     439             :         Pname=aname;
+     440             :         Pind=aind;
+     441             :       }
+     442       38784 :       if(Pname==atype[j]) {
+     443       14544 :         if(Pind0[Pind]==0) {
+     444             :           // adding the atomnumber to the atom/COM list for pairs
+     445       14544 :           Plist[j].push_back(anum);
+     446       14544 :           Pind0[Pind]=aind+1;
+     447             :           oind=Pind;
+     448             :         }
+     449             :         // adding the atomnumber to list of atoms for every COM/Atoms
+     450       14544 :         comatm[Pind0[Pind]-1].push_back(anum);
+     451             :       }
+     452             :     }
+     453             :     // Output Lists
+     454          24 :     log << "  Groups of type  " << j << ": " << Plist[j].size() << " \n";
+     455             :     string gname;
+     456             :     unsigned gsize;
+     457          24 :     if(com) {
+     458           0 :       gname=mypdb.getResidueName(comatm[Pind0[oind]-1][0]);
+     459           0 :       gsize=comatm[Pind0[oind]-1].size();
+     460             :     } else {
+     461          48 :       gname=mypdb.getAtomName(comatm[Pind0[oind]-1][0]);
+     462             :       gsize=1;
+     463             :     }
+     464          24 :     log.printf("    %6s %3s %13s %10i %6s\n", "type  ", gname.c_str(),"   containing ",gsize," atoms");
+     465             :   }
+     466             : 
+     467             :   // This is to build the list with all the atoms
+     468             :   std:: vector<AtomNumber> listall;
+     469       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     470       19392 :     listall.push_back(mypdb.getAtomNumbers()[i]);
+     471             :   }
+     472             : 
+     473             :   // PIV blocks and Neighbour Lists
+     474          12 :   Nlist=0;
+     475             :   // Direct adds the A-A ad B-B blocks (N)
+     476          12 :   if(direct) {
+     477           8 :     Nlist=Nlist+unsigned(Natm);
+     478             :   }
+     479             :   // Cross adds the A-B blocks (N*(N-1)/2)
+     480          12 :   if(cross) {
+     481           8 :     Nlist=Nlist+unsigned(double(Natm*(Natm-1))/2.);
+     482             :   }
+     483             :   // Resize vectors according to Nlist
+     484          12 :   rPIV.resize(Nlist);
+     485             : 
+     486             :   // PIV scaled option
+     487          12 :   scaling.resize(Nlist);
+     488          36 :   for(unsigned j=0; j<Nlist; j++) {
+     489          24 :     scaling[j]=1.;
+     490             :   }
+     491          24 :   if(keywords.exists("SFACTOR")) {
+     492          24 :     parseVector("SFACTOR",scaling);
+     493             :     //if(scaling.size()!=getNumberOfArguments() && scaling.size()!=0) error("not enough values for SFACTOR");
+     494             :   }
+     495             :   // Neighbour Lists option
+     496          12 :   parseFlag("NLIST",doneigh);
+     497          12 :   nl.resize(Nlist);
+     498          12 :   nl_skin.resize(Nlist);
+     499          12 :   if(doneigh) {
+     500          12 :     std:: vector<double> nl_cut(Nlist,0.);
+     501          12 :     std:: vector<int> nl_st(Nlist,0);
+     502          12 :     parseVector("NL_CUTOFF",nl_cut);
+     503             :     //if(nl_cut.size()!=getNumberOfArguments() && nl_cut.size()!=0) error("not enough values for NL_CUTOFF");
+     504          12 :     parseVector("NL_STRIDE",nl_st);
+     505             :     //if(nl_st.size()!=getNumberOfArguments() && nl_st.size()!=0) error("not enough values for NL_STRIDE");
+     506          12 :     parseVector("NL_SKIN",nl_skin);
+     507             :     //if(nl_skin.size()!=getNumberOfArguments() && nl_skin.size()!=0) error("not enough values for NL_SKIN");
+     508          36 :     for (unsigned j=0; j<Nlist; j++) {
+     509          24 :       if(nl_cut[j]<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     510          24 :       if(nl_st[j]<=0) error("NL_STRIDE should be explicitly specified and positive");
+     511          24 :       if(nl_skin[j]<=0.) error("NL_SKIN should be explicitly specified and positive");
+     512          24 :       nl_cut[j]=nl_cut[j]+nl_skin[j];
+     513             :     }
+     514          12 :     log << "Creating Neighbor Lists \n";
+     515             :     // WARNING: is nl_cut meaningful here?
+     516          12 :     nlall= new NeighborList(listall,true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     517          12 :     if(com) {
+     518             :       //Build lists of Atoms for every COM
+     519           0 :       for (unsigned i=0; i<compos.size(); i++) {
+     520             :         // WARNING: is nl_cut meaningful here?
+     521           0 :         nlcom[i]= new NeighborList(comatm[i],true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     522             :       }
+     523             :     }
+     524             :     unsigned ncnt=0;
+     525             :     // Direct blocks AA, BB, CC, ...
+     526          12 :     if(direct) {
+     527          24 :       for (unsigned j=0; j<Natm; j++) {
+     528          16 :         nl[ncnt]= new NeighborList(Plist[j],true,pbc,getPbc(),comm,nl_cut[j],nl_st[j]);
+     529          16 :         ncnt+=1;
+     530             :       }
+     531             :     }
+     532             :     // Cross blocks AB, AC, BC, ...
+     533          12 :     if(cross) {
+     534          24 :       for (unsigned j=0; j<Natm; j++) {
+     535          24 :         for (unsigned i=j+1; i<Natm; i++) {
+     536           8 :           nl[ncnt]= new NeighborList(Plist[i],Plist[j],true,false,pbc,getPbc(),comm,nl_cut[ncnt],nl_st[ncnt]);
+     537           8 :           ncnt+=1;
+     538             :         }
+     539             :       }
+     540             :     }
+     541             :   } else {
+     542           0 :     log << "WARNING: Neighbor List not activated this has not been tested!!  \n";
+     543           0 :     nlall= new NeighborList(listall,true,pbc,getPbc(),comm);
+     544           0 :     for (unsigned j=0; j<Nlist; j++) {
+     545           0 :       nl[j]= new NeighborList(Plist[j],Plist[j],true,true,pbc,getPbc(),comm);
+     546             :     }
+     547             :   }
+     548             :   // Output Nlist
+     549          12 :   log << "Total Nlists: " << Nlist << " \n";
+     550          36 :   for (unsigned j=0; j<Nlist; j++) {
+     551          24 :     log << "  list " << j+1 << "   size " << nl[j]->size() << " \n";
+     552             :   }
+     553             :   // Calculate COM masses once and for all from lists
+     554          12 :   if(com) {
+     555           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     556             :       double commass=0.;
+     557           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     558           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     559           0 :         commass+=mypdb.getOccupancy()[andx];
+     560             :       }
+     561           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     562           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     563           0 :         if(commass>0.) {
+     564           0 :           fmass[andx]=mypdb.getOccupancy()[andx]/commass;
+     565             :         } else {
+     566           0 :           fmass[andx]=1.;
+     567             :         }
+     568             :       }
+     569             :     }
+     570             :   }
+     571             : 
+     572             :   // Sorting
+     573          12 :   dosort.resize(Nlist);
+     574          12 :   std:: vector<int> ynsort(Nlist);
+     575          12 :   parseVector("SORT",ynsort);
+     576          36 :   for (unsigned i=0; i<Nlist; i++) {
+     577          24 :     if(ynsort[i]==0||CompDer) {
+     578             :       dosort[i]=false;
+     579             :     } else {
+     580             :       dosort[i]=true;
+     581             :     }
+     582             :   }
+     583             : 
+     584             :   //build box vectors and correct for pbc
+     585          12 :   log << "Building the box from PDB data ... \n";
+     586          12 :   Tensor Box=mypdb.getBoxVec();
+     587          12 :   log << "  Done! A,B,C vectors in Cartesian space:  \n";
+     588          12 :   log.printf("  A:  %12.6f%12.6f%12.6f\n", Box[0][0],Box[0][1],Box[0][2]);
+     589          12 :   log.printf("  B:  %12.6f%12.6f%12.6f\n", Box[1][0],Box[1][1],Box[1][2]);
+     590          12 :   log.printf("  C:  %12.6f%12.6f%12.6f\n", Box[2][0],Box[2][1],Box[2][2]);
+     591          12 :   log << "Changing the PBC according to the new box \n";
+     592          12 :   Pbc mypbc;
+     593          12 :   mypbc.setBox(Box);
+     594          12 :   log << "The box volume is " << mypbc.getBox().determinant() << " \n";
+     595             : 
+     596             :   //Compute scaling factor
+     597          12 :   if(Svol) {
+     598          12 :     Fvol=cbrt(Vol0/mypbc.getBox().determinant());
+     599          12 :     log << "Scaling atom distances by  " << Fvol << " \n";
+     600             :   } else {
+     601           0 :     log << "Using unscaled atom distances \n";
+     602             :   }
+     603             : 
+     604          12 :   r00.resize(Nlist);
+     605          12 :   sw.resize(Nlist);
+     606          36 :   for (unsigned j=0; j<Nlist; j++) {
+     607          48 :     if( !parseNumbered( "SWITCH", j+1, sw[j] ) ) break;
+     608             :   }
+     609          12 :   if(CompDer) {
+     610             :     // Set switching function parameters here only if computing derivatives
+     611             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     612           6 :     log << "Switching Function Parameters \n";
+     613           6 :     sfs.resize(Nlist);
+     614             :     std::string errors;
+     615          18 :     for (unsigned j=0; j<Nlist; j++) {
+     616          12 :       if(Svol) {
+     617             :         double r0;
+     618             :         std::string old_r0;
+     619          12 :         vector<string> data=Tools::getWords(sw[j]);
+     620             :         data.erase(data.begin());
+     621          12 :         Tools::parse(data,"R_0",old_r0);
+     622          12 :         Tools::convert(old_r0,r0);
+     623          12 :         r0*=Fvol;
+     624          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     625          12 :         std::size_t pos = sw[j].find("R_0");
+     626          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     627          12 :       }
+     628          12 :       sfs[j].set(sw[j],errors);
+     629             :       std::string num;
+     630          12 :       Tools::convert(j+1, num);
+     631          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     632          12 :       r00[j]=sfs[j].get_r0();
+     633          24 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     634             :     }
+     635             :   }
+     636             : 
+     637             :   // build COMs from positions if requested
+     638          12 :   if(com) {
+     639           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     640           0 :       compos[j][0]=0.;
+     641           0 :       compos[j][1]=0.;
+     642           0 :       compos[j][2]=0.;
+     643           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     644           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     645           0 :         compos[j]+=fmass[andx]*mypdb.getPositions()[andx];
+     646             :       }
+     647             :     }
+     648             :   }
+     649             :   // build the rPIV distances (transformation and sorting is done afterwards)
+     650          12 :   if(CompDer) {
+     651           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     652             :   }
+     653          36 :   for(unsigned j=0; j<Nlist; j++) {
+     654    11516328 :     for(unsigned i=0; i<nl[j]->size(); i++) {
+     655    11516304 :       unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     656    11516304 :       unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     657             :       //calculate/get COM position of centers i0 and i1
+     658    11516304 :       Vector Pos0,Pos1;
+     659    11516304 :       if(com) {
+     660             :         //if(pbc) makeWhole();
+     661           0 :         Pos0=compos[i0];
+     662           0 :         Pos1=compos[i1];
+     663             :       } else {
+     664    11516304 :         Pos0=mypdb.getPositions()[i0];
+     665    11516304 :         Pos1=mypdb.getPositions()[i1];
+     666             :       }
+     667    11516304 :       Vector ddist;
+     668    11516304 :       if(pbc) {
+     669    11516304 :         ddist=mypbc.distance(Pos0,Pos1);
+     670             :       } else {
+     671           0 :         ddist=delta(Pos0,Pos1);
+     672             :       }
+     673    11516304 :       double df=0.;
+     674             :       // Transformation and sorting done at the first timestep to solve the r0 definition issue
+     675    11516304 :       if(CompDer) {
+     676        1104 :         rPIV[j].push_back(sfs[j].calculate(ddist.modulo()*Fvol, df));
+     677             :       } else {
+     678    11515200 :         rPIV[j].push_back(ddist.modulo()*Fvol);
+     679             :       }
+     680             :     }
+     681          24 :     if(CompDer) {
+     682          12 :       if(dosort[j]) {
+     683           0 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     684             :       }
+     685             :       int lmt0=0;
+     686             :       int lmt1=0;
+     687        1116 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     688        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     689           0 :           lmt0+=1;
+     690             :         }
+     691        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     692           0 :           lmt1+=1;
+     693             :         }
+     694             :       }
+     695          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     696             :     }
+     697             :   }
+     698             : 
+     699          12 :   checkRead();
+     700             :   // From the plumed manual on how to build-up a new Colvar
+     701          12 :   addValueWithDerivatives();
+     702          12 :   requestAtoms(nlall->getFullAtomList());
+     703          12 :   setNotPeriodic();
+     704             :   // getValue()->setPeridodicity(false);
+     705             :   // set size of derivative vector
+     706          12 :   m_deriv.resize(getNumberOfAtoms());
+     707          24 : }
+     708             : 
+     709             : // The following deallocates pointers
+     710          24 : PIV::~PIV()
+     711             : {
+     712          36 :   for (unsigned j=0; j<Nlist; j++) {
+     713          24 :     delete nl[j];
+     714             :   }
+     715          12 :   if(com) {
+     716           0 :     for (unsigned j=0; j<NLsize; j++) {
+     717           0 :       delete nlcom[j];
+     718             :     }
+     719             :   }
+     720          12 :   delete nlall;
+     721          48 : }
+     722             : 
+     723         327 : void PIV::calculate()
+     724             : {
+     725             : 
+     726             :   // Local variables
+     727             :   // The following are probably needed as static arrays
+     728             :   static int prev_stp=-1;
+     729             :   static int init_stp=1;
+     730         327 :   static std:: vector<std:: vector<Vector> > prev_pos(Nlist);
+     731         327 :   static std:: vector<std:: vector<double> > cPIV(Nlist);
+     732         327 :   static std:: vector<std:: vector<int> > Atom0(Nlist);
+     733         327 :   static std:: vector<std:: vector<int> > Atom1(Nlist);
+     734         327 :   std:: vector<std:: vector<int> > A0(Nprec);
+     735         327 :   std:: vector<std:: vector<int> > A1(Nprec);
+     736             :   size_t stride=1;
+     737             :   unsigned rank=0;
+     738             : 
+     739         327 :   if(!serial) {
+     740         327 :     stride=comm.Get_size();
+     741         327 :     rank=comm.Get_rank();
+     742             :   } else {
+     743             :     stride=1;
+     744             :     rank=0;
+     745             :   }
+     746             : 
+     747             :   // Transform (and sort) the rPIV before starting the dynamics
+     748         327 :   if (((prev_stp==-1) || (init_stp==1)) &&!CompDer) {
+     749           6 :     if(prev_stp!=-1) {init_stp=0;}
+     750             :     // Calculate the volume scaling factor
+     751           6 :     if(Svol) {
+     752           6 :       Fvol=cbrt(Vol0/getBox().determinant());
+     753             :     }
+     754             :     //Set switching function parameters
+     755           6 :     log << "\n";
+     756           6 :     log << "REFERENCE PDB # " << prev_stp+2 << " \n";
+     757             :     // Set switching function parameters here only if computing derivatives
+     758             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     759           6 :     log << "Switching Function Parameters \n";
+     760           6 :     sfs.resize(Nlist);
+     761             :     std::string errors;
+     762          18 :     for (unsigned j=0; j<Nlist; j++) {
+     763          12 :       if(Svol) {
+     764             :         double r0;
+     765             :         std::string old_r0;
+     766          12 :         vector<string> data=Tools::getWords(sw[j]);
+     767             :         data.erase(data.begin());
+     768          12 :         Tools::parse(data,"R_0",old_r0);
+     769          12 :         Tools::convert(old_r0,r0);
+     770          12 :         r0*=Fvol;
+     771          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     772          12 :         std::size_t pos = sw[j].find("R_0");
+     773          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     774          12 :       }
+     775          12 :       sfs[j].set(sw[j],errors);
+     776             :       std::string num;
+     777          12 :       Tools::convert(j+1, num);
+     778          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     779          12 :       r00[j]=sfs[j].get_r0();
+     780          24 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     781             :     }
+     782             :     //Transform and sort
+     783           6 :     log << "Building Reference PIV Vector \n";
+     784           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     785           6 :     double df=0.;
+     786          18 :     for (unsigned j=0; j<Nlist; j++) {
+     787    11515212 :       for (unsigned i=0; i<rPIV[j].size(); i++) {
+     788    11515200 :         rPIV[j][i]=sfs[j].calculate(rPIV[j][i], df);
+     789             :       }
+     790          12 :       if(dosort[j]) {
+     791          12 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     792             :       }
+     793             :       int lmt0=0;
+     794             :       int lmt1=0;
+     795    11515212 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     796    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     797          26 :           lmt0+=1;
+     798             :         }
+     799    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     800       63358 :           lmt1+=1;
+     801             :         }
+     802             :       }
+     803          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     804             :     }
+     805           6 :     log << "\n";
+     806             :   }
+     807             :   // Do the sorting only once per timestep to avoid building the PIV N times for N rPIV PDB structures!
+     808         327 :   if ((getStep()>prev_stp&&getStep()%updatePIV==0)||CompDer) {
+     809         324 :     if (CompDer) log << " Step " << getStep() << "  Computing Derivatives NON-SORTED PIV \n";
+     810             :     //
+     811             :     // build COMs from positions if requested
+     812         324 :     if(com) {
+     813           0 :       if(pbc) makeWhole();
+     814           0 :       for(unsigned j=0; j<compos.size(); j++) {
+     815           0 :         compos[j][0]=0.;
+     816           0 :         compos[j][1]=0.;
+     817           0 :         compos[j][2]=0.;
+     818           0 :         for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     819           0 :           unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     820           0 :           compos[j]+=fmass[andx]*getPosition(andx);
+     821             :         }
+     822             :       }
+     823             :     }
+     824             :     // update neighbor lists when an atom moves out of the Neighbor list skin
+     825         324 :     if (doneigh) {
+     826             :       bool doupdate=false;
+     827             :       // For the first step build previous positions = actual positions
+     828         324 :       if (prev_stp==-1) {
+     829           6 :         bool docom=com;
+     830          18 :         for (unsigned j=0; j<Nlist; j++) {
+     831        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     832        9696 :             Vector Pos;
+     833        9696 :             if(docom) {
+     834           0 :               Pos=compos[i];
+     835             :             } else {
+     836        9696 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     837             :             }
+     838        9696 :             prev_pos[j].push_back(Pos);
+     839             :           }
+     840             :         }
+     841             :         doupdate=true;
+     842             :       }
+     843             :       // Decide whether to update lists based on atom displacement, every stride
+     844         324 :       std:: vector<std:: vector<Vector> > tmp_pos(Nlist);
+     845         324 :       if (getStep() % nlall->getStride() ==0) {
+     846         324 :         bool docom=com;
+     847         972 :         for (unsigned j=0; j<Nlist; j++) {
+     848       20520 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     849       19872 :             Vector Pos;
+     850       19872 :             if(docom) {
+     851           0 :               Pos=compos[i];
+     852             :             } else {
+     853       19872 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     854             :             }
+     855       19872 :             tmp_pos[j].push_back(Pos);
+     856       19872 :             if (pbcDistance(tmp_pos[j][i],prev_pos[j][i]).modulo()>=nl_skin[j]) {
+     857             :               doupdate=true;
+     858             :             }
+     859             :           }
+     860             :         }
+     861             :       }
+     862             :       // Update Nlists if needed
+     863         324 :       if (doupdate==true) {
+     864          18 :         for (unsigned j=0; j<Nlist; j++) {
+     865        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     866        9696 :             prev_pos[j][i]=tmp_pos[j][i];
+     867             :           }
+     868          12 :           nl[j]->update(prev_pos[j]);
+     869          12 :           log << " Step " << getStep() << "  Neighbour lists updated " << nl[j]->size() << " \n";
+     870             :         }
+     871             :       }
+     872         324 :     }
+     873             :     // Calculate the volume scaling factor
+     874         324 :     if(Svol) {
+     875         324 :       Fvol=cbrt(Vol0/getBox().determinant());
+     876             :     }
+     877         324 :     Vector ddist;
+     878             :     // Global to local variables
+     879         324 :     bool doserial=serial;
+     880             :     // Build "Nlist" PIV blocks
+     881         972 :     for(unsigned j=0; j<Nlist; j++) {
+     882         648 :       if(dosort[j]) {
+     883             :         // from global to local variables to speedup the for loop with if statements
+     884           6 :         bool docom=com;
+     885           6 :         bool dopbc=pbc;
+     886             :         // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     887           6 :         std:: vector<int> OrdVec(Nprec,0);
+     888           6 :         cPIV[j].resize(0);
+     889           6 :         Atom0[j].resize(0);
+     890           6 :         Atom1[j].resize(0);
+     891             :         // Building distances for the PIV vector at time t
+     892           9 :         if(timer) stopwatch.start("1 Build cPIV");
+     893     5757606 :         for(unsigned i=rank; i<nl[j]->size(); i+=stride) {
+     894     5757600 :           unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     895     5757600 :           unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     896     5757600 :           Vector Pos0,Pos1;
+     897     5757600 :           if(docom) {
+     898           0 :             Pos0=compos[i0];
+     899           0 :             Pos1=compos[i1];
+     900             :           } else {
+     901     5757600 :             Pos0=getPosition(i0);
+     902     5757600 :             Pos1=getPosition(i1);
+     903             :           }
+     904     5757600 :           if(dopbc) {
+     905     5757600 :             ddist=pbcDistance(Pos0,Pos1);
+     906             :           } else {
+     907           0 :             ddist=delta(Pos0,Pos1);
+     908             :           }
+     909     5757600 :           double df=0.;
+     910             :           //Integer sorting ... faster!
+     911             :           //Transforming distances with the Switching function + real to integer transformation
+     912     5757600 :           int Vint=int(sfs[j].calculate(ddist.modulo()*Fvol, df)*double(Nprec-1)+0.5);
+     913             :           //Integer transformed distance values as index of the Ordering Vector OrdVec
+     914     5757600 :           OrdVec[Vint]+=1;
+     915             :           //Keeps track of atom indices for force and virial calculations
+     916     5757600 :           A0[Vint].push_back(i0);
+     917     5757600 :           A1[Vint].push_back(i1);
+     918             :         }
+     919           9 :         if(timer) stopwatch.stop("1 Build cPIV");
+     920           9 :         if(timer) stopwatch.start("2 Sort cPIV");
+     921           6 :         if(!doserial && comm.initialized()) {
+     922             :           // Vectors keeping track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     923           0 :           std:: vector<int> Vdim(stride,0);
+     924           0 :           std:: vector<int> Vpos(stride,0);
+     925             :           // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     926           0 :           std:: vector<int> OrdVecAll(stride*Nprec);
+     927             :           // Big vectors containing all Atom indexes for every occupancy (Atom0O(Nprec,n) and Atom1O(Nprec,n) matrices in one vector)
+     928             :           std:: vector<int> Atom0F;
+     929             :           std:: vector<int> Atom1F;
+     930             :           // Vector used to reconstruct arrays
+     931           0 :           std:: vector<unsigned> k(stride,0);
+     932             :           // Zeros might be many, this slows down a lot due to MPI communication
+     933             :           // Avoid passing the zeros (i=1) for atom indices
+     934           0 :           for(unsigned i=1; i<Nprec; i++) {
+     935             :             // Building long vectors with all atom indexes for occupancies ordered from i=1 to i=Nprec-1
+     936             :             // Can this be avoided ???
+     937           0 :             Atom0F.insert(Atom0F.end(),A0[i].begin(),A0[i].end());
+     938           0 :             Atom1F.insert(Atom1F.end(),A1[i].begin(),A1[i].end());
+     939           0 :             A0[i].resize(0);
+     940           0 :             A1[i].resize(0);
+     941             :           }
+     942             :           // Resize partial arrays to fill up for the next PIV block
+     943           0 :           A0[0].resize(0);
+     944           0 :           A1[0].resize(0);
+     945           0 :           A0[Nprec-1].resize(0);
+     946           0 :           A1[Nprec-1].resize(0);
+     947             :           // Avoid passing the zeros (i=1) for atom indices
+     948           0 :           OrdVec[0]=0;
+     949           0 :           OrdVec[Nprec-1]=0;
+     950             : 
+     951             :           // Wait for all ranks before communication of Vectors
+     952           0 :           comm.Barrier();
+     953             : 
+     954             :           // pass the array sizes before passing the arrays
+     955           0 :           int dim=Atom0F.size();
+     956             :           // Vdim and Vpos keep track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     957           0 :           comm.Allgather(&dim,1,&Vdim[0],1);
+     958             : 
+     959             :           // TO BE IMPROVED: the following may be done by the rank 0 (now every rank does it)
+     960             :           int Fdim=0;
+     961           0 :           for(unsigned i=1; i<stride; i++) {
+     962           0 :             Vpos[i]=Vpos[i-1]+Vdim[i-1];
+     963           0 :             Fdim+=Vdim[i];
+     964             :           }
+     965           0 :           Fdim+=Vdim[0];
+     966             :           // build big vectors for atom pairs on all ranks for all ranks
+     967           0 :           std:: vector<int> Atom0FAll(Fdim);
+     968           0 :           std:: vector<int> Atom1FAll(Fdim);
+     969             :           // TO BE IMPROVED: Allgathers may be substituted by gathers by proc 0
+     970             :           //   Moreover vectors are gathered head-to-tail and assembled later-on in a serial step.
+     971             :           // Gather the full Ordering Vector (occupancies). This is what we need to build the PIV
+     972           0 :           comm.Allgather(&OrdVec[0],Nprec,&OrdVecAll[0],Nprec);
+     973             :           // Gather the vectors of atom pairs to keep track of the idexes for the forces
+     974           0 :           comm.Allgatherv(Atom0F.data(),Atom0F.size(),&Atom0FAll[0],&Vdim[0],&Vpos[0]);
+     975           0 :           comm.Allgatherv(Atom1F.data(),Atom1F.size(),&Atom1FAll[0],&Vdim[0],&Vpos[0]);
+     976             : 
+     977             :           // Reconstruct the full vectors from collections of Allgathered parts (this is a serial step)
+     978             :           // This is the tricky serial step, to assemble together PIV and atom-pair info from head-tail big vectors
+     979             :           // Loop before on l and then on i would be better but the allgather should be modified
+     980             :           // Loop on blocks
+     981             :           //for(unsigned m=0;m<Nlist;m++) {
+     982             :           // Loop on Ordering Vector size excluding zeros (i=1)
+     983           0 :           if(timer) stopwatch.stop("2 Sort cPIV");
+     984           0 :           if(timer) stopwatch.start("3 Reconstruct cPIV");
+     985           0 :           for(unsigned i=1; i<Nprec; i++) {
+     986             :             // Loop on the ranks
+     987           0 :             for(unsigned l=0; l<stride; l++) {
+     988             :               // Loop on the number of head-to-tail pieces
+     989           0 :               for(unsigned m=0; m<OrdVecAll[i+l*Nprec]; m++) {
+     990             :                 // cPIV is the current PIV at time t
+     991           0 :                 cPIV[j].push_back(double(i)/double(Nprec-1));
+     992           0 :                 Atom0[j].push_back(Atom0FAll[k[l]+Vpos[l]]);
+     993           0 :                 Atom1[j].push_back(Atom1FAll[k[l]+Vpos[l]]);
+     994           0 :                 k[l]+=1;
+     995             :               }
+     996             :             }
+     997             :           }
+     998           0 :           if(timer) stopwatch.stop("3 Reconstruct cPIV");
+     999             :         } else {
+    1000     6000000 :           for(unsigned i=1; i<Nprec; i++) {
+    1001    11757594 :             for(unsigned m=0; m<OrdVec[i]; m++) {
+    1002     5757600 :               cPIV[j].push_back(double(i)/double(Nprec-1));
+    1003     5757600 :               Atom0[j].push_back(A0[i][m]);
+    1004     5757600 :               Atom1[j].push_back(A1[i][m]);
+    1005             :             }
+    1006             :           }
+    1007             :         }
+    1008             :       }
+    1009             :     }
+    1010             :   }
+    1011         327 :   Vector distance;
+    1012         327 :   double dfunc=0.;
+    1013             :   // Calculate volume scaling factor
+    1014         327 :   if(Svol) {
+    1015         327 :     Fvol=cbrt(Vol0/getBox().determinant());
+    1016             :   }
+    1017             : 
+    1018             :   // This test may be run by specifying the TEST keyword as input, it pritnts rPIV and cPIV and quits
+    1019         327 :   if(test) {
+    1020             :     unsigned limit=0;
+    1021           0 :     for(unsigned j=0; j<Nlist; j++) {
+    1022           0 :       if(dosort[j]) {
+    1023           0 :         limit = cPIV[j].size();
+    1024             :       } else {
+    1025           0 :         limit = rPIV[j].size();
+    1026             :       }
+    1027           0 :       log.printf("PIV Block:  %6i %12s %6i \n", j, "      Size:", limit);
+    1028           0 :       log.printf("%6s%6s%12s%12s%36s\n","     i","     j", "    c-PIV   ","    r-PIV   ","   i-j distance vector       ");
+    1029           0 :       for(unsigned i=0; i<limit; i++) {
+    1030             :         unsigned i0=0;
+    1031             :         unsigned i1=0;
+    1032           0 :         if(dosort[j]) {
+    1033           0 :           i0=Atom0[j][i];
+    1034           0 :           i1=Atom1[j][i];
+    1035             :         } else {
+    1036           0 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1037           0 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1038             :         }
+    1039           0 :         Vector Pos0,Pos1;
+    1040           0 :         if(com) {
+    1041           0 :           Pos0=compos[i0];
+    1042           0 :           Pos1=compos[i1];
+    1043             :         } else {
+    1044           0 :           Pos0=getPosition(i0);
+    1045           0 :           Pos1=getPosition(i1);
+    1046             :         }
+    1047           0 :         if(pbc) {
+    1048           0 :           distance=pbcDistance(Pos0,Pos1);
+    1049             :         } else {
+    1050           0 :           distance=delta(Pos0,Pos1);
+    1051             :         }
+    1052           0 :         dfunc=0.;
+    1053             :         double cP,rP;
+    1054           0 :         if(dosort[j]) {
+    1055           0 :           cP = cPIV[j][i];
+    1056           0 :           rP = rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1057             :         } else {
+    1058           0 :           double dm=distance.modulo();
+    1059           0 :           cP = sfs[j].calculate(dm*Fvol, dfunc);
+    1060           0 :           rP = rPIV[j][i];
+    1061             :         }
+    1062           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]);
+    1063             :       }
+    1064             :     }
+    1065           0 :     log.printf("This was a test, now exit \n");
+    1066           0 :     exit();
+    1067             :   }
+    1068             : 
+    1069         328 :   if(timer) stopwatch.start("4 Build For Derivatives");
+    1070             :   // non-global variables Nder and Scalevol defined to speedup if structures in cycles
+    1071         327 :   bool Nder=CompDer;
+    1072         327 :   bool Scalevol=Svol;
+    1073         327 :   if(getStep()%updatePIV==0) {
+    1074             :     // set to zero PIVdistance, derivatives and virial when they are calculated
+    1075       29799 :     for(unsigned j=0; j<m_deriv.size(); j++) {
+    1076      117888 :       for(unsigned k=0; k<3; k++) {m_deriv[j][k]=0.;}
+    1077             :     }
+    1078        1308 :     for(unsigned j=0; j<3; j++) {
+    1079        3924 :       for(unsigned k=0; k<3; k++) {
+    1080        2943 :         m_virial[j][k]=0.;
+    1081             :       }
+    1082             :     }
+    1083         327 :     m_PIVdistance=0.;
+    1084             :     // Re-compute atomic distances for derivatives and compute PIV-PIV distance
+    1085         981 :     for(unsigned j=0; j<Nlist; j++) {
+    1086             :       unsigned limit=0;
+    1087             :       // dosorting definition is to speedup if structure in cycles with non-global variables
+    1088         654 :       bool dosorting=dosort[j];
+    1089         654 :       bool docom=com;
+    1090         654 :       bool dopbc=pbc;
+    1091         654 :       if(dosorting) {
+    1092          12 :         limit = cPIV[j].size();
+    1093             :       } else {
+    1094         642 :         limit = rPIV[j].size();
+    1095             :       }
+    1096    11574918 :       for(unsigned i=rank; i<limit; i+=stride) {
+    1097             :         unsigned i0=0;
+    1098             :         unsigned i1=0;
+    1099    11574264 :         if(dosorting) {
+    1100    11515200 :           i0=Atom0[j][i];
+    1101    11515200 :           i1=Atom1[j][i];
+    1102             :         } else {
+    1103       59064 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1104       59064 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1105             :         }
+    1106    11574264 :         Vector Pos0,Pos1;
+    1107    11574264 :         if(docom) {
+    1108           0 :           Pos0=compos[i0];
+    1109           0 :           Pos1=compos[i1];
+    1110             :         } else {
+    1111    11574264 :           Pos0=getPosition(i0);
+    1112    11574264 :           Pos1=getPosition(i1);
+    1113             :         }
+    1114    11574264 :         if(dopbc) {
+    1115    11574264 :           distance=pbcDistance(Pos0,Pos1);
+    1116             :         } else {
+    1117           0 :           distance=delta(Pos0,Pos1);
+    1118             :         }
+    1119    11574264 :         dfunc=0.;
+    1120             :         // this is needed for dfunc and dervatives
+    1121    11574264 :         double dm=distance.modulo();
+    1122    11574264 :         double tPIV = sfs[j].calculate(dm*Fvol, dfunc);
+    1123             :         // PIV distance
+    1124             :         double coord=0.;
+    1125    11574264 :         if(!dosorting||Nder) {
+    1126       59064 :           coord = tPIV - rPIV[j][i];
+    1127             :         } else {
+    1128    11515200 :           coord = cPIV[j][i] - rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1129             :         }
+    1130             :         // Calculate derivatives, virial, and variable=sum_j (scaling[j] *(cPIV-rPIV)_j^2)
+    1131             :         // WARNING: dfunc=dswf/(Fvol*dm)  (this may change in future Plumed versions)
+    1132    11574264 :         double tmp = 2.*scaling[j]*coord*Fvol*Fvol*dfunc;
+    1133    11574264 :         Vector tmpder = tmp*distance;
+    1134             :         // 0.5*(x_i-x_k)*f_ik         (force on atom k due to atom i)
+    1135    11574264 :         if(docom) {
+    1136           0 :           Vector dist;
+    1137           0 :           for(unsigned k=0; k<nlcom[i0]->getFullAtomList().size(); k++) {
+    1138           0 :             unsigned x0=nlcom[i0]->getFullAtomList()[k].index();
+    1139           0 :             m_deriv[x0] -= tmpder*fmass[x0];
+    1140           0 :             for(unsigned l=0; l<3; l++) {
+    1141           0 :               dist[l]=0.;
+    1142             :             }
+    1143           0 :             Vector P0=getPosition(x0);
+    1144           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1145           0 :               unsigned x1=nlcom[i0]->getFullAtomList()[l].index();
+    1146           0 :               Vector P1=getPosition(x1);
+    1147           0 :               if(dopbc) {
+    1148           0 :                 dist+=pbcDistance(P0,P1);
+    1149             :               } else {
+    1150           0 :                 dist+=delta(P0,P1);
+    1151             :               }
+    1152             :             }
+    1153           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1154           0 :               unsigned x1=nlcom[i1]->getFullAtomList()[l].index();
+    1155           0 :               Vector P1=getPosition(x1);
+    1156           0 :               if(dopbc) {
+    1157           0 :                 dist+=pbcDistance(P0,P1);
+    1158             :               } else {
+    1159           0 :                 dist+=delta(P0,P1);
+    1160             :               }
+    1161             :             }
+    1162           0 :             m_virial    -= 0.25*fmass[x0]*Tensor(dist,tmpder);
+    1163             :           }
+    1164           0 :           for(unsigned k=0; k<nlcom[i1]->getFullAtomList().size(); k++) {
+    1165           0 :             unsigned x1=nlcom[i1]->getFullAtomList()[k].index();
+    1166           0 :             m_deriv[x1] += tmpder*fmass[x1];
+    1167           0 :             for(unsigned l=0; l<3; l++) {
+    1168           0 :               dist[l]=0.;
+    1169             :             }
+    1170           0 :             Vector P1=getPosition(x1);
+    1171           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1172           0 :               unsigned x0=nlcom[i1]->getFullAtomList()[l].index();
+    1173           0 :               Vector P0=getPosition(x0);
+    1174           0 :               if(dopbc) {
+    1175           0 :                 dist+=pbcDistance(P1,P0);
+    1176             :               } else {
+    1177           0 :                 dist+=delta(P1,P0);
+    1178             :               }
+    1179             :             }
+    1180           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1181           0 :               unsigned x0=nlcom[i0]->getFullAtomList()[l].index();
+    1182           0 :               Vector P0=getPosition(x0);
+    1183           0 :               if(dopbc) {
+    1184           0 :                 dist+=pbcDistance(P1,P0);
+    1185             :               } else {
+    1186           0 :                 dist+=delta(P1,P0);
+    1187             :               }
+    1188             :             }
+    1189           0 :             m_virial    += 0.25*fmass[x1]*Tensor(dist,tmpder);
+    1190             :           }
+    1191             :         } else {
+    1192    11574264 :           m_deriv[i0] -= tmpder;
+    1193    11574264 :           m_deriv[i1] += tmpder;
+    1194    11574264 :           m_virial    -= tmp*Tensor(distance,distance);
+    1195             :         }
+    1196    11574264 :         if(Scalevol) {
+    1197    11574264 :           m_virial+=1./3.*tmp*dm*dm*Tensor::identity();
+    1198             :         }
+    1199    11574264 :         m_PIVdistance    += scaling[j]*coord*coord;
+    1200             :       }
+    1201             :     }
+    1202             : 
+    1203         327 :     if (!serial && comm.initialized()) {
+    1204           0 :       comm.Barrier();
+    1205           0 :       comm.Sum(&m_PIVdistance,1);
+    1206           0 :       if(!m_deriv.empty()) comm.Sum(&m_deriv[0][0],3*m_deriv.size());
+    1207           0 :       comm.Sum(&m_virial[0][0],9);
+    1208             :     }
+    1209             :   }
+    1210         327 :   prev_stp=getStep();
+    1211             : 
+    1212             :   //Timing
+    1213         328 :   if(timer) stopwatch.stop("4 Build For Derivatives");
+    1214         327 :   if(timer) {
+    1215           1 :     log.printf("Timings for action %s with label %s \n", getName().c_str(), getLabel().c_str() );
+    1216           1 :     log<<stopwatch;
+    1217             :   }
+    1218             : 
+    1219             :   // Update derivatives, virial, and variable (PIV-distance^2)
+    1220       29799 :   for(unsigned i=0; i<m_deriv.size(); ++i) setAtomsDerivatives(i,m_deriv[i]);
+    1221         327 :   setValue           (m_PIVdistance);
+    1222         327 :   setBoxDerivatives  (m_virial);
+    1223         327 : }
+    1224             : //Close Namespaces at the very beginning
+    1225             : }
+    1226             : }
+    1227             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/piv/index-sort-f.html b/coverage/piv/index-sort-f.html new file mode 100644 index 0000000000..2173c0494f --- /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:42559571.4 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.4%71.4%
+
71.4 %425 / 59572.7 %8 / 11
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/piv/index-sort-l.html b/coverage/piv/index-sort-l.html new file mode 100644 index 0000000000..7bea30717f --- /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:42559571.4 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.4%71.4%
+
71.4 %425 / 59572.7 %8 / 11
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/piv/index.html b/coverage/piv/index.html new file mode 100644 index 0000000000..296d950788 --- /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:42559571.4 %
Date:2024-06-10 08:19:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.4%71.4%
+
71.4 %425 / 59572.7 %8 / 11
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..8198a64b69 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.cpp.func.html b/coverage/reference/ArgumentOnlyDistance.cpp.func.html new file mode 100644 index 0000000000..2efd4d5836 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.cpp.gcov.html b/coverage/reference/ArgumentOnlyDistance.cpp.gcov.html new file mode 100644 index 0000000000..fe5624b262 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..944f87d3f3 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD20ArgumentOnlyDistance28pcaIsEnabledForThisReferenceEv80
_ZN4PLMD20ArgumentOnlyDistance15setupPCAStorageERNS_18ReferenceValuePackE556
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.h.func.html b/coverage/reference/ArgumentOnlyDistance.h.func.html new file mode 100644 index 0000000000..64628db61f --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD20ArgumentOnlyDistance15setupPCAStorageERNS_18ReferenceValuePackE556
_ZN4PLMD20ArgumentOnlyDistance28pcaIsEnabledForThisReferenceEv80
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.h.gcov.html b/coverage/reference/ArgumentOnlyDistance.h.gcov.html new file mode 100644 index 0000000000..bf2407e977 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..dca7256d5c --- /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-06-10 08:19:14Functions: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_115DRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeD2Ev3473
_ZNK4PLMD5DRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb20378
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/DRMSD.cpp.func.html b/coverage/reference/DRMSD.cpp.func.html new file mode 100644 index 0000000000..de3dc1dc2b --- /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-06-10 08:19:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE26
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeD2Ev3473
_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.15
+
+ + + diff --git a/coverage/reference/DRMSD.cpp.gcov.html b/coverage/reference/DRMSD.cpp.gcov.html new file mode 100644 index 0000000000..6575aa1273 --- /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-06-10 08:19:14Functions: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       10471 : 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.15
+
+ + + 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 0000000000..ab34fab648 --- /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-06-10 08:19:14Functions: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_119DirectionRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/Direction.cpp.func.html b/coverage/reference/Direction.cpp.func.html new file mode 100644 index 0000000000..bdd80ea159 --- /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-06-10 08:19:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMe6createERKNS_29ReferenceConfigurationOptionsE10
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeD2Ev3473
_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.15
+
+ + + diff --git a/coverage/reference/Direction.cpp.gcov.html b/coverage/reference/Direction.cpp.gcov.html new file mode 100644 index 0000000000..a5050cb65b --- /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-06-10 08:19:14Functions: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       10439 : 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.15
+
+ + + 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 0000000000..a6e98cacb3 --- /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-06-10 08:19:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Direction17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/Direction.h.func.html b/coverage/reference/Direction.h.func.html new file mode 100644 index 0000000000..0c10fe0d64 --- /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-06-10 08:19:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Direction17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/Direction.h.gcov.html b/coverage/reference/Direction.h.gcov.html new file mode 100644 index 0000000000..88e9869d7b --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..a45ca72051 --- /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-06-10 08:19:14Functions: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_128DotProductDistanceRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/DotProductDistance.cpp.func.html b/coverage/reference/DotProductDistance.cpp.func.html new file mode 100644 index 0000000000..82f40df6dd --- /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-06-10 08:19:14Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeD2Ev3473
_ZN4PLMD18DotProductDistance4readERKNS_3PDBE0
_ZN4PLMD18DotProductDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD18DotProductDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD18DotProductDistance25calculateArgumentDistanceERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/DotProductDistance.cpp.gcov.html b/coverage/reference/DotProductDistance.cpp.gcov.html new file mode 100644 index 0000000000..115ea4a877 --- /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-06-10 08:19:14Functions: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       10419 : 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 (unsigned long i=0; i<vals.size(); ++i) dot+=getReferenceArgument(i)*arg[i];
+      52           0 :   for (unsigned long 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.15
+
+ + + 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 0000000000..f824b23760 --- /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-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17EuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeD2Ev3473
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD17EuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE518364
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/EuclideanDistance.cpp.func.html b/coverage/reference/EuclideanDistance.cpp.func.html new file mode 100644 index 0000000000..a7f520af66 --- /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-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeD2Ev3473
_ZN4PLMD17EuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD17EuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/EuclideanDistance.cpp.gcov.html b/coverage/reference/EuclideanDistance.cpp.gcov.html new file mode 100644 index 0000000000..0acfa2b48b --- /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-06-10 08:19:14Functions: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     1047147 : 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.15
+
+ + + 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 0000000000..9bf2ed62ba --- /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-06-10 08:19:14Functions: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_129IntermolecularDRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/IntermolecularDRMSD.cpp.func.html b/coverage/reference/IntermolecularDRMSD.cpp.func.html new file mode 100644 index 0000000000..8cfa3fc344 --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeD2Ev3473
_ZN4PLMD19IntermolecularDRMSD13setup_targetsEv1
_ZN4PLMD19IntermolecularDRMSD4readERKNS_3PDBE1
_ZN4PLMD19IntermolecularDRMSDC1ERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD19IntermolecularDRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/IntermolecularDRMSD.cpp.gcov.html b/coverage/reference/IntermolecularDRMSD.cpp.gcov.html new file mode 100644 index 0000000000..f091b593f5 --- /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-06-10 08:19:14Functions: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       10421 : 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.15
+
+ + + 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 0000000000..3063137576 --- /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-06-10 08:19:14Functions: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_129IntramolecularDRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/IntramolecularDRMSD.cpp.func.html b/coverage/reference/IntramolecularDRMSD.cpp.func.html new file mode 100644 index 0000000000..90cc06e3b3 --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeD2Ev3473
_ZN4PLMD19IntramolecularDRMSD13setup_targetsEv1
_ZN4PLMD19IntramolecularDRMSD4readERKNS_3PDBE1
_ZN4PLMD19IntramolecularDRMSDC1ERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD19IntramolecularDRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/IntramolecularDRMSD.cpp.gcov.html b/coverage/reference/IntramolecularDRMSD.cpp.gcov.html new file mode 100644 index 0000000000..23a1d39cfd --- /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-06-10 08:19:14Functions: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       10421 : 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.15
+
+ + + 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 0000000000..674fcdff24 --- /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-06-10 08:19:14Functions: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_129MahalanobisDistanceRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/MahalanobisDistance.cpp.func.html b/coverage/reference/MahalanobisDistance.cpp.func.html new file mode 100644 index 0000000000..2babb9e0ca --- /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-06-10 08:19:14Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeD2Ev3473
_ZN4PLMD19MahalanobisDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD19MahalanobisDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/MahalanobisDistance.cpp.gcov.html b/coverage/reference/MahalanobisDistance.cpp.gcov.html new file mode 100644 index 0000000000..8129a3da40 --- /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-06-10 08:19:14Functions: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       10419 : 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.15
+
+ + + 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 0000000000..1a6ec2a7e2 --- /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-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14MetricRegisterD2Ev3473
_ZN4PLMD14MetricRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS8_EERKNS_29ReferenceConfigurationOptionsEE38203
_ZN4PLMD14MetricRegister6removeEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS2_EERKNS_29ReferenceConfigurationOptionsEE38203
_ZN4PLMD14MetricRegister5checkENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518873
_ZN4PLMD14metricRegisterEv595279
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/MetricRegister.cpp.func.html b/coverage/reference/MetricRegister.cpp.func.html new file mode 100644 index 0000000000..6a20db3be4 --- /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-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14MetricRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS8_EERKNS_29ReferenceConfigurationOptionsEE38203
_ZN4PLMD14MetricRegister5checkENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518873
_ZN4PLMD14MetricRegister6removeEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS2_EERKNS_29ReferenceConfigurationOptionsEE38203
_ZN4PLMD14MetricRegisterD2Ev3473
_ZN4PLMD14metricRegisterEv595279
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/MetricRegister.cpp.gcov.html b/coverage/reference/MetricRegister.cpp.gcov.html new file mode 100644 index 0000000000..5e26c95fd3 --- /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-06-10 08:19:14Functions: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        3473 : MetricRegister::~MetricRegister() {
+      28        3473 :   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        3473 : }
+      34             : 
+      35      595279 : MetricRegister& metricRegister() {
+      36      595279 :   static MetricRegister ans;
+      37      595279 :   return ans;
+      38             : }
+      39             : 
+      40       38203 : void MetricRegister::remove(creator_pointer f) {
+      41      222272 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      42      222272 :     if((*p).second==f) {
+      43       38203 :       m.erase(p); break;
+      44             :     }
+      45             :   }
+      46       38203 : }
+      47             : 
+      48       38203 : void MetricRegister::add( std::string type, creator_pointer f ) {
+      49           0 :   plumed_massert(m.count(type)==0,"type has already been registered");
+      50       38203 :   m.insert(std::pair<std::string,creator_pointer>(type,f));
+      51       38203 : }
+      52             : 
+      53      518873 : bool MetricRegister::check(std::string type) {
+      54      518873 :   if( m.count(type)>0 ) return true;
+      55             :   return false;
+      56             : }
+      57             : 
+      58             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..2675dac6ab --- /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-06-10 08:19:14Functions: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_traitsIcESaIcEEE71
_ZN4PLMD14MetricRegister6createINS_8RMSDBaseEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE71
_ZN4PLMD14MetricRegister6createINS_22ReferenceConfigurationEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518743
_ZN4PLMD14MetricRegister6createINS_22ReferenceConfigurationEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE518743
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/MetricRegister.h.func.html b/coverage/reference/MetricRegister.h.func.html new file mode 100644 index 0000000000..7ab4563cca --- /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-06-10 08:19:14Functions: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_traitsIcESaIcEEE71
_ZN4PLMD14MetricRegister6createINS_8RMSDBaseEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE71
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/MetricRegister.h.gcov.html b/coverage/reference/MetricRegister.h.gcov.html new file mode 100644 index 0000000000..09772cd561 --- /dev/null +++ b/coverage/reference/MetricRegister.h.gcov.html @@ -0,0 +1,189 @@ + + + + + + + + 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-06-10 08:19:14Functions: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(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      518873 : std::unique_ptr<T> MetricRegister::create( const std::string& type ) {
+      73             :   std::string ftype;
+      74      518873 :   if( type.find("MULTI-")!=std::string::npos ) {
+      75             :     ftype="MULTI";
+      76             :   } else {
+      77      518868 :     std::size_t dash=type.find("-FAST"); // We must remove the fast label
+      78     1037736 :     ftype=type.substr(0,dash);
+      79             :   }
+      80     1037746 :   plumed_massert( check(ftype), "metric " + ftype + " does not exist" );
+      81      518873 :   ReferenceConfigurationOptions ro( type );
+      82             : // put immediately the result in a safe pointer
+      83      518873 :   std::unique_ptr<ReferenceConfiguration> conf( m[ftype]( ro ) );
+      84             : // try conversion
+      85         130 :   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      518873 :   if(!ptr ) plumed_merror( type + " metric is not valid in this context");
+      90             : // release ownership in order to transfer it to returned pointer
+      91             :   conf.release();
+      92             : // notice that I should pass ptr here rather than conf.release(),
+      93             : // since the type is different
+      94      518873 :   return std::unique_ptr<T>(ptr);
+      95      518873 : }
+      96             : 
+      97             : template <class T>
+      98      518817 : std::unique_ptr<T> MetricRegister::create( const std::string& type, const PDB& pdb ) {
+      99             :   std::string rtype;
+     100      518817 :   if( type.length()==0 ) {
+     101          20 :     rtype=pdb.getMtype();
+     102          10 :     plumed_massert(rtype.length()>0, "TYPE not specified in pdb input file");
+     103             :   } else {
+     104             :     rtype=type;
+     105             :   }
+     106      518817 :   std::unique_ptr<T> confout( create<T>( rtype ) );
+     107      518817 :   confout->read( pdb );
+     108      518817 :   return confout;
+     109           0 : }
+     110             : 
+     111             : }
+     112             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..56ae48274b --- /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-06-10 08:19:14Functions: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_125MultiDomainRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/MultiDomainRMSD.cpp.func.html b/coverage/reference/MultiDomainRMSD.cpp.func.html new file mode 100644 index 0000000000..f12143905a --- /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-06-10 08:19:14Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE5
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeD2Ev3473
_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.15
+
+ + + diff --git a/coverage/reference/MultiDomainRMSD.cpp.gcov.html b/coverage/reference/MultiDomainRMSD.cpp.gcov.html new file mode 100644 index 0000000000..53fbf5f9d8 --- /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-06-10 08:19:14Functions: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       10429 : 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.15
+
+ + + 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 0000000000..9f7322f31b --- /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-06-10 08:19:14Functions: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_137NormalizedEuclideanDistanceRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/NormalizedEuclideanDistance.cpp.func.html b/coverage/reference/NormalizedEuclideanDistance.cpp.func.html new file mode 100644 index 0000000000..67d340257f --- /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-06-10 08:19:14Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeD2Ev3473
_ZN4PLMD27NormalizedEuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD27NormalizedEuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html b/coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html new file mode 100644 index 0000000000..c3877b2e65 --- /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-06-10 08:19:14Functions: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       10419 : 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.15
+
+ + + 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 0000000000..8140e1370b --- /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-06-10 08:19:14Functions: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_121OptimalRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMeD2Ev3473
_ZNK4PLMD11OptimalRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb218933
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/OptimalRMSD.cpp.func.html b/coverage/reference/OptimalRMSD.cpp.func.html new file mode 100644 index 0000000000..5105a6f18e --- /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-06-10 08:19:14Functions: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_121OptimalRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMeD2Ev3473
_ZNK4PLMD11OptimalRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_1107
_ZNK4PLMD11OptimalRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE1158
_ZNK4PLMD11OptimalRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb218933
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/OptimalRMSD.cpp.gcov.html b/coverage/reference/OptimalRMSD.cpp.gcov.html new file mode 100644 index 0000000000..7e2a87338d --- /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-06-10 08:19:14Functions: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       11293 : 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.15
+
+ + + 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 0000000000..20d9a459b4 --- /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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8RMSDBaseC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD8RMSDBaseC2ERKNS_29ReferenceConfigurationOptionsE466
_ZNK4PLMD8RMSDBase9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb40484
_ZNK4PLMD8RMSDBase4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb178609
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/RMSDBase.cpp.func.html b/coverage/reference/RMSDBase.cpp.func.html new file mode 100644 index 0000000000..b5cf9fda3a --- /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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8RMSDBaseC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD8RMSDBaseC2ERKNS_29ReferenceConfigurationOptionsE466
_ZNK4PLMD8RMSDBase4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb178609
_ZNK4PLMD8RMSDBase9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb40484
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/RMSDBase.cpp.gcov.html b/coverage/reference/RMSDBase.cpp.gcov.html new file mode 100644 index 0000000000..1a45b28c19 --- /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-06-10 08:19:14Functions: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         466 : RMSDBase::RMSDBase( const ReferenceConfigurationOptions& ro ):
+      27             :   ReferenceConfiguration(ro),
+      28         466 :   SingleDomainRMSD(ro)
+      29             : {
+      30         466 : }
+      31             : 
+      32       40484 : double RMSDBase::calculate( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const {
+      33             : //  clearDerivatives();
+      34       40484 :   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.15
+
+ + + 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 0000000000..a2b8b278b8 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/reference/ReferenceArguments.cpp.func.html b/coverage/reference/ReferenceArguments.cpp.func.html new file mode 100644 index 0000000000..1e6bed234e --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/reference/ReferenceArguments.cpp.gcov.html b/coverage/reference/ReferenceArguments.cpp.gcov.html new file mode 100644 index 0000000000..e05a3768a9 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..1ae27b6d54 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceArguments16getArgumentNamesB5cxx11Ev962
_ZNK4PLMD18ReferenceArguments20getReferenceArgumentERKj1020
_ZNK4PLMD18ReferenceArguments29getNumberOfReferenceArgumentsEv39585
_ZNK4PLMD18ReferenceArguments21getReferenceArgumentsEv790964
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceArguments.h.func.html b/coverage/reference/ReferenceArguments.h.func.html new file mode 100644 index 0000000000..478c9388bc --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceArguments16getArgumentNamesB5cxx11Ev962
_ZNK4PLMD18ReferenceArguments20getReferenceArgumentERKj1020
_ZNK4PLMD18ReferenceArguments21getReferenceArgumentsEv790964
_ZNK4PLMD18ReferenceArguments29getNumberOfReferenceArgumentsEv39585
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceArguments.h.gcov.html b/coverage/reference/ReferenceArguments.h.gcov.html new file mode 100644 index 0000000000..906b5d20a3 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..2e07d6711b --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ReferenceAtomsC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD14ReferenceAtoms15getAtomRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb449
_ZN4PLMD14ReferenceAtoms20singleDomainRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb449
_ZN4PLMD14ReferenceAtoms22displaceReferenceAtomsERKdRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EE494
_ZN4PLMD14ReferenceAtoms16readAtomsFromPDBERKNS_3PDBEb682
_ZN4PLMD14ReferenceAtomsC2ERKNS_29ReferenceConfigurationOptionsE718
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.cpp.func.html b/coverage/reference/ReferenceAtoms.cpp.func.html new file mode 100644 index 0000000000..8d7a55b656 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ReferenceAtoms15getAtomRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb449
_ZN4PLMD14ReferenceAtoms16readAtomsFromPDBERKNS_3PDBEb682
_ZN4PLMD14ReferenceAtoms20singleDomainRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb449
_ZN4PLMD14ReferenceAtoms22displaceReferenceAtomsERKdRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EE494
_ZN4PLMD14ReferenceAtomsC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD14ReferenceAtomsC2ERKNS_29ReferenceConfigurationOptionsE718
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.cpp.gcov.html b/coverage/reference/ReferenceAtoms.cpp.gcov.html new file mode 100644 index 0000000000..5dffe6b942 --- /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-06-10 08:19:14Functions: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         718 : ReferenceAtoms::ReferenceAtoms( const ReferenceConfigurationOptions& ro ):
+      30             :   ReferenceConfiguration(ro),
+      31         718 :   checks_were_disabled(false)
+      32             : {
+      33         718 : }
+      34             : 
+      35         682 : void ReferenceAtoms::readAtomsFromPDB( const PDB& pdb, const bool allowblocks  ) {
+      36         682 :   if( !allowblocks && pdb.getNumberOfAtomBlocks()!=1 ) error("found multi-atom-block pdb format but expecting only one block of atoms");
+      37             : 
+      38         682 :   indices.resize(0); reference_atoms.resize(0); align.resize(0); displace.resize(0); atom_der_index.resize(0);
+      39        9301 :   for(unsigned i=0; i<pdb.size(); ++i) {
+      40        8619 :     indices.push_back( pdb.getAtomNumbers()[i] ); reference_atoms.push_back( pdb.getPositions()[i] );
+      41        8619 :     align.push_back( pdb.getOccupancy()[i] ); displace.push_back( pdb.getBeta()[i] ); atom_der_index.push_back(i);
+      42             :   }
+      43         682 : }
+      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         449 : void ReferenceAtoms::getAtomRequests( std::vector<AtomNumber>& numbers, bool disable_checks ) {
+      86         449 :   singleDomainRequests(numbers,disable_checks);
+      87         449 : }
+      88             : 
+      89         449 : void ReferenceAtoms::singleDomainRequests( std::vector<AtomNumber>& numbers, bool disable_checks ) {
+      90         449 :   checks_were_disabled=disable_checks;
+      91         449 :   atom_der_index.resize( indices.size() );
+      92             : 
+      93         449 :   if( numbers.size()==0 ) {
+      94        3476 :     for(unsigned i=0; i<indices.size(); ++i) {
+      95        3375 :       numbers.push_back( indices[i] );
+      96        3375 :       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         449 : }
+     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.15
+
+ + + 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 0000000000..549208980c --- /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-06-10 08:19:14Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD14ReferenceAtoms25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD14ReferenceAtoms33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE0
_ZN4PLMD14ReferenceAtoms18getAbsoluteIndexesEv4
_ZNK4PLMD14ReferenceAtoms29getNumberOfReferencePositionsEv150276
_ZNK4PLMD14ReferenceAtoms21getReferencePositionsEv2636046
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.h.func.html b/coverage/reference/ReferenceAtoms.h.func.html new file mode 100644 index 0000000000..0ddd31dcc7 --- /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-06-10 08:19:14Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ReferenceAtoms18getAbsoluteIndexesEv4
_ZNK4PLMD14ReferenceAtoms21getReferencePositionsEv2636046
_ZNK4PLMD14ReferenceAtoms25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD14ReferenceAtoms29getNumberOfReferencePositionsEv150276
_ZNK4PLMD14ReferenceAtoms33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.h.gcov.html b/coverage/reference/ReferenceAtoms.h.gcov.html new file mode 100644 index 0000000000..b251882c28 --- /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-06-10 08:19:14Functions: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      216762 :   return align;
+     119             : }
+     120             : 
+     121             : inline
+     122             : const std::vector<double> & ReferenceAtoms::getDisplace() const {
+     123      216763 :   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     2636046 : const std::vector<Vector> & ReferenceAtoms::getReferencePositions() const {
+     152     2636046 :   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.15
+
+ + + 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 0000000000..7ea1fe50f4 --- /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-06-10 08:19:14Functions: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_29ReferenceConfigurationOptionsE519082
_ZN4PLMD29ReferenceConfigurationOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE519082
_ZN4PLMD22ReferenceConfigurationD2Ev519563
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.cpp.func.html b/coverage/reference/ReferenceConfiguration.cpp.func.html new file mode 100644 index 0000000000..8bc10d87ea --- /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-06-10 08:19:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD22ReferenceConfiguration30displaceReferenceConfigurationERKdRNS_9DirectionE500
_ZN4PLMD22ReferenceConfiguration5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD22ReferenceConfigurationC2ERKNS_29ReferenceConfigurationOptionsE519082
_ZN4PLMD22ReferenceConfigurationD0Ev0
_ZN4PLMD22ReferenceConfigurationD2Ev519563
_ZN4PLMD29ReferenceConfigurationOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE519082
_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.15
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.cpp.gcov.html b/coverage/reference/ReferenceConfiguration.cpp.gcov.html new file mode 100644 index 0000000000..c57fa9c516 --- /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-06-10 08:19:14Functions: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      519082 : ReferenceConfigurationOptions::ReferenceConfigurationOptions( const std::string& type ):
+      34      519082 :   tt(type)
+      35             : {
+      36      519082 : }
+      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      519082 : ReferenceConfiguration::ReferenceConfiguration( const ReferenceConfigurationOptions& ro ):
+      49      519082 :   name(ro.tt)
+      50             : {
+      51      519082 : }
+      52             : 
+      53      519563 : ReferenceConfiguration::~ReferenceConfiguration()
+      54             : {
+      55     1039126 : }
+      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.15
+
+ + + 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 0000000000..435c67cb59 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.h.func.html b/coverage/reference/ReferenceConfiguration.h.func.html new file mode 100644 index 0000000000..e3d0b82b69 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.h.gcov.html b/coverage/reference/ReferenceConfiguration.h.gcov.html new file mode 100644 index 0000000000..b4a62939e0 --- /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-06-10 08:19:14Functions: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      519082 : 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.15
+
+ + + 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 0000000000..abca7b86e4 --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceValuePack6resizeERKjS2_98
_ZN4PLMD18ReferenceValuePack21copyScaledDerivativesERKjRKdRKNS_10MultiValueE162
_ZN4PLMD18ReferenceValuePack15moveDerivativesERKjS2_8662
_ZN4PLMD18ReferenceValuePack19scaleAllDerivativesERKd192765
_ZN4PLMD18ReferenceValuePack5clearEv241448
_ZN4PLMD18ReferenceValuePack18updateDynamicListsEv452938
_ZN4PLMD18ReferenceValuePackC2ERKjS2_RNS_10MultiValueE471328
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.cpp.func.html b/coverage/reference/ReferenceValuePack.cpp.func.html new file mode 100644 index 0000000000..654ba7d226 --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceValuePack15moveDerivativesERKjS2_8662
_ZN4PLMD18ReferenceValuePack18updateDynamicListsEv452938
_ZN4PLMD18ReferenceValuePack19scaleAllDerivativesERKd192765
_ZN4PLMD18ReferenceValuePack21copyScaledDerivativesERKjRKdRKNS_10MultiValueE162
_ZN4PLMD18ReferenceValuePack5clearEv241448
_ZN4PLMD18ReferenceValuePack6resizeERKjS2_98
_ZN4PLMD18ReferenceValuePackC2ERKjS2_RNS_10MultiValueE471328
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.cpp.gcov.html b/coverage/reference/ReferenceValuePack.cpp.gcov.html new file mode 100644 index 0000000000..7b850e2454 --- /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-06-10 08:19:14Functions: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      471328 : ReferenceValuePack::ReferenceValuePack( const unsigned& nargs, const unsigned& natoms, MultiValue& vals ):
+      27      471328 :   boxWasSet(false),
+      28      471328 :   numberOfArgs(nargs),
+      29      471328 :   oind_set(false),
+      30      471328 :   myvals(vals),
+      31      471328 :   atom_indices(myvals.getIndices()),
+      32      471328 :   pca(false)
+      33             : {
+      34      471328 :   if( atom_indices.size()!=natoms ) { atom_indices.resize( natoms ); myvals.getAtomVector().resize( natoms ); }
+      35      471328 :   if( vals.getNumberOfValues()==1 ) { oind=0; oind_set=true; }
+      36      471328 : }
+      37             : 
+      38          98 : void ReferenceValuePack::resize( const unsigned& nargs, const unsigned& natoms ) {
+      39          98 :   numberOfArgs=nargs; atom_indices.resize( natoms );
+      40          98 :   myvals.getAtomVector().resize( natoms );
+      41          98 : }
+      42             : 
+      43      452938 : void ReferenceValuePack::updateDynamicLists() {
+      44      452938 :   myvals.emptyActiveMembers();
+      45      522498 :   for(unsigned i=0; i<numberOfArgs; ++i) myvals.putIndexInActiveArray( i );
+      46    21588521 :   for(unsigned i=0; i<atom_indices.size(); ++i) {
+      47    21135583 :     unsigned nbase = numberOfArgs + 3*atom_indices[i];
+      48    21135583 :     if( atom_indices[i]<myvals.getNumberOfDerivatives() && myvals.isActive( nbase ) ) {
+      49    18163510 :       myvals.putIndexInActiveArray( nbase+0 ); myvals.putIndexInActiveArray( nbase+1 ); myvals.putIndexInActiveArray( nbase+2 );
+      50             :     }
+      51             :   }
+      52      452938 :   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      452938 :   if( atom_indices.size()>0 ) {
+      56     4181580 :     for(unsigned i=0; i<9; ++i) {
+      57     3763422 :       myvals.addDerivative( oind, nbase+i, 0.0 );
+      58     3763422 :       myvals.putIndexInActiveArray( nbase+i );
+      59             :     }
+      60             :   }
+      61      452938 :   myvals.completeUpdate();
+      62      452938 : }
+      63             : 
+      64      241448 : void ReferenceValuePack::clear() {
+      65      241448 :   if( !myvals.updateComplete() ) updateDynamicLists();
+      66      241448 :   myvals.clearAll(); boxWasSet=false;
+      67      241448 : }
+      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.15
+
+ + + 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 0000000000..8f74d950e2 --- /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-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD18ReferenceValuePack17getBoxDerivativesEv600
_ZN4PLMD18ReferenceValuePack17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE8268786
_ZN4PLMD18ReferenceValuePack18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEE16356460
_ZNK4PLMD18ReferenceValuePack17getAtomDerivativeERKj17174456
_ZN4PLMD18ReferenceValuePack18setAtomDerivativesERKjRKNS_13VectorGenericILj3EEE17546439
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.h.func.html b/coverage/reference/ReferenceValuePack.h.func.html new file mode 100644 index 0000000000..c01b0de9ad --- /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-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceValuePack17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE8268786
_ZN4PLMD18ReferenceValuePack18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEE16356460
_ZN4PLMD18ReferenceValuePack18setAtomDerivativesERKjRKNS_13VectorGenericILj3EEE17546439
_ZNK4PLMD18ReferenceValuePack17getAtomDerivativeERKj17174456
_ZNK4PLMD18ReferenceValuePack17getBoxDerivativesEv600
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.h.gcov.html b/coverage/reference/ReferenceValuePack.h.gcov.html new file mode 100644 index 0000000000..a9c60af82d --- /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-06-10 08:19:14Functions: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     2966862 :   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      520180 :   return myvals.updateComplete();
+     149             : }
+     150             : 
+     151             : inline
+     152    17546439 : void ReferenceValuePack::setAtomDerivatives( const unsigned& jder, const Vector& der ) {
+     153             :   plumed_dbg_assert( oind_set && jder<atom_indices.size() );
+     154    17546439 :   myvals.setDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 0, der[0] );
+     155    17546439 :   myvals.setDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 1, der[1] );
+     156    17546439 :   myvals.setDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 2, der[2] );
+     157    17546439 : }
+     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    17174456 : Vector ReferenceValuePack::getAtomDerivative( const unsigned& iatom ) const {
+     186    17174456 :   Vector tmp; plumed_dbg_assert( oind_set && iatom<atom_indices.size() );
+     187    17174456 :   tmp[0]=myvals.getDerivative( oind, numberOfArgs + 3*atom_indices[iatom] + 0 );
+     188    17174456 :   tmp[1]=myvals.getDerivative( oind, numberOfArgs + 3*atom_indices[iatom] + 1 );
+     189    17174456 :   tmp[2]=myvals.getDerivative( oind, numberOfArgs + 3*atom_indices[iatom] + 2 );
+     190    17174456 :   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    17764910 :   return myvals.getAtomVector();
+     219             : }
+     220             : 
+     221             : inline
+     222             : std::vector<Vector>& ReferenceValuePack::getAtomsDisplacementVector() {
+     223        3014 :   return displacement;
+     224             : }
+     225             : 
+     226             : }
+     227             : 
+     228             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..a583d7e7ac --- /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-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SimpleRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD10SimpleRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZN4PLMD10SimpleRMSD28pcaIsEnabledForThisReferenceEv4
_ZN4PLMD10SimpleRMSD4readERKNS_3PDBE25
_ZN4PLMD10SimpleRMSDC1ERKNS_29ReferenceConfigurationOptionsE29
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE29
_ZN4PLMD10SimpleRMSD15setupPCAStorageERNS_18ReferenceValuePackE68
_ZNK4PLMD10SimpleRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE88
_ZNK4PLMD10SimpleRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb160
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeD2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/SimpleRMSD.cpp.func.html b/coverage/reference/SimpleRMSD.cpp.func.html new file mode 100644 index 0000000000..a1340d2ed0 --- /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-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SimpleRMSD15setupPCAStorageERNS_18ReferenceValuePackE68
_ZN4PLMD10SimpleRMSD28pcaIsEnabledForThisReferenceEv4
_ZN4PLMD10SimpleRMSD4readERKNS_3PDBE25
_ZN4PLMD10SimpleRMSDC1ERKNS_29ReferenceConfigurationOptionsE29
_ZN4PLMD10SimpleRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE29
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeC2Ev3473
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeD2Ev3473
_ZNK4PLMD10SimpleRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD10SimpleRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE88
_ZNK4PLMD10SimpleRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb160
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/SimpleRMSD.cpp.gcov.html b/coverage/reference/SimpleRMSD.cpp.gcov.html new file mode 100644 index 0000000000..adf6cc355f --- /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-06-10 08:19:14Functions: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       10477 : PLUMED_REGISTER_METRIC(SimpleRMSD,"SIMPLE")
+      44             : 
+      45          29 : SimpleRMSD::SimpleRMSD( const ReferenceConfigurationOptions& ro ):
+      46             :   ReferenceConfiguration( ro ),
+      47          29 :   RMSDBase( ro )
+      48             : {
+      49          29 : }
+      50             : 
+      51          25 : void SimpleRMSD::read( const PDB& pdb ) {
+      52          25 :   readReference( pdb );
+      53          25 : }
+      54             : 
+      55         160 : double SimpleRMSD::calc( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const {
+      56         160 :   if( myder.getAtomsDisplacementVector().size()!=pos.size() ) myder.getAtomsDisplacementVector().resize( pos.size() );
+      57         160 :   double d=myrmsd.simpleAlignment( getAlign(), getDisplace(), pos, getReferencePositions(), myder.getAtomVector(), myder.getAtomsDisplacementVector(), squared );
+      58        2509 :   myder.clear(); for(unsigned i=0; i<pos.size(); ++i) myder.setAtomDerivatives( i, myder.getAtomVector()[i] );
+      59         160 :   if( !myder.updateComplete() ) myder.updateDynamicLists();
+      60         160 :   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.15
+
+ + + 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 0000000000..ecc339fb50 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSDC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD16SingleDomainRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_45
_ZN4PLMD16SingleDomainRMSD13readReferenceERKNS_3PDBE452
_ZN4PLMD16SingleDomainRMSDC2ERKNS_29ReferenceConfigurationOptionsE494
_ZNK4PLMD16SingleDomainRMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb58046
_ZNK4PLMD16SingleDomainRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb140941
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.cpp.func.html b/coverage/reference/SingleDomainRMSD.cpp.func.html new file mode 100644 index 0000000000..8839e73f38 --- /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-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSD13readReferenceERKNS_3PDBE452
_ZN4PLMD16SingleDomainRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_45
_ZN4PLMD16SingleDomainRMSDC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD16SingleDomainRMSDC2ERKNS_29ReferenceConfigurationOptionsE494
_ZNK4PLMD16SingleDomainRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb140941
_ZNK4PLMD16SingleDomainRMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb58046
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.cpp.gcov.html b/coverage/reference/SingleDomainRMSD.cpp.gcov.html new file mode 100644 index 0000000000..74ad39bd71 --- /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-06-10 08:19:14Functions: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         494 : SingleDomainRMSD::SingleDomainRMSD( const ReferenceConfigurationOptions& ro ):
+      29             :   ReferenceConfiguration(ro),
+      30         494 :   ReferenceAtoms(ro)
+      31             : {
+      32         494 : }
+      33             : 
+      34         452 : void SingleDomainRMSD::readReference( const PDB& pdb ) {
+      35         452 :   readAtomsFromPDB( pdb );
+      36             :   double wa=0, wd=0;
+      37        8327 :   for(unsigned i=0; i<pdb.size(); ++i) { wa+=align[i]; wd+=displace[i]; }
+      38             : 
+      39         452 :   if(wa>epsilon) {
+      40         450 :     double w=1.0/wa;
+      41        8295 :     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         452 :   if(wd>epsilon) {
+      48         450 :     double w=1.0/wd;
+      49        8295 :     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         452 :   Vector center;
+      56        8327 :   for(unsigned i=0; i<pdb.size(); ++i) {
+      57        7875 :     center+=reference_atoms[i]*align[i];
+      58             :   }
+      59        8327 :   for(unsigned i=0; i<pdb.size(); ++i) reference_atoms[i]-=center;
+      60         452 : }
+      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.15
+
+ + + 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 0000000000..275a9bb413 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSD15setupRMSDObjectEv27
_ZN4PLMD16SingleDomainRMSD20setBoundsOnDistancesEbdd28
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.h.func.html b/coverage/reference/SingleDomainRMSD.h.func.html new file mode 100644 index 0000000000..a622f9521c --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSD15setupRMSDObjectEv27
_ZN4PLMD16SingleDomainRMSD20setBoundsOnDistancesEbdd28
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.h.gcov.html b/coverage/reference/SingleDomainRMSD.h.gcov.html new file mode 100644 index 0000000000..b943b788d7 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/reference/index-sort-f.html b/coverage/reference/index-sort-f.html new file mode 100644 index 0000000000..b8519e4d35 --- /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-06-10 08:19:14Functions: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
ReferenceArguments.cpp +
63.2%63.2%
+
63.2 %67 / 10681.8 %9 / 11
SimpleRMSD.cpp +
84.8%84.8%
+
84.8 %28 / 3381.8 %9 / 11
SingleDomainRMSD.cpp +
100.0%
+
100.0 %45 / 4583.3 %5 / 6
ReferenceAtoms.cpp +
90.9%90.9%
+
90.9 %30 / 3383.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
IntramolecularDRMSD.cpp +
100.0%
+
100.0 %18 / 1885.7 %6 / 7
IntermolecularDRMSD.cpp +
100.0%
+
100.0 %19 / 1985.7 %6 / 7
OptimalRMSD.cpp +
100.0%
+
100.0 %53 / 5391.7 %11 / 12
ArgumentOnlyDistance.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
SingleDomainRMSD.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
ReferenceArguments.h +
100.0%
+
100.0 %8 / 8100.0 %4 / 4
ReferenceValuePack.h +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
MetricRegister.cpp +
80.0%80.0%
+
80.0 %16 / 20100.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.15
+
+ + + diff --git a/coverage/reference/index-sort-l.html b/coverage/reference/index-sort-l.html new file mode 100644 index 0000000000..e65a57cd3f --- /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-06-10 08:19:14Functions: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
ArgumentOnlyDistance.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
SingleDomainRMSD.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.15
+
+ + + diff --git a/coverage/reference/index.html b/coverage/reference/index.html new file mode 100644 index 0000000000..9b193bbaf3 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..5e75f5a4b4 --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:15216691.6 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4s2cm14S2ContactModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD4s2cm14S2ContactModelD2Ev0
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe796createERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelC1ERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelD0Ev24
_ZN4PLMD4s2cm14S2ContactModelD1Ev24
_ZN4PLMD4s2cm14S2ContactModel16registerKeywordsERNS_8KeywordsE25
_ZN4PLMD4s2cm14S2ContactModel7prepareEv48
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe79C2Ev3473
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe79D2Ev3473
_ZN4PLMD4s2cm14S2ContactModel9calculateEv5952
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/s2cm/S2ContactModel.cpp.func.html b/coverage/s2cm/S2ContactModel.cpp.func.html new file mode 100644 index 0000000000..f3eaa47e60 --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:15216691.6 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe796createERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe79C2Ev3473
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe79D2Ev3473
_ZN4PLMD4s2cm14S2ContactModel16registerKeywordsERNS_8KeywordsE25
_ZN4PLMD4s2cm14S2ContactModel7prepareEv48
_ZN4PLMD4s2cm14S2ContactModel9calculateEv5952
_ZN4PLMD4s2cm14S2ContactModelC1ERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD4s2cm14S2ContactModelD0Ev24
_ZN4PLMD4s2cm14S2ContactModelD1Ev24
_ZN4PLMD4s2cm14S2ContactModelD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/s2cm/S2ContactModel.cpp.gcov.html b/coverage/s2cm/S2ContactModel.cpp.gcov.html new file mode 100644 index 0000000000..6d4de42b71 --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.gcov.html @@ -0,0 +1,400 @@ + + + + + + + + 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:15216691.6 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ + + + + + + + +

+
          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 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.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : 
+      47             : 
+      48             : 
+      49             : 
+      50             : 
+      51             : 
+      52             : class S2ContactModel : public Colvar {
+      53             :   bool pbc_;
+      54             :   bool serial_;
+      55             :   std::unique_ptr<NeighborList> nl;
+      56             :   bool invalidateList;
+      57             :   bool firsttime;
+      58             :   //
+      59             :   double r_eff_;
+      60             :   double inv_r_eff_;
+      61             :   double prefactor_a_;
+      62             :   double exp_b_;
+      63             :   double offset_c_;
+      64             :   double n_i_;
+      65             :   double total_prefactor_;
+      66             :   double r_globalshift_;
+      67             : 
+      68             :   enum ModelType {methyl,nh} modeltype_;
+      69             : 
+      70             :   //
+      71             : public:
+      72             :   explicit S2ContactModel(const ActionOptions&);
+      73             :   ~S2ContactModel();
+      74             :   virtual void calculate();
+      75             :   virtual void prepare();
+      76             :   static void registerKeywords( Keywords& keys );
+      77             : };
+      78             : 
+      79       10467 : PLUMED_REGISTER_ACTION(S2ContactModel,"S2CM")
+      80             : 
+      81          25 : void S2ContactModel::registerKeywords( Keywords& keys ) {
+      82          25 :   Colvar::registerKeywords(keys);
+      83          50 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+      84          50 :   keys.addFlag("NLIST",false,"Use a neighbour list to speed up the calculation");
+      85          50 :   keys.add("optional","NL_CUTOFF","The cutoff for the neighbour list");
+      86          50 :   keys.add("optional","NL_STRIDE","The frequency with which we are updating the atoms in the neighbour list");
+      87          50 :   keys.add("atoms","METHYL_ATOM","the methyl carbon atom of the residue (i)");
+      88          50 :   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)");
+      89          50 :   keys.add("atoms","HEAVY_ATOMS","the heavy atoms to be included in the calculation");
+      90             :   //
+      91          50 :   keys.add("compulsory","R_EFF","the effective distance, r_eff in the equation, given in nm.");
+      92          50 :   keys.add("compulsory","PREFACTOR_A","the prefactor, a in the equation");
+      93          50 :   keys.add("compulsory","EXPONENT_B","the exponent, b in the equation");
+      94          50 :   keys.add("compulsory","OFFSET_C","the offset, c in the equation");
+      95          50 :   keys.add("compulsory","N_I"," n_i in the equation");
+      96          50 :   keys.add("optional","R_SHIFT","shift all distances by given amount");
+      97          25 : }
+      98             : 
+      99          24 : S2ContactModel::S2ContactModel(const ActionOptions&ao):
+     100             :   PLUMED_COLVAR_INIT(ao),
+     101          24 :   pbc_(true),
+     102          24 :   serial_(false),
+     103          24 :   invalidateList(true),
+     104          24 :   firsttime(true),
+     105          24 :   r_eff_(0.0),
+     106          24 :   inv_r_eff_(0.0),
+     107          24 :   prefactor_a_(0.0),
+     108          24 :   exp_b_(0.0),
+     109          24 :   offset_c_(0.0),
+     110          24 :   n_i_(0.0),
+     111          24 :   total_prefactor_(0.0),
+     112          24 :   r_globalshift_(0.0),
+     113          24 :   modeltype_(methyl)
+     114             : {
+     115             : 
+     116          48 :   parseFlag("SERIAL",serial_);
+     117             : 
+     118             :   std::vector<AtomNumber> methyl_atom;
+     119          48 :   parseAtomList("METHYL_ATOM",methyl_atom);
+     120             :   std::vector<AtomNumber> nh_atoms;
+     121          48 :   parseAtomList("NH_ATOMS",nh_atoms);
+     122             : 
+     123          24 :   if(methyl_atom.size()==0 && nh_atoms.size()==0) {
+     124           0 :     error("you have to give either METHYL_ATOM or NH_ATOMS");
+     125             :   }
+     126          24 :   if(methyl_atom.size()>0 && nh_atoms.size()>0) {
+     127           0 :     error("you cannot give both METHYL_ATOM or NH_ATOMS");
+     128             :   }
+     129          24 :   if(methyl_atom.size()>0 && methyl_atom.size()!=1) {
+     130           0 :     error("you should give one atom in METHYL_ATOM, the methyl carbon atom of the residue");
+     131             :   }
+     132          24 :   if(nh_atoms.size()>0 && nh_atoms.size()!=2) {
+     133           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)");
+     134             :   }
+     135             : 
+     136             :   std::vector<AtomNumber> heavy_atoms;
+     137          48 :   parseAtomList("HEAVY_ATOMS",heavy_atoms);
+     138          24 :   if(heavy_atoms.size()==0) {
+     139           0 :     error("HEAVY_ATOMS is not given");
+     140             :   }
+     141             : 
+     142             :   std::vector<AtomNumber> main_atoms;
+     143          24 :   if(methyl_atom.size()>0) {
+     144           0 :     modeltype_= methyl;
+     145           0 :     main_atoms = methyl_atom;
+     146          24 :   } else if(nh_atoms.size()>0) {
+     147          24 :     modeltype_= nh;
+     148          24 :     main_atoms = nh_atoms;
+     149             :   }
+     150             : 
+     151          24 :   bool nopbc=!pbc_;
+     152          24 :   parseFlag("NOPBC",nopbc);
+     153          24 :   pbc_=!nopbc;
+     154             : 
+     155             :   // neighbor list stuff
+     156          24 :   bool doneigh=false;
+     157          24 :   double nl_cut=0.0;
+     158          24 :   int nl_st=0;
+     159          24 :   parseFlag("NLIST",doneigh);
+     160          24 :   if(doneigh) {
+     161          12 :     parse("NL_CUTOFF",nl_cut);
+     162          12 :     if(nl_cut<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     163          12 :     parse("NL_STRIDE",nl_st);
+     164          12 :     if(nl_st<=0) error("NL_STRIDE should be explicitly specified and positive");
+     165             :   }
+     166             : 
+     167          24 :   parse("R_EFF",r_eff_);
+     168          24 :   inv_r_eff_ = 1.0/r_eff_;
+     169          24 :   parse("PREFACTOR_A",prefactor_a_);
+     170          24 :   parse("EXPONENT_B",exp_b_);
+     171          24 :   parse("OFFSET_C",offset_c_);
+     172             :   unsigned int n_i_int;
+     173          24 :   parse("N_I",n_i_int);
+     174          24 :   n_i_ = static_cast<double>(n_i_int);
+     175          24 :   total_prefactor_ = prefactor_a_/pow(n_i_,exp_b_);
+     176             :   //
+     177          24 :   parse("R_SHIFT",r_globalshift_);
+     178             : 
+     179          24 :   checkRead();
+     180             : 
+     181          24 :   addValueWithDerivatives();
+     182          24 :   setNotPeriodic();
+     183             : 
+     184          24 :   bool dopair=false;
+     185          24 :   if(doneigh) {
+     186          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm,nl_cut,nl_st);
+     187             :   }
+     188             :   else {
+     189          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm);
+     190             :   }
+     191             : 
+     192          24 :   requestAtoms(nl->getFullAtomList());
+     193             : 
+     194             : 
+     195          24 :   log.printf("  NMR S2 contact model CV, please read and cite ");
+     196          48 :   log << plumed.cite("Palazzesi, Valsson, and Parrinello, J. Phys. Chem. Lett. 8, 4752 (2017) - DOI:10.1021/acs.jpclett.7b01770");
+     197             : 
+     198          24 :   if(modeltype_==methyl) {
+     199           0 :     log << plumed.cite("Ming and Bruschweiler, J. Biomol. NMR, 29, 363 (2004) - DOI:10.1023/B:JNMR.0000032612.70767.35");
+     200           0 :     log.printf("\n");
+     201           0 :     log.printf("  calculation of methyl order parameter using atom %d \n",methyl_atom[0].serial());
+     202             :   }
+     203          24 :   else if(modeltype_==nh) {
+     204          48 :     log << plumed.cite("Zhang and Bruschweiler, J. Am. Chem. Soc. 124, 12654 (2002) - DOI:10.1021/ja027847a");
+     205          24 :     log.printf("\n");
+     206          24 :     log.printf("  calculation of NH order parameter using atoms %d and %d\n",nh_atoms[0].serial(),nh_atoms[1].serial());
+     207             :   }
+     208          24 :   log.printf("  heavy atoms used in the calculation (%u in total):\n",static_cast<unsigned int>(heavy_atoms.size()));
+     209        1872 :   for(unsigned int i=0; i<heavy_atoms.size(); ++i) {
+     210        1848 :     if( (i+1) % 25 == 0 ) {log.printf("  \n");}
+     211        1848 :     log.printf("  %d", heavy_atoms[i].serial());
+     212             :   }
+     213          24 :   log.printf("  \n");
+     214          24 :   log.printf("  total number of distances: %u\n",nl->size());
+     215             :   //
+     216          24 :   log.printf("  using parameters");
+     217          24 :   log.printf(" r_eff=%f,",r_eff_);
+     218          24 :   log.printf(" a=%f,",prefactor_a_);
+     219          24 :   log.printf(" b=%f,",exp_b_);
+     220          24 :   log.printf(" c=%f,",offset_c_);
+     221          24 :   log.printf(" n_i=%u",n_i_int);
+     222          24 :   if(r_globalshift_!=0.0) {
+     223           4 :     log.printf(", r_shift=%f",r_globalshift_);
+     224             :   }
+     225          24 :   log.printf("\n");
+     226          24 :   if(pbc_) {
+     227          12 :     log.printf("  using periodic boundary conditions\n");
+     228             :   } else {
+     229          12 :     log.printf("  without periodic boundary conditions\n");
+     230             :   }
+     231          24 :   if(doneigh) {
+     232          12 :     log.printf("  using neighbor lists with\n");
+     233          12 :     log.printf("  update every %d steps and cutoff %f\n",nl_st,nl_cut);
+     234             :   }
+     235          24 :   if(serial_) {
+     236           0 :     log.printf("  calculation done in serial\n");
+     237             :   }
+     238          24 : }
+     239             : 
+     240          48 : S2ContactModel::~S2ContactModel() {
+     241          48 : }
+     242             : 
+     243          48 : void S2ContactModel::prepare() {
+     244          48 :   if(nl->getStride()>0) {
+     245          24 :     if(firsttime || (getStep()%nl->getStride()==0)) {
+     246          24 :       requestAtoms(nl->getFullAtomList());
+     247          24 :       invalidateList=true;
+     248          24 :       firsttime=false;
+     249             :     } else {
+     250           0 :       requestAtoms(nl->getReducedAtomList());
+     251           0 :       invalidateList=false;
+     252           0 :       if(getExchangeStep()) error("Neighbor lists should be updated on exchange steps - choose a NL_STRIDE which divides the exchange stride!");
+     253             :     }
+     254          24 :     if(getExchangeStep()) firsttime=true;
+     255             :   }
+     256          48 : }
+     257             : 
+     258             : // calculator
+     259        5952 : void S2ContactModel::calculate() {
+     260             : 
+     261        5952 :   Tensor virial;
+     262        5952 :   std::vector<Vector> deriv(getNumberOfAtoms());
+     263             : 
+     264        5952 :   if(nl->getStride()>0 && invalidateList) {
+     265        2976 :     nl->update(getPositions());
+     266             :   }
+     267             : 
+     268        5952 :   unsigned int stride=comm.Get_size();
+     269        5952 :   unsigned int rank=comm.Get_rank();
+     270        5952 :   if(serial_) {
+     271             :     stride=1;
+     272             :     rank=0;
+     273             :   }
+     274             : 
+     275        5952 :   double contact_sum = 0.0;
+     276             : 
+     277        5952 :   const unsigned int nn=nl->size();
+     278             : 
+     279      321408 :   for(unsigned int i=rank; i<nn; i+=stride) {
+     280      315456 :     Vector distance;
+     281      315456 :     unsigned int i0=nl->getClosePair(i).first;
+     282      315456 :     unsigned int i1=nl->getClosePair(i).second;
+     283      315456 :     if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) {continue;}
+     284             : 
+     285      315456 :     if(pbc_) {
+     286       86304 :       distance=pbcDistance(getPosition(i0),getPosition(i1));
+     287             :     } else {
+     288      229152 :       distance=delta(getPosition(i0),getPosition(i1));
+     289             :     }
+     290             : 
+     291      315456 :     double exp_arg = exp(-(distance.modulo()-r_globalshift_)*inv_r_eff_);
+     292      315456 :     contact_sum += exp_arg;
+     293             : 
+     294      315456 :     exp_arg /= distance.modulo();
+     295      315456 :     Vector dd(exp_arg*distance);
+     296      315456 :     Tensor vv(dd,distance);
+     297      315456 :     deriv[i0]-=dd;
+     298      315456 :     deriv[i1]+=dd;
+     299      315456 :     virial-=vv;
+     300             :   }
+     301             : 
+     302        5952 :   if(!serial_) {
+     303        5952 :     comm.Sum(contact_sum);
+     304        5952 :     if(!deriv.empty()) {
+     305        5952 :       comm.Sum(&deriv[0][0],3*deriv.size());
+     306             :     }
+     307        5952 :     comm.Sum(virial);
+     308             :   }
+     309             : 
+     310        5952 :   double value = tanh(total_prefactor_*contact_sum);
+     311             :   // using that d/dx[tanh(x)]= 1-[tanh(x)]^2
+     312        5952 :   double deriv_f = -inv_r_eff_*total_prefactor_*(1.0-value*value);
+     313        5952 :   value -= offset_c_;
+     314             : 
+     315      476160 :   for(unsigned int i=0; i<deriv.size(); ++i) {
+     316      470208 :     setAtomsDerivatives(i,deriv_f*deriv[i]);
+     317             :   }
+     318        5952 :   setValue(value);
+     319        5952 :   setBoxDerivatives(deriv_f*virial);
+     320             : 
+     321        5952 : }
+     322             : }
+     323             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/s2cm/index-sort-f.html b/coverage/s2cm/index-sort-f.html new file mode 100644 index 0000000000..983210b7fe --- /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:15216691.6 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.6%91.6%
+
91.6 %152 / 16681.8 %9 / 11
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/s2cm/index-sort-l.html b/coverage/s2cm/index-sort-l.html new file mode 100644 index 0000000000..ffeaf21c96 --- /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:15216691.6 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.6%91.6%
+
91.6 %152 / 16681.8 %9 / 11
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/s2cm/index.html b/coverage/s2cm/index.html new file mode 100644 index 0000000000..56386637a5 --- /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:15216691.6 %
Date:2024-06-10 08:19:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.6%91.6%
+
91.6 %152 / 16681.8 %9 / 11
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/sasa/index-sort-f.html b/coverage/sasa/index-sort-f.html new file mode 100644 index 0000000000..050f6a0e32 --- /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:1004122382.1 %
Date:2024-06-10 08:19:14Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_LCPO.cpp +
82.3%82.3%
+
82.3 %522 / 63481.2 %13 / 16
sasa_HASEL.cpp +
81.8%81.8%
+
81.8 %482 / 58987.5 %14 / 16
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/sasa/index-sort-l.html b/coverage/sasa/index-sort-l.html new file mode 100644 index 0000000000..2c79e2551c --- /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:1004122382.1 %
Date:2024-06-10 08:19:14Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.8%81.8%
+
81.8 %482 / 58987.5 %14 / 16
sasa_LCPO.cpp +
82.3%82.3%
+
82.3 %522 / 63481.2 %13 / 16
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/sasa/index.html b/coverage/sasa/index.html new file mode 100644 index 0000000000..8c00e46929 --- /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:1004122382.1 %
Date:2024-06-10 08:19:14Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.8%81.8%
+
81.8 %482 / 58987.5 %14 / 16
sasa_LCPO.cpp +
82.3%82.3%
+
82.3 %522 / 63481.2 %13 / 16
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..46b09a6215 --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + 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:48258981.8 %
Date:2024-06-10 08:19:14Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe1636createERKNS_13ActionOptionsE2
_ZN4PLMD4sasa10SASA_HASEL16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4sasa10SASA_HASEL9calcNlistEv24
_ZN4PLMD4sasa10SASA_HASEL9calculateEv24
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_42
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe163C2Ev3473
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe163D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.func.html b/coverage/sasa/sasa_HASEL.cpp.func.html new file mode 100644 index 0000000000..30ed1e03aa --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + 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:48258981.8 %
Date:2024-06-10 08:19:14Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_8KeywordsE3
_ZN4PLMD4sasa10SASA_HASEL7readPDBEv2
_ZN4PLMD4sasa10SASA_HASEL9calcNlistEv24
_ZN4PLMD4sasa10SASA_HASEL9calculateEv24
_ZN4PLMD4sasa10SASA_HASELC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa10SASA_HASELC2ERKNS_13ActionOptionsE0
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe1636createERKNS_13ActionOptionsE2
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe163C2Ev3473
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe163D2Ev3473
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_42
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.gcov.html b/coverage/sasa/sasa_HASEL.cpp.gcov.html new file mode 100644 index 0000000000..e0869f2104 --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.gcov.html @@ -0,0 +1,1087 @@ + + + + + + + + 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:48258981.8 %
Date:2024-06-10 08:19:14Functions:141687.5 %
+
+ + + + + + + + +

+
          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 "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. 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).
+      44             : 
+      45             : Different properties can be calculated and selected using the TYPE keyword:
+      46             : 
+      47             : 1) the total SASA (TOTAL);
+      48             : 
+      49             : 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.
+      50             : 
+      51             : 
+      52             : 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:
+      53             : 
+      54             : \verbatim
+      55             : 
+      56             : ----------------Sample DeltaG.dat file---------------------
+      57             : ALA     0.711019999999962
+      58             : ARG     -2.24832799999996
+      59             : ASN     -2.74838799999999
+      60             : ASP     -2.5626376
+      61             : CYS     3.89864000000006
+      62             : GLN     -1.76192
+      63             : GLU     -2.38664400000002
+      64             : GLY     0
+      65             : HIS     -3.58152799999999
+      66             : ILE     2.42634399999986
+      67             : LEU     1.77233599999988
+      68             : LYS     -1.92576400000002
+      69             : MET     -0.262827999999956
+      70             : PHE     1.62028800000007
+      71             : PRO     -2.15598800000001
+      72             : SER     -1.60934800000004
+      73             : THR     -0.591559999999987
+      74             : TRP     1.22936000000027
+      75             : TYR     0.775547999999958
+      76             : VAL     2.12779200000011
+      77             : BACKBONE        1.00066920000002
+      78             : -----------------------------------------------------------
+      79             : \endverbatim
+      80             : 
+      81             : where the second column is the free energy of transfer for each sidechain/backbone, in kJ/mol.
+      82             : 
+      83             : 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.
+      84             : 
+      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_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.
+      94             : 
+      95             : 
+      96             : \par Examples
+      97             : 
+      98             : The following input tells plumed to print the total SASA for atoms 10 to 20 in a protein chain.
+      99             : \plumedfile
+     100             : SASA_HASEL TYPE=TOTAL ATOMS=10-20 NL_STRIDE=10 LABEL=sasa
+     101             : PRINT ARG=sasa STRIDE=1 FILE=colvar
+     102             : \endplumedfile
+     103             : 
+     104             : 
+     105             : 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.
+     106             : 
+     107             : \plumedfile
+     108             : SASA_HASEL TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 DELTAGFILE=DeltaG.dat LABEL=sasa
+     109             : 
+     110             : bias: BIASVALUE ARG=sasa
+     111             : 
+     112             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     113             : \endplumedfile
+     114             : 
+     115             : 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.
+     116             : 
+     117             : \plumedfile
+     118             : SASA_HASEL TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 APPROACH=2 LABEL=sasa
+     119             : 
+     120             : bias: BIASVALUE ARG=sasa
+     121             : 
+     122             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     123             : \endplumedfile
+     124             : 
+     125             : */
+     126             : //+ENDPLUMEDOC
+     127             : 
+     128             : class SASA_HASEL : public Colvar {
+     129             : private:
+     130             :   enum CV_TYPE {TOTAL, TRANSFER};
+     131             :   int sasa_type;
+     132             :   bool nopbc;
+     133             :   double rs;
+     134             :   string DeltaGValues;
+     135             :   int approach;
+     136             :   unsigned stride;
+     137             :   unsigned nl_update;
+     138             :   int firstStepFlag;
+     139             :   double Ti;
+     140             :   // cppcheck-suppress duplInheritedMember
+     141             :   std::vector<AtomNumber> atoms;
+     142             :   vector < vector < std::string > > AtomResidueName;
+     143             :   vector < vector < double > > SASAparam;
+     144             :   vector < vector < std::string > > CONNECTparam;
+     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_HASEL(const ActionOptions&);
+     152             :   void readPDB();
+     153             :   map<string, vector<std::string> > setupHASELparam();
+     154             :   void readSASAparam();
+     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       10423 : PLUMED_REGISTER_ACTION(SASA_HASEL,"SASA_HASEL")
+     164             : 
+     165           3 : void SASA_HASEL::registerKeywords(Keywords& keys) {
+     166           3 :   Colvar::registerKeywords(keys);
+     167           6 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the SASA for");
+     168           6 :   keys.add("compulsory","TYPE","TOTAL","The type of calculation you want to perform. Can be TOTAL or TRANSFER");
+     169           6 :   keys.add("compulsory", "NL_STRIDE", "The frequency with which the neighbor list for the calculation of SASA is updated.");
+     170           6 :   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");
+     171           6 :   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           3 : }
+     173             : 
+     174             : 
+     175           2 : SASA_HASEL::SASA_HASEL(const ActionOptions&ao):
+     176             :   PLUMED_COLVAR_INIT(ao),
+     177           2 :   nopbc(false),
+     178           2 :   stride(10),
+     179           2 :   nl_update(0),
+     180           4 :   DeltaGValues("absent"),
+     181           2 :   Ti(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           2 :   addValueWithDerivatives(); setNotPeriodic();
+     220           2 :   requestAtoms(atoms);
+     221             : 
+     222           2 :   natoms = getNumberOfAtoms();
+     223           2 :   AtomResidueName.resize(2);
+     224           2 :   SASAparam.resize(natoms);
+     225           2 :   CONNECTparam.resize(natoms);
+     226           2 :   MaxSurf.resize(natoms);
+     227           2 :   DeltaG.resize(natoms+1);
+     228           2 :   Nlist.resize(natoms);
+     229             : 
+     230             : 
+     231           2 : }
+     232             : 
+     233             : 
+     234             : //splits strings into tokens. Used to read into SASA parameters file and into reference pdb file
+     235             : template <class Container>
+     236          42 : void split(const std::string& str, Container& cont)
+     237             : {
+     238          42 :   std::istringstream iss(str);
+     239          84 :   std::copy(std::istream_iterator<std::string>(iss),
+     240          42 :             std::istream_iterator<std::string>(),
+     241             :             std::back_inserter(cont));
+     242          42 : }
+     243             : 
+     244             : 
+     245             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     246             : 
+     247           2 : void SASA_HASEL::readPDB() {
+     248           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     249           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     250           2 :   AtomResidueName[0].clear();
+     251           2 :   AtomResidueName[1].clear();
+     252             : 
+     253         242 :   for(unsigned i=0; i<natoms; i++) {
+     254         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     255         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     256         240 :     AtomResidueName[0].push_back (Aname);
+     257         240 :     AtomResidueName[1].push_back (Rname);
+     258             :   }
+     259             : 
+     260           2 : }
+     261             : 
+     262             : 
+     263             : //Hasel et al. parameters database
+     264           2 : map<string, vector<std::string> > SASA_HASEL::setupHASELparam() {
+     265             :   map<string, vector<std::string> > haselmap;
+     266          16 :   haselmap["ALA_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     267          16 :   haselmap["ALA_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     268          16 :   haselmap["ALA_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     269          16 :   haselmap["ALA_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     270          16 :   haselmap["ALA_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     271          16 :   haselmap["ALA_CB"] = { "2.0",  "0.88",  "CA",  "Z",  "Z",  "Z", };
+     272          16 :   haselmap["ASP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     273          16 :   haselmap["ASP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     274          16 :   haselmap["ASP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     275          16 :   haselmap["ASP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     276          16 :   haselmap["ASP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     277          16 :   haselmap["ASP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     278          16 :   haselmap["ASP_CG"] = { "1.72",  "1.554",  "CB",  "OD1",  "OD2",  "Z", };
+     279          16 :   haselmap["ASP_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     280          16 :   haselmap["ASP_OD2"] = { "1.7",  "0.922",  "CG",  "Z",  "Z",  "Z", };
+     281          16 :   haselmap["ASN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     282          16 :   haselmap["ASN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     283          16 :   haselmap["ASN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     284          16 :   haselmap["ASN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     285          16 :   haselmap["ASN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     286          16 :   haselmap["ASN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     287          16 :   haselmap["ASN_CG"] = { "1.7",  "2.149",  "CB",  "OD1",  "ND2",  "Z", };
+     288          16 :   haselmap["ASN_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     289          16 :   haselmap["ASN_ND2"] = { "1.6",  "1.215",  "CG",  "1HD2",  "1HD2",  "Z", };
+     290          16 :   haselmap["ASN_1HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     291          16 :   haselmap["ASN_2HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     292          16 :   haselmap["ARG_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     293          16 :   haselmap["ARG_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     294          16 :   haselmap["ARG_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     295          16 :   haselmap["ARG_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     296          16 :   haselmap["ARG_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     297          16 :   haselmap["ARG_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     298          16 :   haselmap["ARG_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     299          16 :   haselmap["ARG_CD"] = { "1.9",  "1.045",  "CG",  "NE",  "Z",  "Z", };
+     300          16 :   haselmap["ARG_NE"] = { "1.55",  "1.028",  "CD",  "HE",  "CZ",  "Z", };
+     301          16 :   haselmap["ARG_NH1"] = { "1.55",  "1.028",  "CZ",  "1HH1",  "2HH1",  "Z", };
+     302          16 :   haselmap["ARG_NH2"] = { "1.55",  "1.028",  "CZ",  "1HH2",  "2HH2",  "Z", };
+     303          16 :   haselmap["ARG_CZ"] = { "1.72",  "1.554",  "NE",  "NH1",  "NH2",  "Z", };
+     304          16 :   haselmap["ARG_HE"] = { "1.1",  "1.128",  "NE",  "Z",  "Z",  "Z", };
+     305          16 :   haselmap["ARG_1HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     306          16 :   haselmap["ARG_2HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     307          16 :   haselmap["ARG_2HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     308          16 :   haselmap["ARG_1HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     309          16 :   haselmap["CYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     310          16 :   haselmap["CYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     311          16 :   haselmap["CYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     312          16 :   haselmap["CYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     313          16 :   haselmap["CYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     314          16 :   haselmap["CYS_CB"] = { "1.9",  "1.045",  "CA",  "SG",  "Z",  "Z", };
+     315          16 :   haselmap["CYS_SG"] = { "1.8",  "1.121",  "CB",  "HG",  "Z",  "Z", };
+     316          16 :   haselmap["CYS_HG"] = { "1.2",  "0.928",  "SG",  "Z",  "Z",  "Z", };
+     317          16 :   haselmap["GLU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     318          16 :   haselmap["GLU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     319          16 :   haselmap["GLU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     320          16 :   haselmap["GLU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     321          16 :   haselmap["GLU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     322          16 :   haselmap["GLU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     323          16 :   haselmap["GLU_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     324          16 :   haselmap["GLU_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "OE2",  "Z", };
+     325          16 :   haselmap["GLU_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     326          16 :   haselmap["GLU_OE2"] = { "1.7",  "0.922",  "CD",  "Z",  "Z",  "Z", };
+     327          16 :   haselmap["GLN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     328          16 :   haselmap["GLN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     329          16 :   haselmap["GLN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     330          16 :   haselmap["GLN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     331          16 :   haselmap["GLN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     332          16 :   haselmap["GLN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     333          16 :   haselmap["GLN_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     334          16 :   haselmap["GLN_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "NE2",  "Z", };
+     335          16 :   haselmap["GLN_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     336          16 :   haselmap["GLN_NE2"] = { "1.6",  "1.215",  "CD",  "2HE2",  "1HE2",  "Z", };
+     337          16 :   haselmap["GLN_2HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     338          16 :   haselmap["GLN_1HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     339          16 :   haselmap["GLY_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     340          16 :   haselmap["GLY_CA"] = { "1.7",  "2.149",  "N",  "C",  "Z",  "Z", };
+     341          16 :   haselmap["GLY_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     342          16 :   haselmap["GLY_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     343          16 :   haselmap["GLY_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     344          16 :   haselmap["HIS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     345          16 :   haselmap["HIS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     346          16 :   haselmap["HIS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     347          16 :   haselmap["HIS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     348          16 :   haselmap["HIS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     349          16 :   haselmap["HIS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     350          16 :   haselmap["HIS_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "ND1",  "Z", };
+     351          16 :   haselmap["HIS_ND1"] = { "1.55",  "1.028",  "CG",  "CE1",  "Z",  "Z", };
+     352          16 :   haselmap["HIS_CE1"] = { "1.8",  "1.073",  "ND1",  "NE2",  "Z",  "Z", };
+     353          16 :   haselmap["HIS_NE2"] = { "1.55",  "1.413",  "CE1",  "2HE",  "CD2",  "Z", };
+     354          16 :   haselmap["HIS_CD2"] = { "1.8",  "1.073",  "NE2",  "CG",  "Z",  "Z", };
+     355          16 :   haselmap["HIS_2HE"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     356          16 :   haselmap["ILE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     357          16 :   haselmap["ILE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     358          16 :   haselmap["ILE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     359          16 :   haselmap["ILE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     360          16 :   haselmap["ILE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     361          16 :   haselmap["ILE_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "CG1",  "Z", };
+     362          16 :   haselmap["ILE_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     363          16 :   haselmap["ILE_CG1"] = { "1.9",  "1.045",  "CB",  "CD1",  "Z",  "Z", };
+     364          16 :   haselmap["ILE_CD1"] = { "2.0",  "0.88",  "CG1",  "Z",  "Z",  "Z", };
+     365          16 :   haselmap["LEU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     366          16 :   haselmap["LEU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     367          16 :   haselmap["LEU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     368          16 :   haselmap["LEU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     369          16 :   haselmap["LEU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     370          16 :   haselmap["LEU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     371          16 :   haselmap["LEU_CG"] = { "1.8",  "1.276",  "CB",  "CD1",  "CD2",  "Z", };
+     372          16 :   haselmap["LEU_CD1"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     373          16 :   haselmap["LEU_CD2"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     374          16 :   haselmap["LYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     375          16 :   haselmap["LYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     376          16 :   haselmap["LYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     377          16 :   haselmap["LYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     378          16 :   haselmap["LYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     379          16 :   haselmap["LYS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     380          16 :   haselmap["LYS_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     381          16 :   haselmap["LYS_CD"] = { "1.9",  "1.045",  "CG",  "CE",  "Z",  "Z", };
+     382          16 :   haselmap["LYS_CE"] = { "1.9",  "1.045",  "CD",  "NZ",  "Z",  "Z", };
+     383          16 :   haselmap["LYS_NZ"] = { "1.6",  "1.215",  "CE",  "1HZ",  "2HZ",  "3HZ", };
+     384          16 :   haselmap["LYS_1HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     385          16 :   haselmap["LYS_2HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     386          16 :   haselmap["LYS_3HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     387          16 :   haselmap["MET_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     388          16 :   haselmap["MET_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     389          16 :   haselmap["MET_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     390          16 :   haselmap["MET_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     391          16 :   haselmap["MET_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     392          16 :   haselmap["MET_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     393          16 :   haselmap["MET_CG"] = { "1.9",  "1.045",  "CB",  "SD",  "Z",  "Z", };
+     394          16 :   haselmap["MET_SD"] = { "1.8",  "1.121",  "CG",  "CE",  "Z",  "Z", };
+     395          16 :   haselmap["MET_CE"] = { "2.0",  "0.88",  "SD",  "Z",  "Z",  "Z", };
+     396          16 :   haselmap["PHE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     397          16 :   haselmap["PHE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     398          16 :   haselmap["PHE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     399          16 :   haselmap["PHE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     400          16 :   haselmap["PHE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     401          16 :   haselmap["PHE_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     402          16 :   haselmap["PHE_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     403          16 :   haselmap["PHE_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     404          16 :   haselmap["PHE_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     405          16 :   haselmap["PHE_CZ"] = { "1.8",  "1.073",  "CE1",  "CE2",  "Z",  "Z", };
+     406          16 :   haselmap["PHE_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     407          16 :   haselmap["PHE_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     408          16 :   haselmap["PRO_N"] = { "1.55",  "1.028",  "CD",  "CA",  "Z",  "Z", };
+     409          16 :   haselmap["PRO_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     410          16 :   haselmap["PRO_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     411          16 :   haselmap["PRO_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     412          16 :   haselmap["PRO_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     413          16 :   haselmap["PRO_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     414          16 :   haselmap["PRO_CD"] = { "1.9",  "1.045",  "CG",  "N",  "Z",  "Z", };
+     415          16 :   haselmap["SER_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     416          16 :   haselmap["SER_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     417          16 :   haselmap["SER_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     418          16 :   haselmap["SER_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     419          16 :   haselmap["SER_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     420          16 :   haselmap["SER_CB"] = { "1.9",  "1.045",  "CA",  "OG",  "Z",  "Z", };
+     421          16 :   haselmap["SER_OG"] = { "1.52",  "1.08",  "CB",  "HG",  "Z",  "Z", };
+     422          16 :   haselmap["SER_HG"] = { "1.0",  "0.944",  "OG",  "Z",  "Z",  "Z", };
+     423          16 :   haselmap["THR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     424          16 :   haselmap["THR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     425          16 :   haselmap["THR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     426          16 :   haselmap["THR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     427          16 :   haselmap["THR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     428          16 :   haselmap["THR_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "OG1",  "Z", };
+     429          16 :   haselmap["THR_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     430          16 :   haselmap["THR_OG1"] = { "1.52",  "1.08",  "1HG",  "CB",  "Z",  "Z", };
+     431          16 :   haselmap["THR_1HG"] = { "1.0",  "0.944",  "OG1",  "Z",  "Z",  "Z", };
+     432          16 :   haselmap["TRP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     433          16 :   haselmap["TRP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     434          16 :   haselmap["TRP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     435          16 :   haselmap["TRP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     436          16 :   haselmap["TRP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     437          16 :   haselmap["TRP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     438          16 :   haselmap["TRP_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "CD1",  "Z", };
+     439          16 :   haselmap["TRP_CD1"] = { "1.8",  "1.073",  "CG",  "NE1",  "Z",  "Z", };
+     440          16 :   haselmap["TRP_NE1"] = { "1.55",  "1.413",  "CD1",  "CE2",  "1HE",  "Z", };
+     441          16 :   haselmap["TRP_CE2"] = { "1.72",  "1.554",  "NE1",  "CD2",  "CZ2",  "Z", };
+     442          16 :   haselmap["TRP_CZ2"] = { "1.8",  "1.073",  "CE2",  "CH2",  "Z",  "Z", };
+     443          16 :   haselmap["TRP_CH2"] = { "1.8",  "1.073",  "CZ2",  "CZ3",  "Z",  "Z", };
+     444          16 :   haselmap["TRP_CZ3"] = { "1.8",  "1.073",  "CH2",  "CE3",  "Z",  "Z", };
+     445          16 :   haselmap["TRP_CE3"] = { "1.8",  "1.073",  "CZ3",  "CD2",  "Z",  "Z", };
+     446          16 :   haselmap["TRP_CD2"] = { "1.72",  "1.554",  "CE3",  "CE2",  "CG",  "Z", };
+     447          16 :   haselmap["TRP_1HE"] = { "1.1",  "1.128",  "NE1",  "Z",  "Z",  "Z", };
+     448          16 :   haselmap["TYR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     449          16 :   haselmap["TYR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     450          16 :   haselmap["TYR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     451          16 :   haselmap["TYR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     452          16 :   haselmap["TYR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     453          16 :   haselmap["TYR_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     454          16 :   haselmap["TYR_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     455          16 :   haselmap["TYR_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     456          16 :   haselmap["TYR_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     457          16 :   haselmap["TYR_CZ"] = { "1.72",  "1.554",  "CE1",  "OH",  "CE2",  "Z", };
+     458          16 :   haselmap["TYR_OH"] = { "1.52",  "1.08",  "CZ",  "HH",  "Z",  "Z", };
+     459          16 :   haselmap["TYR_HH"] = { "1.0",  "0.944",  "OH",  "Z",  "Z",  "Z", };
+     460          16 :   haselmap["TYR_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     461          16 :   haselmap["TYR_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     462          16 :   haselmap["VAL_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     463          16 :   haselmap["VAL_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     464          16 :   haselmap["VAL_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     465          16 :   haselmap["VAL_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     466          16 :   haselmap["VAL_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     467          16 :   haselmap["VAL_CB"] = { "1.8",  "1.276",  "CA",  "CG1",  "CG2",  "Z", };
+     468          16 :   haselmap["VAL_CG1"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     469          16 :   haselmap["VAL_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     470           2 :   return haselmap;
+     471             : }
+     472             : 
+     473             : //assigns SASA parameters to each atom reading from HASEL parameter database
+     474           2 : void SASA_HASEL::readSASAparam() {
+     475             : 
+     476         242 :   for(unsigned i=0; i<natoms; i++) {
+     477         240 :     SASAparam[i].clear();
+     478         240 :     CONNECTparam[i].clear();
+     479             :   }
+     480             : 
+     481             :   map<string, vector<std::string> > haselmap;
+     482           4 :   haselmap = setupHASELparam();
+     483             :   vector<std::string> HASELparamVector;
+     484             :   string identifier;
+     485             : 
+     486             : 
+     487         242 :   for(unsigned i=0; i<natoms; i++) {
+     488         480 :     identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     489         240 :     if (haselmap.find(identifier)!=haselmap.end()) {
+     490         144 :       HASELparamVector = haselmap.at(identifier);
+     491         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[0].c_str())+rs*10);
+     492         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[1].c_str()));
+     493         288 :       CONNECTparam[i].push_back (HASELparamVector[2].c_str());
+     494         288 :       CONNECTparam[i].push_back (HASELparamVector[3].c_str());
+     495         288 :       CONNECTparam[i].push_back (HASELparamVector[4].c_str());
+     496         288 :       CONNECTparam[i].push_back (HASELparamVector[5].c_str());
+     497             :     }
+     498             :   }
+     499             : 
+     500             : 
+     501         242 :   for(unsigned i=0; i<natoms; i++) {
+     502         240 :     if (SASAparam[i].size()==0 ) {
+     503          96 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     504           0 :         cout << "Could not find SASA paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     505           0 :         error ("missing SASA parameters\n");
+     506             :       }
+     507             :     }
+     508             :   }
+     509             : 
+     510             : 
+     511           4 : }
+     512             : 
+     513             : 
+     514             : 
+     515             : //Max Surf values, used only if TYPE=TRANSFER
+     516           1 : map<string, vector<double> > SASA_HASEL::setupMaxSurfMap() {
+     517             :   // Max Surface Area for backbone and sidechain, in nm2
+     518             :   map<string, vector<double> > valuemap;
+     519           1 :   valuemap ["ALA"]= {0.56425,0.584851,};
+     520           1 :   valuemap ["ARG"]= {0.498656,1.808093,};
+     521           1 :   valuemap ["ASN"]= {0.473409,0.818394,};
+     522           1 :   valuemap ["ASP"]= {0.477057,0.977303,};
+     523           1 :   valuemap ["CYS"]= {0.507512,0.791483,};
+     524           1 :   valuemap ["GLN"]= {0.485859,1.281534,};
+     525           1 :   valuemap ["GLU"]= {0.495054,1.464718,};
+     526           1 :   valuemap ["GLY"]= {0.658632,0,};
+     527           1 :   valuemap ["HIS"]= {0.48194,1.118851,};
+     528           1 :   valuemap ["ILE"]= {0.461283,1.450569,};
+     529           1 :   valuemap ["LEU"]= {0.476315,1.498843,};
+     530           1 :   valuemap ["LYS"]= {0.493533,1.619731,};
+     531           1 :   valuemap ["MET"]= {0.507019,1.631904,};
+     532           1 :   valuemap ["PHE"]= {0.457462, 1.275125,};
+     533           1 :   valuemap ["PRO"]= {0.315865,0.859456,};
+     534           1 :   valuemap ["SER"]= {0.48636,0.627233,};
+     535           1 :   valuemap ["THR"]= {0.45064,0.91088,};
+     536           1 :   valuemap ["TRP"]= {0.45762,1.366369,};
+     537           1 :   valuemap ["TYR"]= {0.461826,1.425822,};
+     538           1 :   valuemap ["VAL"]= {0.477054,1.149101,};
+     539           1 :   return valuemap;
+     540             : }
+     541             : 
+     542             : 
+     543             : 
+     544             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     545             : 
+     546           1 : void SASA_HASEL::readMaxSurf() {
+     547             :   map<string, vector<double> > valuemap;
+     548           2 :   valuemap = setupMaxSurfMap();
+     549             :   vector<double> MaxSurfVector;
+     550             : 
+     551         121 :   for(unsigned i=0; i<natoms; i++) {
+     552         120 :     MaxSurf[i].clear();
+     553         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     554         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     555         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     556             :   }
+     557           1 : }
+     558             : 
+     559             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     560             : 
+     561           1 : void SASA_HASEL::readDeltaG() {
+     562             : 
+     563         121 :   for(unsigned i=0; i<natoms; i++) {
+     564         120 :     DeltaG[i].clear();
+     565             :   }
+     566             : 
+     567             :   string DeltaGline;
+     568           1 :   fstream DeltaGFile;
+     569           1 :   DeltaGFile.open(DeltaGValues);
+     570           1 :   if (DeltaGFile) {
+     571             :     int backboneflag = 0;
+     572          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     573          22 :       if(!DeltaGline.empty()) {
+     574             :         std::vector<std::string> DeltaGtoken;
+     575          21 :         split(DeltaGline, DeltaGtoken);
+     576        2541 :         for(unsigned i=0; i<natoms; i++) {
+     577        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     578         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     579             :           }
+     580             :         }
+     581          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     582             :           backboneflag = 1;
+     583           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     584             :         }
+     585          21 :       }
+     586             :     }
+     587           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     588             :   }
+     589           0 :   else error("Cannot open DeltaG file");
+     590             : 
+     591         121 :   for(unsigned i=0; i<natoms; i++) {
+     592         120 :     if (DeltaG[i].size()==0 ) {
+     593           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     594           0 :       error ("missing Delta G parameter\n");
+     595             :     }
+     596             :   }
+     597             : 
+     598           2 : }
+     599             : 
+     600             : //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.
+     601             : 
+     602           0 : void SASA_HASEL::computeDeltaG() {
+     603             : 
+     604           0 :   for(unsigned i=0; i<natoms; i++) {
+     605           0 :     DeltaG[i].clear();
+     606             :   }
+     607             : 
+     608             :   double T;
+     609           0 :   T = plumed.getAtoms().getKbT()/plumed.getAtoms().getKBoltzmann();
+     610             : 
+     611           0 :   if (T != Ti) {
+     612           0 :     for(unsigned i=0; i<natoms; i++) {
+     613           0 :       if (approach==2) {
+     614           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     615           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     616             :         }
+     617           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     618           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     619             :         }
+     620           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     621           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     622             :         }
+     623           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     624           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     625             :         }
+     626           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     627           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     628             :         }
+     629           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     630           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     631             :         }
+     632           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     633           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     634             :         }
+     635           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     636           0 :           DeltaG[i].push_back (0);
+     637             :         }
+     638           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     639           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     640             :         }
+     641           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     642           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     643             :         }
+     644           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     645           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     646             :         }
+     647           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     648           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     649             :         }
+     650           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     651           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     652             :         }
+     653           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     654           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     655             :         }
+     656           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     657           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     658             :         }
+     659           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     660           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     661             :         }
+     662           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     663           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     664             :         }
+     665           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     666           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     667             :         }
+     668           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     669           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     670             :         }
+     671           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     672           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     673             :         }
+     674           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     675             :       }
+     676           0 :       if (approach==3) {
+     677           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     678           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     679             :         }
+     680           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     681           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     682             :         }
+     683           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     684           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     685             :         }
+     686           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     687           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     688             :         }
+     689           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     690           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     691             :         }
+     692           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     693           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     694             :         }
+     695           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     696           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     697             :         }
+     698           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     699           0 :           DeltaG[i].push_back (0);
+     700             :         }
+     701           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     702           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     703             :         }
+     704           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     705           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     706             :         }
+     707           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     708           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     709             :         }
+     710           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     711           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     712             :         }
+     713           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     714           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     715             :         }
+     716           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     717           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     718             :         }
+     719           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     720           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     721             :         }
+     722           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     723           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     724             :         }
+     725           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     726           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     727             :         }
+     728           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     729           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     730             :         }
+     731           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     732           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     733             :         }
+     734           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     735           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     736             :         }
+     737           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     738             :       }
+     739             :     }
+     740             :   }
+     741             : 
+     742           0 :   Ti = T;
+     743             : 
+     744           0 :   if (firstStepFlag ==0) {
+     745           0 :     if (approach!=2 && approach!=3) {
+     746           0 :       cout << "Unknown approach " << approach << endl;
+     747             :     }
+     748           0 :     for(unsigned i=0; i<natoms; i++) {
+     749           0 :       if (DeltaG[i].size()==0 ) {
+     750           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     751           0 :         error ("missing Delta G parameter\n");
+     752             :       }
+     753             :     }
+     754             :   }
+     755           0 : }
+     756             : 
+     757             : 
+     758             : //calculates neighbor list
+     759          24 : void SASA_HASEL::calcNlist() {
+     760          24 :   if(!nopbc) makeWhole();
+     761             : 
+     762        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     763        2880 :     Nlist[i].clear();
+     764             :   }
+     765             : 
+     766        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     767        2880 :     if (SASAparam[i].size()>0) {
+     768      103680 :       for (unsigned j = 0; j < i; j++) {
+     769      101952 :         if (SASAparam[j].size()>0) {
+     770       61344 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     771       61344 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     772       61344 :           double overlapD = SASAparam[i][0]+SASAparam[j][0];
+     773       61344 :           if (Delta_ij_mod < overlapD) {
+     774       26748 :             Nlist.at(i).push_back (j);
+     775       26748 :             Nlist.at(j).push_back (i);
+     776             :           }
+     777             :         }
+     778             :       }
+     779             :     }
+     780             :   }
+     781          24 : }
+     782             : 
+     783             : 
+     784             : //calculates SASA according to Hasel et al., Tetrahedron Computer Methodology Vol. 1, No. 2, pp. 103-116, 1988
+     785          24 : void SASA_HASEL::calculate() {
+     786          24 :   if(!nopbc) makeWhole();
+     787             : 
+     788          24 :   if(getExchangeStep()) nl_update = 0;
+     789          24 :   if (firstStepFlag ==0) {
+     790           2 :     readPDB();
+     791           2 :     readSASAparam();
+     792             :   }
+     793          24 :   if (nl_update == 0) {
+     794          24 :     calcNlist();
+     795             :   }
+     796             : 
+     797             : 
+     798          24 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     799          24 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     800             :   double Si, sasai, bij;
+     801          24 :   double sasa = 0;
+     802          24 :   vector<Vector> derivatives( natoms );
+     803        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     804        2880 :     derivatives[i][0] = 0.;
+     805        2880 :     derivatives[i][1] = 0.;
+     806        2880 :     derivatives[i][2] = 0.;
+     807             :   }
+     808             : 
+     809          24 :   Tensor virial;
+     810          24 :   vector <double> ddij_di(3);
+     811          24 :   vector <double> dbij_di(3);
+     812          24 :   vector <double> dAijt_di(3);
+     813             : 
+     814          24 :   if( sasa_type==TOTAL ) {
+     815        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     816        1440 :       if(SASAparam[i].size() > 0) {
+     817         864 :         double ri = SASAparam[i][0];
+     818         864 :         Si = 4*M_PI*ri*ri;
+     819             :         sasai = 1.0;
+     820             : 
+     821        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     822             : 
+     823         864 :         dAijt_di[0] = 0;
+     824         864 :         dAijt_di[1] = 0;
+     825         864 :         dAijt_di[2] = 0;
+     826         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     827             : 
+     828       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     829             :           double pij = 0.3516;
+     830             : 
+     831       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     832       26748 :           if (NumRes_i==NumRes_j) {
+     833        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) {
+     834             :               pij = 0.8875;
+     835             :             }
+     836             :           }
+     837       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     838       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     839             :               pij = 0.8875;
+     840             :             }
+     841             :           }
+     842             : 
+     843       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     844       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     845             : 
+     846       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     847       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     848             : 
+     849       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     850             : 
+     851       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     852       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     853       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     854             : 
+     855       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     856       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     857       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     858             : 
+     859       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     860       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     861       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     862             : 
+     863       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     864       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     865       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     866             : 
+     867             :         }
+     868             : 
+     869         864 :         sasa += Si*sasai/100; //nm2
+     870             : 
+     871         864 :         derivatives[i][0] += Si*sasai/10*dAijt_di[0]; //nm
+     872         864 :         derivatives[i][1] += Si*sasai/10*dAijt_di[1];
+     873         864 :         derivatives[i][2] += Si*sasai/10*dAijt_di[2];
+     874             : 
+     875       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     876       26748 :           derivatives[Nlist[i][j]][0] += Si*sasai/10*derTerm[j][0]; //nm
+     877       26748 :           derivatives[Nlist[i][j]][1] += Si*sasai/10*derTerm[j][1];
+     878       26748 :           derivatives[Nlist[i][j]][2] += Si*sasai/10*derTerm[j][2];
+     879             :         }
+     880         864 :       }
+     881             :     }
+     882             :   }
+     883             : 
+     884             : 
+     885          24 :   if( sasa_type==TRANSFER ) {
+     886             : 
+     887          12 :     if (firstStepFlag ==0) {
+     888           1 :       readMaxSurf();
+     889             :     }
+     890             : 
+     891          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     892           1 :       readDeltaG();
+     893             :     }
+     894             : 
+     895          12 :     if (DeltaGValues == "absent") {
+     896           0 :       computeDeltaG();
+     897             :     }
+     898             : 
+     899             : 
+     900        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     901             : 
+     902             : 
+     903             : 
+     904        1440 :       if(SASAparam[i].size() > 0) {
+     905         864 :         double ri = SASAparam[i][0];
+     906         864 :         Si = 4*M_PI*ri*ri;
+     907             :         sasai = 1.0;
+     908             : 
+     909        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     910             : 
+     911         864 :         dAijt_di[0] = 0;
+     912         864 :         dAijt_di[1] = 0;
+     913         864 :         dAijt_di[2] = 0;
+     914         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     915             : 
+     916       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     917             :           double pij = 0.3516;
+     918             : 
+     919       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     920       26748 :           if (NumRes_i==NumRes_j) {
+     921        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) {
+     922             :               pij = 0.8875;
+     923             :             }
+     924             :           }
+     925       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     926       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     927             :               pij = 0.8875;
+     928             :             }
+     929             :           }
+     930             : 
+     931       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     932       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     933             : 
+     934       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     935       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     936             : 
+     937       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     938             : 
+     939       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     940       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     941       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     942             : 
+     943       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     944       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     945       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     946             : 
+     947       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     948       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     949       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     950             : 
+     951       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     952       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     953       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     954             : 
+     955             :         }
+     956             : 
+     957        2880 :         if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     958             : 
+     959         720 :           sasa += Si*sasai/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol
+     960             : 
+     961             : 
+     962         720 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][0]*DeltaG[natoms][0]*10; //kJ/mol/nm
+     963         720 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     964         720 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     965             :         }
+     966             : 
+     967        2880 :         if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     968         144 :           sasa += Si*sasai/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol
+     969             : 
+     970         144 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][1]*DeltaG[i][0]*10; //kJ/mol/nm
+     971         144 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     972         144 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     973             :         }
+     974             : 
+     975             : 
+     976       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     977       86883 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     978       22438 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol/nm
+     979       22438 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][0]*DeltaG[natoms][0];
+     980       22438 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][0]*DeltaG[natoms][0];
+     981             :           }
+     982             : 
+     983       86883 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     984        4310 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol/nm
+     985        4310 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][1]*DeltaG[i][0];
+     986        4310 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][1]*DeltaG[i][0];
+     987             :           }
+     988             :         }
+     989         864 :       }
+     990             :     }
+     991             :   }
+     992             : 
+     993             : 
+     994        2904 :   for(unsigned i=0; i<natoms; i++) {
+     995        2880 :     setAtomsDerivatives(i,derivatives[i]);
+     996        2880 :     virial -= Tensor(getPosition(i),derivatives[i]);
+     997             :   }
+     998             : 
+     999          24 :   setBoxDerivatives(virial);
+    1000          24 :   setValue(sasa);
+    1001          24 :   firstStepFlag = 1;
+    1002          24 :   ++nl_update;
+    1003          24 :   if (nl_update == stride) {
+    1004          24 :     nl_update = 0;
+    1005             :   }
+    1006             : // setBoxDerivativesNoPbc();
+    1007          24 : }
+    1008             : 
+    1009             : }//namespace sasa
+    1010             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..f3337e0583 --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + 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:52263482.3 %
Date:2024-06-10 08:19:14Functions:131681.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe1616createERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPO13readLCPOparamEv2
_ZN4PLMD4sasa9SASA_LCPO14setupLCPOparamB5cxx11Ev2
_ZN4PLMD4sasa9SASA_LCPO7readPDBEv2
_ZN4PLMD4sasa9SASA_LCPOC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPO16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4sasa9SASA_LCPO9calcNlistEv24
_ZN4PLMD4sasa9SASA_LCPO9calculateEv24
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe161C2Ev3473
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe161D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.func.html b/coverage/sasa/sasa_LCPO.cpp.func.html new file mode 100644 index 0000000000..f321cd98b2 --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + 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:52263482.3 %
Date:2024-06-10 08:19:14Functions:131681.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe1616createERKNS_13ActionOptionsE2
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe161C2Ev3473
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe161D2Ev3473
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_0
_ZN4PLMD4sasa9SASA_LCPO10readDeltaGEv1
_ZN4PLMD4sasa9SASA_LCPO11readMaxSurfEv1
_ZN4PLMD4sasa9SASA_LCPO13computeDeltaGEv0
_ZN4PLMD4sasa9SASA_LCPO13readLCPOparamEv2
_ZN4PLMD4sasa9SASA_LCPO14setupLCPOparamB5cxx11Ev2
_ZN4PLMD4sasa9SASA_LCPO15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa9SASA_LCPO16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4sasa9SASA_LCPO7readPDBEv2
_ZN4PLMD4sasa9SASA_LCPO9calcNlistEv24
_ZN4PLMD4sasa9SASA_LCPO9calculateEv24
_ZN4PLMD4sasa9SASA_LCPOC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPOC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.gcov.html b/coverage/sasa/sasa_LCPO.cpp.gcov.html new file mode 100644 index 0000000000..50336a9b95 --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.gcov.html @@ -0,0 +1,1155 @@ + + + + + + + + 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:52263482.3 %
Date:2024-06-10 08:19:14Functions:131681.2 %
+
+ + + + + + + + +

+
          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 "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. 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).
+      44             : 
+      45             : Different properties can be calculated and selected using the TYPE keyword:
+      46             : 
+      47             : 1) the total SASA (TOTAL);
+      48             : 
+      49             : 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.
+      50             : 
+      51             : 
+      52             : 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:
+      53             : 
+      54             : \verbatim
+      55             : ----------------Sample DeltaG.dat file---------------------
+      56             : ALA     0.711019999999962
+      57             : ARG     -2.24832799999996
+      58             : ASN     -2.74838799999999
+      59             : ASP     -2.5626376
+      60             : CYS     3.89864000000006
+      61             : GLN     -1.76192
+      62             : GLU     -2.38664400000002
+      63             : GLY     0
+      64             : HIS     -3.58152799999999
+      65             : ILE     2.42634399999986
+      66             : LEU     1.77233599999988
+      67             : LYS     -1.92576400000002
+      68             : MET     -0.262827999999956
+      69             : PHE     1.62028800000007
+      70             : PRO     -2.15598800000001
+      71             : SER     -1.60934800000004
+      72             : THR     -0.591559999999987
+      73             : TRP     1.22936000000027
+      74             : TYR     0.775547999999958
+      75             : VAL     2.12779200000011
+      76             : BACKBONE        1.00066920000002
+      77             : -----------------------------------------------------------
+      78             : \endverbatim
+      79             : 
+      80             : where the second column is the free energy of transfer for each sidechain/backbone, in kJ/mol.
+      81             : 
+      82             : 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.
+      83             : 
+      84             : 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.
+      85             : 
+      86             : 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.
+      87             : 
+      88             : In case you want to recover the old behavior you should use the NOPBC flag.
+      89             : In that case you need to take care that atoms are in the correct periodic image.
+      90             : 
+      91             : 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.
+      92             : 
+      93             : 
+      94             : 
+      95             : \par Examples
+      96             : 
+      97             : The following input tells plumed to print the total SASA for atoms 10 to 20 in a protein chain.
+      98             : \plumedfile
+      99             : SASA_LCPO TYPE=TOTAL ATOMS=10-20 NL_STRIDE=10 LABEL=sasa
+     100             : PRINT ARG=sasa STRIDE=1 FILE=colvar
+     101             : \endplumedfile
+     102             : 
+     103             : 
+     104             : 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.
+     105             : 
+     106             : \plumedfile
+     107             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 DELTAGFILE=DeltaG.dat LABEL=sasa
+     108             : 
+     109             : bias: BIASVALUE ARG=sasa
+     110             : 
+     111             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     112             : \endplumedfile
+     113             : 
+     114             : 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.
+     115             : 
+     116             : \plumedfile
+     117             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 APPROACH=2 LABEL=sasa
+     118             : 
+     119             : bias: BIASVALUE ARG=sasa
+     120             : 
+     121             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     122             : \endplumedfile
+     123             : 
+     124             : */
+     125             : //+ENDPLUMEDOC
+     126             : 
+     127             : class SASA_LCPO : public Colvar {
+     128             : private:
+     129             :   enum CV_TYPE {TOTAL, TRANSFER};
+     130             :   int sasa_type;
+     131             :   bool nopbc;
+     132             :   double rs;
+     133             :   string DeltaGValues;
+     134             :   int approach;
+     135             :   unsigned stride;
+     136             :   unsigned nl_update;
+     137             :   int firstStepFlag;
+     138             :   double Ti;
+     139             :   // cppcheck-suppress duplInheritedMember
+     140             :   std::vector<AtomNumber> atoms;
+     141             :   vector < vector < std::string > > AtomResidueName;
+     142             :   vector < vector < double > > LCPOparam;
+     143             :   unsigned natoms;
+     144             :   vector < vector < double > > MaxSurf;
+     145             :   vector < vector < double > > DeltaG;
+     146             :   vector < vector < int > > Nlist;
+     147             : public:
+     148             :   static void registerKeywords(Keywords& keys);
+     149             :   explicit SASA_LCPO(const ActionOptions&);
+     150             :   void readPDB();
+     151             :   map<string, vector<double> > setupLCPOparam();
+     152             :   void readLCPOparam();
+     153             :   void calcNlist();
+     154             :   map<string, vector<double> > setupMaxSurfMap();
+     155             :   void readMaxSurf();
+     156             :   void readDeltaG();
+     157             :   void computeDeltaG();
+     158             :   virtual void calculate();
+     159             : };
+     160             : 
+     161       10423 : PLUMED_REGISTER_ACTION(SASA_LCPO,"SASA_LCPO")
+     162             : 
+     163           3 : void SASA_LCPO::registerKeywords(Keywords& keys) {
+     164           3 :   Colvar::registerKeywords(keys);
+     165           6 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the SASA for");
+     166           6 :   keys.add("compulsory","TYPE","TOTAL","The type of calculation you want to perform. Can be TOTAL or TRANSFER");
+     167           6 :   keys.add("compulsory", "NL_STRIDE", "The frequency with which the neighbor list is updated.");
+     168           6 :   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");
+     169           6 :   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");
+     170           3 : }
+     171             : 
+     172             : 
+     173           2 : SASA_LCPO::SASA_LCPO(const ActionOptions&ao):
+     174             :   PLUMED_COLVAR_INIT(ao),
+     175           2 :   nopbc(false),
+     176           4 :   DeltaGValues("absent"),
+     177           2 :   Ti(0),
+     178           2 :   stride(10),
+     179           2 :   nl_update(0),
+     180           2 :   firstStepFlag(0)
+     181             : {
+     182           2 :   rs = 0.14;
+     183           2 :   parse("DELTAGFILE",DeltaGValues);
+     184           2 :   parse("APPROACH", approach);
+     185           4 :   parseAtomList("ATOMS",atoms);
+     186           2 :   if(atoms.size()==0) error("no atoms specified");
+     187             :   std::string Type;
+     188           2 :   parse("TYPE",Type);
+     189           2 :   parse("NL_STRIDE", stride);
+     190           2 :   parseFlag("NOPBC",nopbc);
+     191           2 :   checkRead();
+     192             : 
+     193           2 :   if(Type=="TOTAL") sasa_type=TOTAL;
+     194           1 :   else if(Type=="TRANSFER") sasa_type=TRANSFER;
+     195           0 :   else error("Unknown SASA type");
+     196             : 
+     197           2 :   switch(sasa_type)
+     198             :   {
+     199           1 :   case TOTAL:   log.printf("  TOTAL SASA;"); break;
+     200           1 :   case TRANSFER: log.printf("  TRANSFER MODEL;"); break;
+     201             :   }
+     202             : 
+     203           2 :   log.printf("  atoms involved : ");
+     204         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     205         240 :     if(i%25==0) log<<"\n";
+     206         240 :     log.printf("%d ",atoms[i].serial());
+     207             :   }
+     208           2 :   log.printf("\n");
+     209             : 
+     210           2 :   if(nopbc) {
+     211           0 :     log<<"  PBC will be ignored\n";
+     212             :   } else {
+     213           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     214             :   }
+     215             : 
+     216             : 
+     217           2 :   addValueWithDerivatives(); setNotPeriodic();
+     218           2 :   requestAtoms(atoms);
+     219             : 
+     220           2 :   natoms = getNumberOfAtoms();
+     221           2 :   AtomResidueName.resize(2);
+     222           2 :   LCPOparam.resize(natoms);
+     223           2 :   MaxSurf.resize(natoms);
+     224           2 :   DeltaG.resize(natoms+1);
+     225           2 :   Nlist.resize(natoms);
+     226             : 
+     227             : 
+     228           2 : }
+     229             : 
+     230             : 
+     231             : //splits strings into tokens. Used to read into LCPO parameters file and into reference pdb file
+     232             : template <class Container>
+     233           0 : void split(const std::string& str, Container& cont)
+     234             : {
+     235           0 :   std::istringstream iss(str);
+     236           0 :   std::copy(std::istream_iterator<std::string>(iss),
+     237           0 :             std::istream_iterator<std::string>(),
+     238             :             std::back_inserter(cont));
+     239           0 : }
+     240             : 
+     241             : 
+     242             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     243             : 
+     244           2 : void SASA_LCPO::readPDB() {
+     245           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     246           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     247           2 :   AtomResidueName[0].clear();
+     248           2 :   AtomResidueName[1].clear();
+     249             : 
+     250         242 :   for(unsigned i=0; i<natoms; i++) {
+     251         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     252         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     253         240 :     AtomResidueName[0].push_back (Aname);
+     254         240 :     AtomResidueName[1].push_back (Rname);
+     255             :   }
+     256             : 
+     257           2 : }
+     258             : 
+     259             : //LCPO parameters database
+     260           2 : map<string, vector<double> > SASA_LCPO::setupLCPOparam() {
+     261             :   map<string, vector<double> > lcpomap;
+     262           2 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     263           2 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     264           2 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     265           2 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     266           2 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     267           2 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     268           2 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     269           2 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     270           2 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     271           2 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     272           2 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     273           2 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     274           2 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     275           2 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     276           2 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     277           2 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     278           2 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     279           2 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     280           2 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     281           2 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     282           2 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     283           2 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     284           2 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     285           2 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     286           2 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     287           2 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     288           2 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     289           2 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     290           2 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     291           2 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     292           2 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     293           2 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     294           2 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     295           2 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     296           2 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     297           2 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     298           2 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     299           2 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     300           2 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     301           2 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     302           2 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     303           2 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     304           2 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     305           2 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     306           2 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     307           2 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     308           2 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     309           2 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     310           2 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     311           2 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     312           2 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     313           2 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     314           2 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     315           2 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     316           2 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     317           2 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     318           2 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     319           2 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     320           2 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     321           2 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     322           2 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     323           2 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     324           2 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     325           2 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     326           2 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     327           2 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     328           2 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     329           2 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     330           2 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     331           2 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     332           2 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     333           2 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     334           2 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     335           2 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     336           2 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     337           2 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     338           2 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     339           2 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     340           2 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     341           2 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     342           2 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     343           2 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     344           2 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     345           2 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     346           2 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     347           2 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     348           2 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     349           2 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     350           2 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     351           2 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     352           2 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     353           2 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     354           2 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     355           2 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     356           2 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     357           2 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     358           2 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     359           2 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     360           2 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     361           2 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     362           2 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     363           2 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     364           2 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     365           2 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     366           2 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     367           2 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     368           2 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     369           2 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     370           2 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     371           2 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     372           2 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     373           2 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     374           2 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     375           2 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     376           2 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     377           2 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     378           2 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     379           2 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     380           2 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     381           2 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     382           2 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     383           2 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     384           2 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     385           2 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     386           2 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     387           2 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     388           2 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     389           2 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     390           2 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     391           2 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     392           2 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     393           2 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     394           2 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     395           2 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     396           2 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     397           2 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     398           2 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     399           2 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     400           2 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     401           2 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     402           2 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     403           2 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     404           2 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     405           2 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     406           2 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     407           2 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     408           2 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     409           2 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     410           2 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     411           2 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     412           2 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     413           2 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     414           2 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     415           2 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     416           2 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     417           2 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     418           2 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     419           2 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     420           2 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     421           2 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     422           2 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     423           2 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     424           2 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     425           2 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     426           2 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     427           2 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     428           2 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     429           2 :   return lcpomap;
+     430             : }
+     431             : 
+     432             : //assigns LCPO parameters to each atom reading from database
+     433           2 : void SASA_LCPO::readLCPOparam() {
+     434             : 
+     435         242 :   for(unsigned i=0; i<natoms; i++) {
+     436         240 :     LCPOparam[i].clear();
+     437             :   }
+     438             : 
+     439             :   map<string, vector<double> > lcpomap;
+     440           4 :   lcpomap = setupLCPOparam();
+     441             :   vector<double> LCPOparamVector;
+     442             :   string identifier;
+     443         242 :   for(unsigned i=0; i<natoms; i++) {
+     444         240 :     if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     445         240 :       identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     446         120 :       LCPOparamVector = lcpomap.at(identifier);
+     447         120 :       LCPOparam[i].push_back (LCPOparamVector[0]+rs*10);
+     448         120 :       LCPOparam[i].push_back (LCPOparamVector[1]);
+     449         120 :       LCPOparam[i].push_back (LCPOparamVector[2]);
+     450         120 :       LCPOparam[i].push_back (LCPOparamVector[3]);
+     451         120 :       LCPOparam[i].push_back (LCPOparamVector[4]);
+     452             :     }
+     453             :   }
+     454             : 
+     455             : 
+     456         242 :   for(unsigned i=0; i<natoms; i++) {
+     457         240 :     if (LCPOparam[i].size()==0 ) {
+     458         120 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     459           0 :         cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     460           0 :         error ("missing LCPO parameters\n");
+     461             :       }
+     462             :     }
+     463             :   }
+     464             : 
+     465           2 :   if (AtomResidueName[0][0] == "N") {
+     466           2 :     LCPOparam[0][1] = 7.3511e-01;
+     467           2 :     LCPOparam[0][2] = -2.2116e-01;
+     468           2 :     LCPOparam[0][3] = -8.9148e-04;
+     469           2 :     LCPOparam[0][4] = 2.5230e-04;
+     470             :   }
+     471             : 
+     472           2 :   if (AtomResidueName[0][natoms-1] == "O") {
+     473           2 :     LCPOparam[natoms-1][1] = 8.8857e-01;
+     474           2 :     LCPOparam[natoms-1][2] = -3.3421e-01;
+     475           2 :     LCPOparam[natoms-1][3] = -1.8683e-03;
+     476           2 :     LCPOparam[natoms-1][4] = 4.9372e-04;
+     477             :   }
+     478           2 : }
+     479             : 
+     480             : 
+     481             : //Max Surf values, used only if TYPE=TRANSFER
+     482           1 : map<string, vector<double> > SASA_LCPO::setupMaxSurfMap() {
+     483             :   // Max Surface Area for backbone and sidechain, in nm2
+     484             :   map<string, vector<double> > valuemap;
+     485           1 :   valuemap ["ALA"]= {0.671446,0.420263,};
+     486           1 :   valuemap ["ARG"]= {0.578582,1.95454,};
+     487           1 :   valuemap ["ASN"]= {0.559411,1.07102,};
+     488           1 :   valuemap ["ASP"]= {0.558363,1.03971,};
+     489           1 :   valuemap ["CYS"]= {0.609271,0.657612,};
+     490           1 :   valuemap ["GLN"]= {0.565651,1.433031,};
+     491           1 :   valuemap ["GLU"]= {0.572399,1.41848,};
+     492           1 :   valuemap ["GLY"]= {0.861439,0,};
+     493           1 :   valuemap ["HIS"]= {0.559929,1.143827,};
+     494           1 :   valuemap ["ILE"]= {0.553491,1.25334,};
+     495           1 :   valuemap ["LEU"]= {0.570103,1.260459,};
+     496           1 :   valuemap ["LYS"]= {0.580304,1.687487,};
+     497           1 :   valuemap ["MET"]= {0.5856,1.498954,};
+     498           1 :   valuemap ["PHE"]= {0.54155,1.394861,};
+     499           1 :   valuemap ["PRO"]= {0.456048,0.849461,};
+     500           1 :   valuemap ["SER"]= {0.59074,0.714538,};
+     501           1 :   valuemap ["THR"]= {0.559116,0.951644,};
+     502           1 :   valuemap ["TRP"]= {0.55536,1.59324,};
+     503           1 :   valuemap ["TYR"]= {0.451171,1.566918,};
+     504           1 :   valuemap ["VAL"]= {0.454809,0.928685,};
+     505           1 :   return valuemap;
+     506             : }
+     507             : 
+     508             : 
+     509             : 
+     510             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     511             : 
+     512           1 : void SASA_LCPO::readMaxSurf() {
+     513             :   map<string, vector<double> > valuemap;
+     514           2 :   valuemap = setupMaxSurfMap();
+     515             :   vector<double> MaxSurfVector;
+     516             : 
+     517         121 :   for(unsigned i=0; i<natoms; i++) {
+     518         120 :     MaxSurf[i].clear();
+     519         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     520         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     521         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     522             :   }
+     523           1 : }
+     524             : 
+     525             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     526             : 
+     527           1 : void SASA_LCPO::readDeltaG() {
+     528             : 
+     529         121 :   for(unsigned i=0; i<natoms; i++) {
+     530         120 :     DeltaG[i].clear();
+     531             :   }
+     532             : 
+     533             :   string DeltaGline;
+     534           1 :   fstream DeltaGFile;
+     535           1 :   DeltaGFile.open(DeltaGValues);
+     536           1 :   if (DeltaGFile) {
+     537             :     int backboneflag = 0;
+     538          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     539          22 :       if(!DeltaGline.empty()) {
+     540             :         std::vector<std::string> DeltaGtoken;
+     541          21 :         split(DeltaGline, DeltaGtoken);
+     542        2541 :         for(unsigned i=0; i<natoms; i++) {
+     543        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     544         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     545             :           }
+     546             :         }
+     547          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     548             :           backboneflag = 1;
+     549           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     550             :         }
+     551          21 :       }
+     552             :     }
+     553           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     554             :   }
+     555           0 :   else error("Cannot open DeltaG file");
+     556             : 
+     557         121 :   for(unsigned i=0; i<natoms; i++) {
+     558         120 :     if (DeltaG[i].size()==0 ) {
+     559           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     560           0 :       error ("missing Delta G parameter\n");
+     561             :     }
+     562             :   }
+     563             : 
+     564           2 : }
+     565             : 
+     566             : //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.
+     567             : 
+     568           0 : void SASA_LCPO::computeDeltaG() {
+     569             : 
+     570           0 :   for(unsigned i=0; i<natoms; i++) {
+     571           0 :     DeltaG[i].clear();
+     572             :   }
+     573             : 
+     574             :   double T;
+     575           0 :   T = plumed.getAtoms().getKbT()/plumed.getAtoms().getKBoltzmann();
+     576             : 
+     577           0 :   if (T != Ti) {
+     578           0 :     for(unsigned i=0; i<natoms; i++) {
+     579           0 :       if (approach==2) {
+     580           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     581           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     582             :         }
+     583           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     584           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     585             :         }
+     586           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     587           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     588             :         }
+     589           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     590           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     591             :         }
+     592           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     593           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     594             :         }
+     595           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     596           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     597             :         }
+     598           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     599           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     600             :         }
+     601           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     602           0 :           DeltaG[i].push_back (0);
+     603             :         }
+     604           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     605           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     606             :         }
+     607           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     608           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     609             :         }
+     610           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     611           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     612             :         }
+     613           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     614           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     615             :         }
+     616           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     617           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     618             :         }
+     619           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     620           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     621             :         }
+     622           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     623           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     624             :         }
+     625           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     626           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     627             :         }
+     628           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     629           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     630             :         }
+     631           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     632           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     633             :         }
+     634           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     635           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     636             :         }
+     637           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     638           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     639             :         }
+     640           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     641             :       }
+     642           0 :       if (approach==3) {
+     643           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     644           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     645             :         }
+     646           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     647           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     648             :         }
+     649           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     650           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     651             :         }
+     652           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     653           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     654             :         }
+     655           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     656           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     657             :         }
+     658           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     659           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     660             :         }
+     661           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     662           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     663             :         }
+     664           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     665           0 :           DeltaG[i].push_back (0);
+     666             :         }
+     667           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     668           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     669             :         }
+     670           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     671           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     672             :         }
+     673           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     674           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     675             :         }
+     676           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     677           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     678             :         }
+     679           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     680           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     681             :         }
+     682           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     683           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     684             :         }
+     685           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     686           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     687             :         }
+     688           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     689           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     690             :         }
+     691           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     692           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     693             :         }
+     694           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     695           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     696             :         }
+     697           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     698           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     699             :         }
+     700           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     701           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     702             :         }
+     703           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     704             :       }
+     705             :     }
+     706             :   }
+     707             : 
+     708           0 :   Ti = T;
+     709             : 
+     710           0 :   if (firstStepFlag ==0) {
+     711           0 :     if (approach!=2 && approach!=3) {
+     712           0 :       cout << "Unknown approach " << approach << endl;
+     713             :     }
+     714           0 :     for(unsigned i=0; i<natoms; i++) {
+     715           0 :       if (DeltaG[i].size()==0 ) {
+     716           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     717           0 :         error ("missing Delta G parameter\n");
+     718             :       }
+     719             :     }
+     720             :   }
+     721           0 : }
+     722             : 
+     723             : 
+     724             : //calculates neighbor list
+     725          24 : void SASA_LCPO::calcNlist() {
+     726          24 :   if(!nopbc) makeWhole();
+     727             : 
+     728        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     729        2880 :     Nlist[i].clear();
+     730             :   }
+     731             : 
+     732        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     733        2880 :     if (LCPOparam[i].size()>0) {
+     734       87264 :       for (unsigned j = 0; j < i; j++) {
+     735       85824 :         if (LCPOparam[j].size()>0) {
+     736       42480 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     737       42480 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     738       42480 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
+     739       42480 :           if (Delta_ij_mod < overlapD) {
+     740       19030 :             Nlist.at(i).push_back (j);
+     741       19030 :             Nlist.at(j).push_back (i);
+     742             :           }
+     743             :         }
+     744             :       }
+     745             :     }
+     746             :   }
+     747          24 : }
+     748             : 
+     749             : 
+     750             : //calculates SASA according to LCPO algorithm
+     751          24 : void SASA_LCPO::calculate() {
+     752          24 :   if(!nopbc) makeWhole();
+     753             : 
+     754          24 :   if(getExchangeStep()) nl_update = 0;
+     755          24 :   if (firstStepFlag ==0) {
+     756           2 :     readPDB();
+     757           2 :     readLCPOparam();
+     758             :   }
+     759          24 :   if (nl_update == 0) {
+     760          24 :     calcNlist();
+     761             :   }
+     762             : 
+     763             : 
+     764             : 
+     765             :   double S1, Aij, Ajk, Aijk, Aijt, Ajkt, Aikt;
+     766             :   double dAdd;
+     767          24 :   double sasa = 0;
+     768          24 :   vector<Vector> derivatives( natoms );
+     769          24 :   Tensor virial;
+     770          24 :   vector <double> dAijdc_2t(3);
+     771          24 :   vector <double> dSASA_2_neigh_dc(3);
+     772          24 :   vector <double> ddij_di(3);
+     773          24 :   vector <double> ddik_di(3);
+     774             : 
+     775          24 :   if( sasa_type==TOTAL ) {
+     776        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     777        1440 :       derivatives[i][0] = 0.;
+     778        1440 :       derivatives[i][1] = 0.;
+     779        1440 :       derivatives[i][2] = 0.;
+     780        1440 :       if ( LCPOparam[i].size()>1) {
+     781         720 :         if (LCPOparam[i][1]>0.0) {
+     782             :           Aij = 0.0;
+     783             :           Aijk = 0.0;
+     784             :           Ajk = 0.0;
+     785         720 :           double ri = LCPOparam[i][0];
+     786         720 :           S1 = 4*M_PI*ri*ri;
+     787         720 :           vector <double> dAijdc_2(3, 0);
+     788         720 :           vector <double> dAijdc_4(3, 0);
+     789             : 
+     790             : 
+     791       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     792       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     793       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     794             : 
+     795       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     796       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     797       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     798             : 
+     799       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     800             : 
+     801       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     802       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     803       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     804             : 
+     805             :             Ajkt = 0.0;
+     806             :             Aikt = 0.0;
+     807             : 
+     808       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     809       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     810       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     811       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     812             : 
+     813       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     814       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     815       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     816             : 
+     817       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     818             : 
+     819             : 
+     820       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     821       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     822       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     823             : 
+     824      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     825      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     826      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     827      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     828             : 
+     829      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     830      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     831             : 
+     832      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     833      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     834      370872 :                 Ajkt += sjk;
+     835      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     836             : 
+     837      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     838             : 
+     839      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     840      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     841      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     842             : 
+     843             : 
+     844      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     845      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     846      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     847             : 
+     848      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     849             : 
+     850      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+     851      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+     852      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+     853             : 
+     854      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+     855      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+     856      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+     857             : 
+     858             :               }
+     859             :             }
+     860       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+     861       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+     862       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+     863             : 
+     864       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+     865       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+     866       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+     867             : 
+     868       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+     869       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+     870       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+     871             : 
+     872             : 
+     873       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;
+     874       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;
+     875       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;
+     876             : 
+     877             : 
+     878       19030 :             Aijk += (Aijt * Ajkt);
+     879       19030 :             Aij += Aijt;
+     880       19030 :             Ajk += Ajkt;
+     881             : 
+     882       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+     883       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+     884       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+     885             : 
+     886             : 
+     887       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+     888       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+     889       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+     890             : 
+     891             : 
+     892             :           }
+     893         720 :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+     894         720 :           if (sasai > 0 ) sasa += sasai/100;
+     895         720 :           derivatives[i][0] += (dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/10;
+     896         720 :           derivatives[i][1] += (dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/10;
+     897         720 :           derivatives[i][2] += (dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/10;
+     898             :         }
+     899             :       }
+     900        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+     901             :     }
+     902             :   }
+     903             : 
+     904             : 
+     905             : 
+     906          24 :   if( sasa_type==TRANSFER ) {
+     907             : 
+     908          12 :     if (firstStepFlag ==0) {
+     909           1 :       readMaxSurf();
+     910             :     }
+     911             : 
+     912          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     913           1 :       readDeltaG();
+     914             :     }
+     915             : 
+     916          12 :     if (DeltaGValues == "absent") {
+     917           0 :       computeDeltaG();
+     918             :     }
+     919             : 
+     920             : 
+     921        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     922             : 
+     923             : 
+     924             : 
+     925        1440 :       derivatives[i][0] = 0.;
+     926        1440 :       derivatives[i][1] = 0.;
+     927        1440 :       derivatives[i][2] = 0.;
+     928             : 
+     929        1440 :       if ( LCPOparam[i].size()>1) {
+     930         720 :         if (LCPOparam[i][1]>0.0) {
+     931             :           Aij = 0.0;
+     932             :           Aijk = 0.0;
+     933             :           Ajk = 0.0;
+     934         720 :           double ri = LCPOparam[i][0];
+     935         720 :           S1 = 4*M_PI*ri*ri;
+     936         720 :           vector <double> dAijdc_2(3, 0);
+     937         720 :           vector <double> dAijdc_4(3, 0);
+     938             : 
+     939             : 
+     940       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     941       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     942       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     943             : 
+     944       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     945       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     946       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     947             : 
+     948       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     949       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     950       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     951       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     952             : 
+     953             :             Ajkt = 0.0;
+     954             :             Aikt = 0.0;
+     955             : 
+     956       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     957       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     958       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     959       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     960             : 
+     961       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     962       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     963       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     964             : 
+     965       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     966             : 
+     967       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     968       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     969       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     970             : 
+     971      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     972      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     973      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     974      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     975             : 
+     976      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     977      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     978             : 
+     979      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     980      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     981      370872 :                 Ajkt += sjk;
+     982      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     983             : 
+     984      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     985             : 
+     986      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     987      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     988      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     989             : 
+     990             : 
+     991      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     992      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     993      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     994             : 
+     995      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     996             : 
+     997      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+     998      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+     999      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+    1000             : 
+    1001      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+    1002      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+    1003      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+    1004             : 
+    1005             :               }
+    1006             :             }
+    1007       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+    1008       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+    1009       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+    1010             : 
+    1011       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+    1012       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+    1013       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+    1014             : 
+    1015       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+    1016       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+    1017       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+    1018             : 
+    1019       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") {
+    1020       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;
+    1021       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;
+    1022       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;
+    1023             :             }
+    1024             : 
+    1025       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") {
+    1026        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;
+    1027        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;
+    1028        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;
+    1029             :             }
+    1030             : 
+    1031       19030 :             Aijk += (Aijt * Ajkt);
+    1032       19030 :             Aij += Aijt;
+    1033       19030 :             Ajk += Ajkt;
+    1034             : 
+    1035       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+    1036       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+    1037       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+    1038             : 
+    1039       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+    1040       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+    1041       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+    1042             : 
+    1043             :           }
+    1044         720 :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+    1045             : 
+    1046        2016 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O") {
+    1047         576 :             if (sasai > 0 ) sasa += (sasai/MaxSurf[i][0]*DeltaG[natoms][0]);
+    1048         576 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1049         576 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1050         576 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1051             :           }
+    1052             : 
+    1053        2016 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O") {
+    1054         144 :             if (sasai > 0. ) sasa += (sasai/MaxSurf[i][1]*DeltaG[i][0]);
+    1055         144 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1056         144 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1057         144 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1058             :           }
+    1059             :         }
+    1060             :       }
+    1061        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+    1062             :     }
+    1063             :   }
+    1064             : 
+    1065             : 
+    1066        2904 :   for(unsigned i=0; i<natoms; i++) { setAtomsDerivatives(i,derivatives[i]);}
+    1067          24 :   setBoxDerivatives(virial);
+    1068          24 :   setValue(sasa);
+    1069          24 :   firstStepFlag = 1;
+    1070          24 :   ++nl_update;
+    1071          24 :   if (nl_update == stride) {
+    1072          24 :     nl_update = 0;
+    1073             :   }
+    1074             : // setBoxDerivativesNoPbc();
+    1075          24 : }
+    1076             : 
+    1077             : }//namespace sasa
+    1078             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e0699548d2 --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:5050100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure9AlphaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe946createERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe94C2Ev3473
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe94D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.func.html b/coverage/secondarystructure/AlphaRMSD.cpp.func.html new file mode 100644 index 0000000000..99bbde62b9 --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:5050100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe946createERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe94C2Ev3473
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe94D2Ev3473
_ZN4PLMD18secondarystructure9AlphaRMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD18secondarystructure9AlphaRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html b/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html new file mode 100644 index 0000000000..dc50232a30 --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html @@ -0,0 +1,235 @@ + + + + + + + + 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:5050100.0 %
Date:2024-06-10 08:19:14Functions:5683.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 "SecondaryStructureRMSD.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace secondarystructure {
+      28             : 
+      29             : //+PLUMEDOC COLVAR ALPHARMSD
+      30             : /*
+      31             : Probe the alpha helical content of a protein structure.
+      32             : 
+      33             : Any chain of six contiguous residues in a protein chain can form an alpha helix. This
+      34             : colvar thus generates the set of all possible six residue sections and calculates
+      35             : the RMSD distance between the configuration in which the residues find themselves
+      36             : and an idealized alpha helical structure. These distances can be calculated by either
+      37             : aligning the instantaneous structure with the reference structure and measuring each
+      38             : atomic displacement or by calculating differences between the set of inter-atomic
+      39             : distances in the reference and instantaneous structures.
+      40             : 
+      41             : This colvar is based on the following reference \cite pietrucci09jctc.  The authors of
+      42             : this paper use the set of distances from the alpha helix configurations to measure
+      43             : the number of segments that have an alpha helical configuration. This is done by calculating
+      44             : the following sum of functions of the rmsd distances:
+      45             : 
+      46             : \f[
+      47             : 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 }
+      48             : \f]
+      49             : 
+      50             : where the sum runs over all possible segments of alpha helix.  By default the
+      51             : NN, MM and D_0 parameters are set equal to those used in \cite pietrucci09jctc.  The R_0
+      52             : parameter must be set by the user - the value used in \cite pietrucci09jctc was 0.08 nm.
+      53             : 
+      54             : If you change the function in the above sum you can calculate quantities such as the average
+      55             : distance from a purely the alpha helical configuration or the distance between the set of
+      56             : residues that is closest to an alpha helix and the reference configuration. To do these sorts of
+      57             : calculations you can use the AVERAGE and MIN keywords. In addition you can use the LESS_THAN
+      58             : keyword if you would like to change the form of the switching function. If you use any of these
+      59             : options you no longer need to specify NN, R_0, MM and D_0.
+      60             : 
+      61             : Please be aware that for codes like gromacs you must ensure that plumed
+      62             : reconstructs the chains involved in your CV when you calculate this CV using
+      63             : anything other than TYPE=DRMSD.  For more details as to how to do this see \ref WHOLEMOLECULES.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : The following input calculates the number of six residue segments of
+      68             : protein that are in an alpha helical configuration.
+      69             : 
+      70             : \plumedfile
+      71             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      72             : MOLINFO STRUCTURE=helix.pdb
+      73             : alpha: ALPHARMSD RESIDUES=all
+      74             : \endplumedfile
+      75             : 
+      76             : Here the same is done use RMSD instead of DRMSD
+      77             : 
+      78             : \plumedfile
+      79             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      80             : MOLINFO STRUCTURE=helix.pdb
+      81             : WHOLEMOLECULES ENTITY0=1-100
+      82             : alpha: ALPHARMSD RESIDUES=all TYPE=OPTIMAL R_0=0.1
+      83             : \endplumedfile
+      84             : 
+      85             : */
+      86             : //+ENDPLUMEDOC
+      87             : 
+      88             : class AlphaRMSD : public SecondaryStructureRMSD {
+      89             : public:
+      90             :   static void registerKeywords( Keywords& keys );
+      91             :   explicit AlphaRMSD(const ActionOptions&);
+      92             : };
+      93             : 
+      94       10425 : PLUMED_REGISTER_ACTION(AlphaRMSD,"ALPHARMSD")
+      95             : 
+      96           4 : void AlphaRMSD::registerKeywords( Keywords& keys ) {
+      97           4 :   SecondaryStructureRMSD::registerKeywords( keys );
+      98           4 : }
+      99             : 
+     100           3 : AlphaRMSD::AlphaRMSD(const ActionOptions&ao):
+     101             :   Action(ao),
+     102           3 :   SecondaryStructureRMSD(ao)
+     103             : {
+     104             :   // read in the backbone atoms
+     105           3 :   std::vector<unsigned> chains; readBackboneAtoms( "protein", chains);
+     106             : 
+     107             :   // This constructs all conceivable sections of alpha helix in the backbone of the chains
+     108           3 :   unsigned nprevious=0; std::vector<unsigned> nlist(30);
+     109           6 :   for(unsigned i=0; i<chains.size(); ++i) {
+     110           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");
+     111           3 :     unsigned nres=chains[i]/5;
+     112           3 :     if( chains[i]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     113          12 :     for(unsigned ires=0; ires<nres-5; ires++) {
+     114           9 :       unsigned accum=nprevious + 5*ires;
+     115         279 :       for(unsigned k=0; k<30; ++k) nlist[k] = accum+k;
+     116           9 :       addColvar( nlist );
+     117             :     }
+     118           3 :     nprevious+=chains[i];
+     119             :   }
+     120             : 
+     121             :   // Build the reference structure ( in angstroms )
+     122           3 :   std::vector<Vector> reference(30);
+     123           3 :   reference[0] = Vector( 0.733,  0.519,  5.298 ); // N    i
+     124           3 :   reference[1] = Vector( 1.763,  0.810,  4.301 ); // CA
+     125           3 :   reference[2] = Vector( 3.166,  0.543,  4.881 ); // CB
+     126           3 :   reference[3] = Vector( 1.527, -0.045,  3.053 ); // C
+     127           3 :   reference[4] = Vector( 1.646,  0.436,  1.928 ); // O
+     128           3 :   reference[5] = Vector( 1.180, -1.312,  3.254 ); // N    i+1
+     129           3 :   reference[6] = Vector( 0.924, -2.203,  2.126 ); // CA
+     130           3 :   reference[7] = Vector( 0.650, -3.626,  2.626 ); // CB
+     131           3 :   reference[8] = Vector(-0.239, -1.711,  1.261 ); // C
+     132           3 :   reference[9] = Vector(-0.190, -1.815,  0.032 ); // O
+     133           3 :   reference[10] = Vector(-1.280, -1.172,  1.891 ); // N    i+2
+     134           3 :   reference[11] = Vector(-2.416, -0.661,  1.127 ); // CA
+     135           3 :   reference[12] = Vector(-3.548, -0.217,  2.056 ); // CB
+     136           3 :   reference[13] = Vector(-1.964,  0.529,  0.276 ); // C
+     137           3 :   reference[14] = Vector(-2.364,  0.659, -0.880 ); // O
+     138           3 :   reference[15] = Vector(-1.130,  1.391,  0.856 ); // N    i+3
+     139           3 :   reference[16] = Vector(-0.620,  2.565,  0.148 ); // CA
+     140           3 :   reference[17] = Vector( 0.228,  3.439,  1.077 ); // CB
+     141           3 :   reference[18] = Vector( 0.231,  2.129, -1.032 ); // C
+     142           3 :   reference[19] = Vector( 0.179,  2.733, -2.099 ); // O
+     143           3 :   reference[20] = Vector( 1.028,  1.084, -0.833 ); // N    i+4
+     144           3 :   reference[21] = Vector( 1.872,  0.593, -1.919 ); // CA
+     145           3 :   reference[22] = Vector( 2.850, -0.462, -1.397 ); // CB
+     146           3 :   reference[23] = Vector( 1.020,  0.020, -3.049 ); // C
+     147           3 :   reference[24] = Vector( 1.317,  0.227, -4.224 ); // O
+     148           3 :   reference[25] = Vector(-0.051, -0.684, -2.696 ); // N    i+5
+     149           3 :   reference[26] = Vector(-0.927, -1.261, -3.713 ); // CA
+     150           3 :   reference[27] = Vector(-1.933, -2.219, -3.074 ); // CB
+     151           3 :   reference[28] = Vector(-1.663, -0.171, -4.475 ); // C
+     152           3 :   reference[29] = Vector(-1.916, -0.296, -5.673 ); // O
+     153             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     154           3 :   setSecondaryStructure( reference, 0.17/atoms.getUnits().getLength(), 0.1/atoms.getUnits().getLength() );
+     155           3 : }
+     156             : 
+     157             : }
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..929a056bcd --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:767897.4 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe956createERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe95C2Ev3473
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe95D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.func.html b/coverage/secondarystructure/AntibetaRMSD.cpp.func.html new file mode 100644 index 0000000000..b62339b199 --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:767897.4 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12AntibetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe956createERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe95C2Ev3473
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe95D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html b/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html new file mode 100644 index 0000000000..11eca89450 --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html @@ -0,0 +1,287 @@ + + + + + + + + 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:767897.4 %
Date:2024-06-10 08:19:14Functions:5683.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 "SecondaryStructureRMSD.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace secondarystructure {
+      28             : 
+      29             : //+PLUMEDOC COLVAR ANTIBETARMSD
+      30             : /*
+      31             : Probe the antiparallel beta sheet content of your protein structure.
+      32             : 
+      33             : Two protein segments containing three contiguous residues can form an antiparallel beta sheet.
+      34             : Although if the two segments are part of the same protein chain they must be separated by
+      35             : a minimum of 2 residues to make room for the turn. This colvar thus generates the set of
+      36             : all possible six residue sections that could conceivably form an antiparallel beta sheet
+      37             : and calculates the RMSD distance between the configuration in which the residues find themselves
+      38             : and an idealized antiparallel beta sheet structure. These distances can be calculated by either
+      39             : aligning the instantaneous structure with the reference structure and measuring each
+      40             : atomic displacement or by calculating differences between the set of inter-atomic
+      41             : distances in the reference and instantaneous structures.
+      42             : 
+      43             : This colvar is based on the following reference \cite pietrucci09jctc.  The authors of
+      44             : this paper use the set of distances from the anti parallel beta sheet configurations to measure
+      45             : the number of segments that have an configuration that resembles an anti parallel beta sheet. This is done by calculating
+      46             : the following sum of functions of the rmsd distances:
+      47             : 
+      48             : \f[
+      49             : 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 }
+      50             : \f]
+      51             : 
+      52             : where the sum runs over all possible segments of antiparallel beta sheet.  By default the
+      53             : NN, MM and D_0 parameters are set equal to those used in \cite pietrucci09jctc.  The R_0
+      54             : parameter must be set by the user - the value used in \cite pietrucci09jctc was 0.08 nm.
+      55             : 
+      56             : If you change the function in the above sum you can calculate quantities such as the average
+      57             : distance from a purely configuration composed of pure anti-parallel beta sheets or the distance between the set of
+      58             : residues that is closest to an anti-parallel beta sheet and the reference configuration. To do these sorts of
+      59             : calculations you can use the AVERAGE and MIN keywords. In addition you can use the LESS_THAN
+      60             : keyword if you would like to change the form of the switching function. If you use any of these
+      61             : options you no longer need to specify NN, R_0, MM and D_0.
+      62             : 
+      63             : Please be aware that for codes like gromacs you must ensure that plumed
+      64             : reconstructs the chains involved in your CV when you calculate this CV using
+      65             : anything other than TYPE=DRMSD.  For more details as to how to do this see \ref WHOLEMOLECULES.
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : The following input calculates the number of six residue segments of
+      70             : protein that are in an antiparallel beta sheet configuration.
+      71             : 
+      72             : \plumedfile
+      73             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      74             : MOLINFO STRUCTURE=beta.pdb
+      75             : ab: ANTIBETARMSD RESIDUES=all STRANDS_CUTOFF=1
+      76             : \endplumedfile
+      77             : 
+      78             : Here the same is done use RMSD instead of DRMSD
+      79             : 
+      80             : \plumedfile
+      81             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      82             : MOLINFO STRUCTURE=helix.pdb
+      83             : WHOLEMOLECULES ENTITY0=1-100
+      84             : hh: ANTIBETARMSD RESIDUES=all TYPE=OPTIMAL R_0=0.1  STRANDS_CUTOFF=1
+      85             : \endplumedfile
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : class AntibetaRMSD : public SecondaryStructureRMSD {
+      90             : public:
+      91             :   static void registerKeywords( Keywords& keys );
+      92             :   explicit AntibetaRMSD(const ActionOptions&);
+      93             : };
+      94             : 
+      95       10443 : PLUMED_REGISTER_ACTION(AntibetaRMSD,"ANTIBETARMSD")
+      96             : 
+      97          13 : void AntibetaRMSD::registerKeywords( Keywords& keys ) {
+      98          13 :   SecondaryStructureRMSD::registerKeywords( keys );
+      99          26 :   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 "
+     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          13 :   keys.use("STRANDS_CUTOFF");
+     104          13 : }
+     105             : 
+     106          12 : AntibetaRMSD::AntibetaRMSD(const ActionOptions&ao):
+     107             :   Action(ao),
+     108          12 :   SecondaryStructureRMSD(ao)
+     109             : {
+     110             :   // read in the backbone atoms
+     111          24 :   std::vector<unsigned> chains; readBackboneAtoms( "protein", chains );
+     112             : 
+     113             :   bool intra_chain(false), inter_chain(false);
+     114          24 :   std::string style; parse("STYLE",style);
+     115          12 :   if( style=="all" ) {
+     116             :     intra_chain=true; inter_chain=true;
+     117           2 :   } else if( style=="inter") {
+     118             :     intra_chain=false; inter_chain=true;
+     119           0 :   } else if( 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          12 :   setAtomsFromStrands( 6, 21 );
+     127             : 
+     128             :   // This constructs all conceivable sections of antibeta sheet in the backbone of the chains
+     129          12 :   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         330 :       for(unsigned ires=0; ires<nres-7; ires++) {
+     137         344 :         for(unsigned jres=ires+7; jres<nres; jres++) {
+     138        2832 :           for(unsigned k=0; k<15; ++k) {
+     139        2655 :             nlist[k]=nprevious + ires*5+k;
+     140        2655 :             nlist[k+15]=nprevious + (jres-2)*5+k;
+     141             :           }
+     142         177 :           addColvar( nlist );
+     143             :         }
+     144             :       }
+     145         163 :       nprevious+=chains[i];
+     146             :     }
+     147             :   }
+     148          12 :   if( inter_chain ) {
+     149          13 :     if( chains.size()==1 && style!="all" ) error("there is only one chain defined so cannot use inter_chain option");
+     150          12 :     std::vector<unsigned> nlist(30);
+     151         167 :     for(unsigned ichain=1; ichain<chains.size(); ++ichain) {
+     152        1534 :       unsigned iprev=0; for(unsigned i=0; i<ichain; ++i) iprev+=chains[i];
+     153         155 :       unsigned inres=chains[ichain]/5;
+     154         155 :       if( chains[ichain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     155        1075 :       for(unsigned ires=0; ires<inres-2; ++ires) {
+     156        9184 :         for(unsigned jchain=0; jchain<ichain; ++jchain) {
+     157       52328 :           unsigned jprev=0; for(unsigned i=0; i<jchain; ++i) jprev+=chains[i];
+     158        8264 :           unsigned jnres=chains[jchain]/5;
+     159        8264 :           if( chains[jchain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     160       57838 :           for(unsigned jres=0; jres<jnres-2; ++jres) {
+     161      793184 :             for(unsigned k=0; k<15; ++k) {
+     162      743610 :               nlist[k]=iprev+ ires*5+k;
+     163      743610 :               nlist[k+15]=jprev+ jres*5+k;
+     164             :             }
+     165       49574 :             addColvar( nlist );
+     166             :           }
+     167             :         }
+     168             :       }
+     169             :     }
+     170             :   }
+     171             : 
+     172             :   // Build the reference structure ( in angstroms )
+     173          12 :   std::vector<Vector> reference(30);
+     174          12 :   reference[0]=Vector( 2.263, -3.795,  1.722); // N    i
+     175          12 :   reference[1]=Vector( 2.493, -2.426,  2.263); // CA
+     176          12 :   reference[2]=Vector( 3.847, -1.838,  1.761); // CB
+     177          12 :   reference[3]=Vector( 1.301, -1.517,  1.921); // C
+     178          12 :   reference[4]=Vector( 0.852, -1.504,  0.739); // O
+     179          12 :   reference[5]=Vector( 0.818, -0.738,  2.917); // N    i+1
+     180          12 :   reference[6]=Vector(-0.299,  0.243,  2.748); // CA
+     181          12 :   reference[7]=Vector(-1.421, -0.076,  3.757); // CB
+     182          12 :   reference[8]=Vector( 0.273,  1.680,  2.854); // C
+     183          12 :   reference[9]=Vector( 0.902,  1.993,  3.888); // O
+     184          12 :   reference[10]=Vector( 0.119,  2.532,  1.813); // N    i+2
+     185          12 :   reference[11]=Vector( 0.683,  3.916,  1.680); // CA
+     186          12 :   reference[12]=Vector( 1.580,  3.940,  0.395); // CB
+     187          12 :   reference[13]=Vector(-0.394,  5.011,  1.630); // C
+     188          12 :   reference[14]=Vector(-1.459,  4.814,  0.982); // O
+     189          12 :   reference[15]=Vector(-2.962,  3.559, -1.359); // N    j-2
+     190          12 :   reference[16]=Vector(-2.439,  2.526, -2.287); // CA
+     191          12 :   reference[17]=Vector(-1.189,  3.006, -3.087); // CB
+     192          12 :   reference[18]=Vector(-2.081,  1.231, -1.520); // C
+     193          12 :   reference[19]=Vector(-1.524,  1.324, -0.409); // O
+     194          12 :   reference[20]=Vector(-2.326,  0.037, -2.095); // N    j-1
+     195          12 :   reference[21]=Vector(-1.858, -1.269, -1.554); // CA
+     196          12 :   reference[22]=Vector(-3.053, -2.199, -1.291); // CB
+     197          12 :   reference[23]=Vector(-0.869, -1.949, -2.512); // C
+     198          12 :   reference[24]=Vector(-1.255, -2.070, -3.710); // O
+     199          12 :   reference[25]=Vector( 0.326, -2.363, -2.072); // N    j
+     200          12 :   reference[26]=Vector( 1.405, -2.992, -2.872); // CA
+     201          12 :   reference[27]=Vector( 2.699, -2.129, -2.917); // CB
+     202          12 :   reference[28]=Vector( 1.745, -4.399, -2.330); // C
+     203          12 :   reference[29]=Vector( 1.899, -4.545, -1.102); // O
+     204             : 
+     205             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     206          12 :   setSecondaryStructure( reference, 0.17/atoms.getUnits().getLength(), 0.1/atoms.getUnits().getLength() );
+     207          12 : }
+     208             : 
+     209             : }
+     210             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..02ce9bf103 --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:10610997.2 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe966createERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe96C2Ev3473
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe96D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.func.html b/coverage/secondarystructure/ParabetaRMSD.cpp.func.html new file mode 100644 index 0000000000..d743744dd4 --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:10610997.2 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12ParabetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe966createERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe96C2Ev3473
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe96D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html b/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html new file mode 100644 index 0000000000..b642100b2c --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html @@ -0,0 +1,321 @@ + + + + + + + + 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:10610997.2 %
Date:2024-06-10 08:19:14Functions:5683.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 "SecondaryStructureRMSD.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace secondarystructure {
+      28             : 
+      29             : //+PLUMEDOC COLVAR PARABETARMSD
+      30             : /*
+      31             : Probe the parallel beta sheet content of your protein structure.
+      32             : 
+      33             : Two protein segments containing three contiguous residues can form a parallel beta sheet.
+      34             : Although if the two segments are part of the same protein chain they must be separated by
+      35             : a minimum of 3 residues to make room for the turn. This colvar thus generates the set of
+      36             : all possible six residue sections that could conceivably form a parallel beta sheet
+      37             : and calculates the RMSD distance between the configuration in which the residues find themselves
+      38             : and an idealized parallel beta sheet structure. These distances can be calculated by either
+      39             : aligning the instantaneous structure with the reference structure and measuring each
+      40             : atomic displacement or by calculating differences between the set of inter-atomic
+      41             : distances in the reference and instantaneous structures.
+      42             : 
+      43             : This colvar is based on the following reference \cite pietrucci09jctc.  The authors of
+      44             : this paper use the set of distances from the parallel beta sheet configurations to measure
+      45             : the number of segments whose configuration resembles a parallel beta sheet. This is done by calculating
+      46             : the following sum of functions of the rmsd distances:
+      47             : 
+      48             : \f[
+      49             : 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 }
+      50             : \f]
+      51             : 
+      52             : where the sum runs over all possible segments of parallel beta sheet.  By default the
+      53             : NN, MM and D_0 parameters are set equal to those used in \cite pietrucci09jctc.  The R_0
+      54             : parameter must be set by the user - the value used in \cite pietrucci09jctc was 0.08 nm.
+      55             : 
+      56             : If you change the function in the above sum you can calculate quantities such as the average
+      57             : distance from a structure composed of only parallel beta sheets or the distance between the set of
+      58             : residues that is closest to a parallel beta sheet and the reference configuration. To do these sorts of
+      59             : calculations you can use the AVERAGE and MIN keywords. In addition you can use the LESS_THAN
+      60             : keyword if you would like to change the form of the switching function. If you use any of these
+      61             : options you no longer need to specify NN, R_0, MM and D_0.
+      62             : 
+      63             : Please be aware that for codes like gromacs you must ensure that plumed
+      64             : reconstructs the chains involved in your CV when you calculate this CV using
+      65             : anything other than TYPE=DRMSD.  For more details as to how to do this see \ref WHOLEMOLECULES.
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : The following input calculates the number of six residue segments of
+      70             : protein that are in an parallel beta sheet configuration.
+      71             : 
+      72             : \plumedfile
+      73             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      74             : MOLINFO STRUCTURE=beta.pdb
+      75             : pb: PARABETARMSD RESIDUES=all STRANDS_CUTOFF=1
+      76             : \endplumedfile
+      77             : 
+      78             : Here the same is done use RMSD instead of DRMSD
+      79             : 
+      80             : \plumedfile
+      81             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      82             : MOLINFO STRUCTURE=helix.pdb
+      83             : WHOLEMOLECULES ENTITY0=1-100
+      84             : hh: PARABETARMSD RESIDUES=all TYPE=OPTIMAL R_0=0.1  STRANDS_CUTOFF=1
+      85             : \endplumedfile
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : class ParabetaRMSD : public SecondaryStructureRMSD {
+      91             : public:
+      92             :   static void registerKeywords( Keywords& keys );
+      93             :   explicit ParabetaRMSD(const ActionOptions&);
+      94             : };
+      95             : 
+      96       10439 : PLUMED_REGISTER_ACTION(ParabetaRMSD,"PARABETARMSD")
+      97             : 
+      98          11 : void ParabetaRMSD::registerKeywords( Keywords& keys ) {
+      99          11 :   SecondaryStructureRMSD::registerKeywords( keys );
+     100          22 :   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 "
+     101             :            "chain configuration with the appropriate geometry are counted.  If STYLE=inter "
+     102             :            "only sheet-like configurations involving two chains are counted, while if STYLE=intra "
+     103             :            "only sheet-like configurations involving a single chain are counted");
+     104          11 :   keys.use("STRANDS_CUTOFF");
+     105          11 : }
+     106             : 
+     107          10 : ParabetaRMSD::ParabetaRMSD(const ActionOptions&ao):
+     108             :   Action(ao),
+     109          10 :   SecondaryStructureRMSD(ao)
+     110             : {
+     111             :   // read in the backbone atoms
+     112          20 :   std::vector<unsigned> chains; readBackboneAtoms( "protein", chains );
+     113             : 
+     114             :   bool intra_chain(false), inter_chain(false);
+     115          20 :   std::string style; parse("STYLE",style);
+     116          10 :   if( style=="all" ) {
+     117             :     intra_chain=true; inter_chain=true;
+     118           0 :   } else if( style=="inter") {
+     119             :     intra_chain=false; inter_chain=true;
+     120           0 :   } else if( style=="intra") {
+     121             :     intra_chain=true; inter_chain=false;
+     122             :   } else {
+     123           0 :     error( style + " is not a valid directive for the STYLE keyword");
+     124             :   }
+     125             : 
+     126             :   // Align the atoms based on the positions of these two atoms
+     127          10 :   setAtomsFromStrands( 6, 21 );
+     128             : 
+     129             :   // This constructs all conceivable sections of antibeta sheet in the backbone of the chains
+     130          10 :   if( intra_chain ) {
+     131          10 :     unsigned nprevious=0; std::vector<unsigned> nlist(30);
+     132         173 :     for(unsigned i=0; i<chains.size(); ++i) {
+     133         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");
+     134             :       // Loop over all possible triples in each 8 residue segment of protein
+     135         163 :       unsigned nres=chains[i]/5;
+     136         163 :       if( chains[i]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     137         167 :       for(unsigned ires=0; ires<nres-8; ires++) {
+     138          14 :         for(unsigned jres=ires+6; jres<nres-2; jres++) {
+     139         160 :           for(unsigned k=0; k<15; ++k) {
+     140         150 :             nlist[k]=nprevious + ires*5+k;
+     141         150 :             nlist[k+15]=nprevious + jres*5+k;
+     142             :           }
+     143          10 :           addColvar( nlist );
+     144             :         }
+     145             :       }
+     146         163 :       nprevious+=chains[i];
+     147             :     }
+     148             :   }
+     149             :   // This constructs all conceivable sections of antibeta sheet that form between chains
+     150          10 :   if( inter_chain ) {
+     151          11 :     if( chains.size()==1 && style!="all" ) error("there is only one chain defined so cannot use inter_chain option");
+     152          10 :     std::vector<unsigned> nlist(30);
+     153         163 :     for(unsigned ichain=1; ichain<chains.size(); ++ichain) {
+     154        1530 :       unsigned iprev=0; for(unsigned i=0; i<ichain; ++i) iprev+=chains[i];
+     155         153 :       unsigned inres=chains[ichain]/5;
+     156         153 :       if( chains[ichain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     157        1071 :       for(unsigned ires=0; ires<inres-2; ++ires) {
+     158        9180 :         for(unsigned jchain=0; jchain<ichain; ++jchain) {
+     159       52326 :           unsigned jprev=0; for(unsigned i=0; i<jchain; ++i) jprev+=chains[i];
+     160        8262 :           unsigned jnres=chains[jchain]/5;
+     161        8262 :           if( chains[jchain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     162       57834 :           for(unsigned jres=0; jres<jnres-2; ++jres) {
+     163      793152 :             for(unsigned k=0; k<15; ++k) {
+     164      743580 :               nlist[k]=iprev + ires*5+k;
+     165      743580 :               nlist[k+15]=jprev + jres*5+k;
+     166             :             }
+     167       49572 :             addColvar( nlist );
+     168             :           }
+     169             :         }
+     170             :       }
+     171             :     }
+     172             :   }
+     173             : 
+     174             :   // Build the reference structure ( in angstroms )
+     175          10 :   std::vector<Vector> reference(30);
+     176          10 :   reference[0]=Vector( 1.244, -4.620, -2.127); // N    i
+     177          10 :   reference[1]=Vector(-0.016, -4.500, -1.395); // CA
+     178          10 :   reference[2]=Vector( 0.105, -5.089,  0.024); // CB
+     179          10 :   reference[3]=Vector(-0.287, -3.000, -1.301); // C
+     180          10 :   reference[4]=Vector( 0.550, -2.245, -0.822); // O
+     181          10 :   reference[5]=Vector(-1.445, -2.551, -1.779); // N    i+1
+     182          10 :   reference[6]=Vector(-1.752, -1.130, -1.677); // CA
+     183          10 :   reference[7]=Vector(-2.113, -0.550, -3.059); // CB
+     184          10 :   reference[8]=Vector(-2.906, -0.961, -0.689); // C
+     185          10 :   reference[9]=Vector(-3.867, -1.738, -0.695); // O
+     186          10 :   reference[10]=Vector(-2.774,  0.034,  0.190); // N    i+2
+     187          10 :   reference[11]=Vector(-3.788,  0.331,  1.201); // CA
+     188          10 :   reference[12]=Vector(-3.188,  0.300,  2.624); // CB
+     189          10 :   reference[13]=Vector(-4.294,  1.743,  0.937); // C
+     190          10 :   reference[14]=Vector(-3.503,  2.671,  0.821); // O
+     191          10 :   reference[15]=Vector( 4.746, -2.363,  0.188); // N    j
+     192          10 :   reference[16]=Vector( 3.427, -1.839,  0.545); // CA
+     193          10 :   reference[17]=Vector( 3.135, -1.958,  2.074); // CB
+     194          10 :   reference[18]=Vector( 3.346, -0.365,  0.181); // C
+     195          10 :   reference[19]=Vector( 4.237,  0.412,  0.521); // O
+     196          10 :   reference[20]=Vector( 2.261,  0.013, -0.487); // N    j+1
+     197          10 :   reference[21]=Vector( 2.024,  1.401, -0.875); // CA
+     198          10 :   reference[22]=Vector( 1.489,  1.514, -2.313); // CB
+     199          10 :   reference[23]=Vector( 0.914,  1.902,  0.044); // C
+     200          10 :   reference[24]=Vector(-0.173,  1.330,  0.052); // O
+     201          10 :   reference[25]=Vector( 1.202,  2.940,  0.828); // N    j+2
+     202          10 :   reference[26]=Vector( 0.190,  3.507,  1.718); // CA
+     203          10 :   reference[27]=Vector( 0.772,  3.801,  3.104); // CB
+     204          10 :   reference[28]=Vector(-0.229,  4.791,  1.038); // C
+     205          10 :   reference[29]=Vector( 0.523,  5.771,  0.996); // O
+     206             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     207          10 :   setSecondaryStructure( reference, 0.17/atoms.getUnits().getLength(), 0.1/atoms.getUnits().getLength() );
+     208             : 
+     209          10 :   reference[0]=Vector(-1.439, -5.122, -1.144); // N    i
+     210          10 :   reference[1]=Vector(-0.816, -3.803, -1.013); // CA
+     211          10 :   reference[2]=Vector( 0.099, -3.509, -2.206); // CB
+     212          10 :   reference[3]=Vector(-1.928, -2.770, -0.952); // C
+     213          10 :   reference[4]=Vector(-2.991, -2.970, -1.551); // O
+     214          10 :   reference[5]=Vector(-1.698, -1.687, -0.215); // N    i+1
+     215          10 :   reference[6]=Vector(-2.681, -0.613, -0.143); // CA
+     216          10 :   reference[7]=Vector(-3.323, -0.477,  1.267); // CB
+     217          10 :   reference[8]=Vector(-1.984,  0.681, -0.574); // C
+     218          10 :   reference[9]=Vector(-0.807,  0.921, -0.273); // O
+     219          10 :   reference[10]=Vector(-2.716,  1.492, -1.329); // N    i+2
+     220          10 :   reference[11]=Vector(-2.196,  2.731, -1.883); // CA
+     221          10 :   reference[12]=Vector(-2.263,  2.692, -3.418); // CB
+     222          10 :   reference[13]=Vector(-2.989,  3.949, -1.433); // C
+     223          10 :   reference[14]=Vector(-4.214,  3.989, -1.583); // O
+     224          10 :   reference[15]=Vector( 2.464, -4.352,  2.149); // N    j
+     225          10 :   reference[16]=Vector( 3.078, -3.170,  1.541); // CA
+     226          10 :   reference[17]=Vector( 3.398, -3.415,  0.060); // CB
+     227          10 :   reference[18]=Vector( 2.080, -2.021,  1.639); // C
+     228          10 :   reference[19]=Vector( 0.938, -2.178,  1.225); // O
+     229          10 :   reference[20]=Vector( 2.525, -0.886,  2.183); // N    j+1
+     230          10 :   reference[21]=Vector( 1.692,  0.303,  2.346); // CA
+     231          10 :   reference[22]=Vector( 1.541,  0.665,  3.842); // CB
+     232          10 :   reference[23]=Vector( 2.420,  1.410,  1.608); // C
+     233          10 :   reference[24]=Vector( 3.567,  1.733,  1.937); // O
+     234          10 :   reference[25]=Vector( 1.758,  1.976,  0.600); // N    j+2
+     235          10 :   reference[26]=Vector( 2.373,  2.987, -0.238); // CA
+     236          10 :   reference[27]=Vector( 2.367,  2.527, -1.720); // CB
+     237          10 :   reference[28]=Vector( 1.684,  4.331, -0.148); // C
+     238          10 :   reference[29]=Vector( 0.486,  4.430, -0.415); // O
+     239             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     240          10 :   setSecondaryStructure( reference, 0.17/atoms.getUnits().getLength(), 0.1/atoms.getUnits().getLength() );
+     241          10 : }
+     242             : 
+     243             : }
+     244             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7163e54f83 --- /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-06-10 08:19:14Functions: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_8KeywordsE28
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD21setSecondaryStructureERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEdd35
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17turnOnDerivativesEv62
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD5applyEv192
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9calculateEv2568
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9addColvarERKSt6vectorIjSaIjEE99342
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD11performTaskERKjS3_RNS_10MultiValueE400032
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html new file mode 100644 index 0000000000..cd176ca990 --- /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-06-10 08:19:14Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD16registerKeywordsERNS_8KeywordsE28
_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.15
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html new file mode 100644 index 0000000000..972ad8fbb0 --- /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-06-10 08:19:14Functions: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 "core/Atoms.h"
+      27             : #include "vesselbase/Vessel.h"
+      28             : #include "reference/MetricRegister.h"
+      29             : #include "reference/SingleDomainRMSD.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace secondarystructure {
+      33             : 
+      34          28 : void SecondaryStructureRMSD::registerKeywords( Keywords& keys ) {
+      35          28 :   Action::registerKeywords( keys );
+      36          28 :   ActionWithValue::registerKeywords( keys );
+      37          28 :   ActionAtomistic::registerKeywords( keys );
+      38          56 :   keys.add("residues","RESIDUES","this command is used to specify the set of residues that could conceivably form part of the secondary structure. "
+      39             :            "It is possible to use residues numbers as the various chains and residues should have been identified else using an instance of the "
+      40             :            "\\ref MOLINFO action. If you wish to use all the residues from all the chains in your system you can do so by "
+      41             :            "specifying all. Alternatively, if you wish to use a subset of the residues you can specify the particular residues "
+      42             :            "you are interested in as a list of numbers. Please be aware that to form secondary structure elements your chain "
+      43             :            "must contain at least N residues, where N is dependent on the particular secondary structure you are interested in. "
+      44             :            "As such if you define portions of the chain with fewer than N residues the code will crash.");
+      45          56 :   keys.add("compulsory","TYPE","DRMSD","the manner in which RMSD alignment is performed. Should be OPTIMAL, SIMPLE or DRMSD. "
+      46             :            "For more details on the OPTIMAL and SIMPLE methods see \\ref RMSD. For more details on the "
+      47             :            "DRMSD method see \\ref DRMSD.");
+      48          56 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions");
+      49          56 :   keys.add("compulsory","R_0","0.08","The r_0 parameter of the switching function.");
+      50          56 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      51          56 :   keys.add("compulsory","NN","8","The n parameter of the switching function");
+      52          56 :   keys.add("compulsory","MM","12","The m parameter of the switching function");
+      53          56 :   keys.reserve("optional","STRANDS_CUTOFF","If in a segment of protein the two strands are further apart then the calculation "
+      54             :                "of the actual RMSD is skipped as the structure is very far from being beta-sheet like. "
+      55             :                "This keyword speeds up the calculation enormously when you are using the LESS_THAN option. "
+      56             :                "However, if you are using some other option, then this cannot be used");
+      57          56 :   keys.addFlag("VERBOSE",false,"write a more detailed output");
+      58          56 :   keys.add("hidden","NL_STRIDE","the frequency with which the neighbor list should be updated. Between neighbour list update steps all quantities "
+      59             :            "that contributed less than TOL at the previous neighbor list update step are ignored.");
+      60          28 :   ActionWithVessel::registerKeywords( keys );
+      61         140 :   keys.use("LESS_THAN"); keys.use("MIN"); keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      62          28 :   keys.setComponentsIntroduction("By default this Action calculates the number of structural units that are within a certain "
+      63             :                                  "distance of a idealized secondary structure element. This quantity can then be referenced "
+      64             :                                  "elsewhere in the input by using the label of the action. However, this Action can also be used to "
+      65             :                                  "calculate the following quantities by using the keywords as described below.  The quantities then "
+      66             :                                  "calculated can be referenced using the label of the action followed by a dot and then the name "
+      67             :                                  "from the table below.  Please note that you can use the LESS_THAN keyword more than once.  The resulting "
+      68             :                                  "components will be labelled <em>label</em>.lessthan-1, <em>label</em>.lessthan-2 and so on unless you "
+      69             :                                  "exploit the fact that these labels can be given custom labels by using the LABEL keyword in the "
+      70             :                                  "description of you LESS_THAN function that you are computing");
+      71          28 : }
+      72             : 
+      73          25 : SecondaryStructureRMSD::SecondaryStructureRMSD(const ActionOptions&ao):
+      74             :   Action(ao),
+      75             :   ActionAtomistic(ao),
+      76             :   ActionWithValue(ao),
+      77             :   ActionWithVessel(ao),
+      78          25 :   nopbc(false),
+      79          25 :   align_strands(false),
+      80          25 :   s_cutoff2(0),
+      81          25 :   align_atom_1(0),
+      82          25 :   align_atom_2(0)
+      83             : {
+      84          50 :   parse("TYPE",alignType); parseFlag("NOPBC",nopbc);
+      85          25 :   log.printf("  distances from secondary structure elements are calculated using %s algorithm\n",alignType.c_str() );
+      86          75 :   log<<"  Bibliography "<<plumed.cite("Pietrucci and Laio, J. Chem. Theory Comput. 5, 2197 (2009)"); log<<"\n";
+      87             : 
+      88          25 :   parseFlag("VERBOSE",verbose_output);
+      89             : 
+      90          50 :   if( keywords.exists("STRANDS_CUTOFF") ) {
+      91          22 :     double s_cutoff = 0;
+      92          22 :     parse("STRANDS_CUTOFF",s_cutoff); align_strands=true;
+      93          22 :     if( s_cutoff>0) log.printf("  ignoring contributions from strands that are more than %f apart\n",s_cutoff);
+      94          22 :     s_cutoff2=s_cutoff*s_cutoff;
+      95             :   }
+      96          25 : }
+      97             : 
+      98          25 : SecondaryStructureRMSD::~SecondaryStructureRMSD() {
+      99             : // destructor needed to delete forward declarated objects
+     100          50 : }
+     101             : 
+     102          62 : void SecondaryStructureRMSD::turnOnDerivatives() {
+     103          62 :   ActionWithValue::turnOnDerivatives();
+     104          62 :   needsDerivatives();
+     105          62 : }
+     106             : 
+     107          22 : void SecondaryStructureRMSD::setAtomsFromStrands( const unsigned& atom1, const unsigned& atom2 ) {
+     108          22 :   align_atom_1=atom1; align_atom_2=atom2;
+     109          22 : }
+     110             : 
+     111          25 : void SecondaryStructureRMSD::readBackboneAtoms( const std::string& moltype, std::vector<unsigned>& chain_lengths ) {
+     112          25 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     113          25 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     114             : 
+     115          25 :   std::vector<std::string> resstrings; parseVector( "RESIDUES", resstrings );
+     116          25 :   if( !verbose_output ) {
+     117          25 :     if(resstrings.size()==0) error("residues are not defined, check the keyword RESIDUES");
+     118          25 :     else if(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( plumed.getAtoms().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 :   if( getForcesFromVessels( forcesToApply ) ) setForcesOnAtoms( forcesToApply );
+     265         192 : }
+     266             : 
+     267             : }
+     268             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ccf7b59902 --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD10isPeriodicEv25
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD21getNumberOfQuantitiesEv5424
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv5607
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html new file mode 100644 index 0000000000..9430c17e40 --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD10isPeriodicEv25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv5607
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD21getNumberOfQuantitiesEv5424
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html new file mode 100644 index 0000000000..bec242dd67 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/secondarystructure/index-sort-f.html b/coverage/secondarystructure/index-sort-f.html new file mode 100644 index 0000000000..4cd0a7eac2 --- /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:37638996.7 %
Date:2024-06-10 08:19:14Functions:293582.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
AntibetaRMSD.cpp +
97.4%97.4%
+
97.4 %76 / 7883.3 %5 / 6
AlphaRMSD.cpp +
100.0%
+
100.0 %50 / 5083.3 %5 / 6
ParabetaRMSD.cpp +
97.2%97.2%
+
97.2 %106 / 10983.3 %5 / 6
SecondaryStructureRMSD.h +
100.0%
+
100.0 %6 / 6100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/index-sort-l.html b/coverage/secondarystructure/index-sort-l.html new file mode 100644 index 0000000000..909140aaad --- /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:37638996.7 %
Date:2024-06-10 08:19:14Functions:293582.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 %106 / 10983.3 %5 / 6
AntibetaRMSD.cpp +
97.4%97.4%
+
97.4 %76 / 7883.3 %5 / 6
SecondaryStructureRMSD.h +
100.0%
+
100.0 %6 / 6100.0 %3 / 3
AlphaRMSD.cpp +
100.0%
+
100.0 %50 / 5083.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/secondarystructure/index.html b/coverage/secondarystructure/index.html new file mode 100644 index 0000000000..109010cbf1 --- /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:37638996.7 %
Date:2024-06-10 08:19:14Functions:293582.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AlphaRMSD.cpp +
100.0%
+
100.0 %50 / 5083.3 %5 / 6
AntibetaRMSD.cpp +
97.4%97.4%
+
97.4 %76 / 7883.3 %5 / 6
ParabetaRMSD.cpp +
97.2%97.2%
+
97.2 %106 / 10983.3 %5 / 6
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.15
+
+ + + 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 0000000000..41d9d3dddb --- /dev/null +++ b/coverage/setup/Load.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup4LoadC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe1046createERKNS_13ActionOptionsE2
_ZN4PLMD5setup4LoadC1ERKNS_13ActionOptionsE2
_ZN4PLMD5setup4Load16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe104C2Ev3473
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe104D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/setup/Load.cpp.func.html b/coverage/setup/Load.cpp.func.html new file mode 100644 index 0000000000..2e2d8858a0 --- /dev/null +++ b/coverage/setup/Load.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:1111100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe1046createERKNS_13ActionOptionsE2
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe104C2Ev3473
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe104D2Ev3473
_ZN4PLMD5setup4Load16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD5setup4LoadC1ERKNS_13ActionOptionsE2
_ZN4PLMD5setup4LoadC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/setup/Load.cpp.gcov.html b/coverage/setup/Load.cpp.gcov.html new file mode 100644 index 0000000000..c99485fb9a --- /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:1111100.0 %
Date:2024-06-10 08:19:14Functions:5683.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/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       10422 : PLUMED_REGISTER_ACTION(Load,"LOAD")
+     105             : 
+     106           3 : void Load::registerKeywords( Keywords& keys ) {
+     107           3 :   ActionSetup::registerKeywords(keys);
+     108           6 :   keys.add("compulsory","FILE","file to be loaded");
+     109           3 : }
+     110             : 
+     111           2 : Load::Load(const ActionOptions&ao):
+     112             :   Action(ao),
+     113           2 :   ActionSetup(ao)
+     114             : {
+     115             :   std::string f;
+     116           3 :   parse("FILE",f);
+     117           2 :   checkRead();
+     118           2 :   plumed.load(f);
+     119           2 : }
+     120             : 
+     121             : }
+     122             : }
+     123             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..447fb26665 --- /dev/null +++ b/coverage/setup/Restart.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:1919100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup7RestartC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe986createERKNS_13ActionOptionsE56
_ZN4PLMD5setup7RestartC1ERKNS_13ActionOptionsE56
_ZN4PLMD5setup7Restart16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe98C2Ev3473
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe98D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/setup/Restart.cpp.func.html b/coverage/setup/Restart.cpp.func.html new file mode 100644 index 0000000000..427e7ea730 --- /dev/null +++ b/coverage/setup/Restart.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:1919100.0 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe986createERKNS_13ActionOptionsE56
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe98C2Ev3473
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe98D2Ev3473
_ZN4PLMD5setup7Restart16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD5setup7RestartC1ERKNS_13ActionOptionsE56
_ZN4PLMD5setup7RestartC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/setup/Restart.cpp.gcov.html b/coverage/setup/Restart.cpp.gcov.html new file mode 100644 index 0000000000..39082af6ba --- /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:1919100.0 %
Date:2024-06-10 08:19:14Functions:5683.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/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       10531 : PLUMED_REGISTER_ACTION(Restart,"RESTART")
+      99             : 
+     100          57 : void Restart::registerKeywords( Keywords& keys ) {
+     101          57 :   ActionSetup::registerKeywords(keys);
+     102         114 :   keys.addFlag("NO",false,"switch off restart - can be used to override the behavior of the MD engine");
+     103          57 : }
+     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.15
+
+ + + 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 0000000000..4b6fba28ae --- /dev/null +++ b/coverage/setup/Units.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:575996.6 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup5UnitsC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe986createERKNS_13ActionOptionsE19
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE19
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe98C2Ev3473
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe98D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/setup/Units.cpp.func.html b/coverage/setup/Units.cpp.func.html new file mode 100644 index 0000000000..21488d6480 --- /dev/null +++ b/coverage/setup/Units.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:575996.6 %
Date:2024-06-10 08:19:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe986createERKNS_13ActionOptionsE19
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe98C2Ev3473
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe98D2Ev3473
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE19
_ZN4PLMD5setup5UnitsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/setup/Units.cpp.gcov.html b/coverage/setup/Units.cpp.gcov.html new file mode 100644 index 0000000000..992ef1f481 --- /dev/null +++ b/coverage/setup/Units.cpp.gcov.html @@ -0,0 +1,278 @@ + + + + + + + + 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:575996.6 %
Date:2024-06-10 08:19:14Functions: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 "core/ActionSetup.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/Atoms.h"
+      26             : #include "tools/Exception.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace setup {
+      30             : 
+      31             : //+PLUMEDOC GENERIC UNITS
+      32             : /*
+      33             : This command sets the internal units for the code.
+      34             : 
+      35             : A new unit can be set by either
+      36             : specifying a conversion factor from the plumed default unit or by using a string
+      37             : corresponding to one of the defined units given below.  This directive MUST
+      38             : appear at the BEGINNING of the plumed.dat file.  The same units must be used
+      39             : throughout the plumed.dat file.
+      40             : 
+      41             : Notice that all input/output will then be made using the specified units.
+      42             : That is: all the input parameters, all the output files, etc. The only
+      43             : exceptions are file formats for which there is a specific convention concerning
+      44             : the units. For example, trajectories written in .gro format (with \ref DUMPATOMS)
+      45             : are going to be always in nm.
+      46             : 
+      47             : The following strings can be used to specify units. Note that the strings are
+      48             : case sensitive.
+      49             : - LENGTH: nm (default), A (for Angstrom), um (for micrometer), Bohr (0.052917721067 nm)
+      50             : - ENERGY: kj/mol (default), j/mol, kcal/mol (4.184 kj/mol), eV (96.48530749925792 kj/mol), Ha (for Hartree, 2625.499638 kj/mol)
+      51             : - TIME: ps (default), fs, ns, atomic (2.418884326509e-5 ps)
+      52             : - MASS: amu (default)
+      53             : - CHARGE: e (default)
+      54             : 
+      55             : 
+      56             : \par Examples
+      57             : 
+      58             : \plumedfile
+      59             : # this is using Angstrom - kj/mol - fs
+      60             : UNITS LENGTH=A TIME=fs
+      61             : 
+      62             : # compute distance between atoms 1 and 4
+      63             : d: DISTANCE ATOMS=1,4
+      64             : 
+      65             : # print time and distance on a COLVAR file
+      66             : PRINT ARG=d FILE=COLVAR
+      67             : 
+      68             : # dump atoms 1 to 100 on a 'out.gro' file
+      69             : DUMPATOMS FILE=out.gro STRIDE=10 ATOMS=1-100
+      70             : 
+      71             : # dump atoms 1 to 100 on a 'out.xyz' file
+      72             : DUMPATOMS FILE=out.xyz STRIDE=10 ATOMS=1-100
+      73             : \endplumedfile
+      74             : 
+      75             : In the `COLVAR` file, time and distance will appear in fs and A respectively, *irrespective* of which units
+      76             : you are using in the host MD code. The coordinates in the `out.gro` file will be expressed in nm,
+      77             : since `gro` files are by convention written in nm. The coordinates in the `out.xyz` file
+      78             : will be written in Angstrom *since we used the UNITS command setting Angstrom units*.
+      79             : Indeed, within PLUMED xyz files are using internal PLUMED units and not necessarily Angstrom!
+      80             : 
+      81             : If a number, x, is found instead of a string, the new unit is equal to x times the default units.
+      82             : Using the following command as first line of the previous example would have lead to an identical result:
+      83             : \plumedfile
+      84             : UNITS LENGTH=0.1 TIME=0.001
+      85             : \endplumedfile
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : class Units :
+      91             :   public virtual ActionSetup
+      92             : {
+      93             : public:
+      94             :   static void registerKeywords( Keywords& keys );
+      95             :   explicit Units(const ActionOptions&ao);
+      96             : };
+      97             : 
+      98       10457 : PLUMED_REGISTER_ACTION(Units,"UNITS")
+      99             : 
+     100          20 : void Units::registerKeywords( Keywords& keys ) {
+     101          20 :   ActionSetup::registerKeywords(keys);
+     102          40 :   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.");
+     103          40 :   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)");
+     104          40 :   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");
+     105          40 :   keys.add("optional","MASS","the units of masses.  Specify a conversion factor from the default, amu");
+     106          40 :   keys.add("optional","CHARGE","the units of charges.  Specify a conversion factor from the default, e");
+     107          40 :   keys.addFlag("NATURAL",false,"use natural units");
+     108          20 : }
+     109             : 
+     110          19 : Units::Units(const ActionOptions&ao):
+     111             :   Action(ao),
+     112          19 :   ActionSetup(ao)
+     113             : {
+     114          19 :   PLMD::Units u;
+     115             : 
+     116             :   std::string s;
+     117             : 
+     118             :   s="";
+     119          38 :   parse("LENGTH",s);
+     120          19 :   if(s.length()>0) u.setLength(s);
+     121          36 :   if(u.getLengthString().length()>0 && u.getLengthString()=="nm") {
+     122           8 :     log.printf("  length: %s\n",u.getLengthString().c_str());
+     123             :   }
+     124          20 :   else if(u.getLengthString().length()>0 && u.getLengthString()!="nm") {
+     125           9 :     log.printf("  length: %s = %g nm\n",u.getLengthString().c_str(),u.getLength());
+     126             :   }
+     127             :   else {
+     128           2 :     log.printf("  length: %g nm\n",u.getLength());
+     129             :   }
+     130             : 
+     131             :   s="";
+     132          38 :   parse("ENERGY",s);
+     133          19 :   if(s.length()>0) u.setEnergy(s);
+     134          36 :   if(u.getEnergyString().length()>0 && u.getEnergyString()=="kj/mol") {
+     135          12 :     log.printf("  energy: %s\n",u.getEnergyString().c_str());
+     136             :   }
+     137          12 :   else if(u.getEnergyString().length()>0 && u.getEnergyString()!="kj/mol") {
+     138           5 :     log.printf("  energy: %s = %g kj/mol\n",u.getEnergyString().c_str(),u.getEnergy());
+     139             :   }
+     140             :   else {
+     141           2 :     log.printf("  energy: %g kj/mol\n",u.getEnergy());
+     142             :   }
+     143             : 
+     144             :   s="";
+     145          38 :   parse("TIME",s);
+     146          19 :   if(s.length()>0) u.setTime(s);
+     147          36 :   if(u.getTimeString().length()>0 && u.getTimeString()=="ps") {
+     148          14 :     log.printf("  time: %s\n",u.getTimeString().c_str());
+     149             :   }
+     150           8 :   else if(u.getTimeString().length()>0 && u.getTimeString()!="ps") {
+     151           3 :     log.printf("  time: %s = %g ps\n",u.getTimeString().c_str(),u.getTime());
+     152             :   }
+     153             :   else {
+     154           2 :     log.printf("  time: %g ps\n",u.getTime());
+     155             :   }
+     156             : 
+     157             :   s="";
+     158          38 :   parse("CHARGE",s);
+     159          19 :   if(s.length()>0) u.setCharge(s);
+     160          36 :   if(u.getChargeString().length()>0 && u.getChargeString()=="e") {
+     161          17 :     log.printf("  charge: %s\n",u.getChargeString().c_str());
+     162             :   }
+     163           2 :   else if(u.getChargeString().length()>0 && u.getChargeString()!="e") {
+     164           0 :     log.printf("  charge: %s = %g e\n",u.getChargeString().c_str(),u.getCharge());
+     165             :   }
+     166             :   else {
+     167           2 :     log.printf("  charge: %g e\n",u.getCharge());
+     168             :   }
+     169             : 
+     170             :   s="";
+     171          38 :   parse("MASS",s);
+     172          19 :   if(s.length()>0) u.setMass(s);
+     173          37 :   if(u.getMassString().length()>0 && u.getMassString()=="amu") {
+     174          18 :     log.printf("  mass: %s\n",u.getMassString().c_str());
+     175             :   }
+     176           1 :   else if(u.getMassString().length()>0 && u.getMassString()!="amu") {
+     177           0 :     log.printf("  mass: %s = %g amu\n",u.getMassString().c_str(),u.getMass());
+     178             :   }
+     179             :   else {
+     180           1 :     log.printf("  mass: %g amu\n",u.getMass());
+     181             :   }
+     182             : 
+     183          19 :   bool natural=false;
+     184          19 :   parseFlag("NATURAL",natural);
+     185          19 :   plumed.getAtoms().setNaturalUnits(natural);
+     186             : 
+     187          19 :   checkRead();
+     188             : 
+     189          19 :   plumed.getAtoms().setUnits(u);
+     190          19 :   if(natural) {
+     191           6 :     log.printf("  using natural units\n");
+     192             :   } else {
+     193          13 :     log.printf("  using physical units\n");
+     194             :   }
+     195          19 :   log.printf("  inside PLUMED, Boltzmann constant is %g\n",plumed.getAtoms().getKBoltzmann());
+     196             : 
+     197          19 :   plumed.getAtoms().updateUnits();
+     198          19 : }
+     199             : 
+     200             : }
+     201             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/setup/index-sort-f.html b/coverage/setup/index-sort-f.html new file mode 100644 index 0000000000..22aa67a908 --- /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:878997.8 %
Date:2024-06-10 08:19:14Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Units.cpp +
96.6%96.6%
+
96.6 %57 / 5983.3 %5 / 6
Load.cpp +
100.0%
+
100.0 %11 / 1183.3 %5 / 6
Restart.cpp +
100.0%
+
100.0 %19 / 1983.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/setup/index-sort-l.html b/coverage/setup/index-sort-l.html new file mode 100644 index 0000000000..e5bf77f42f --- /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:878997.8 %
Date:2024-06-10 08:19:14Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Units.cpp +
96.6%96.6%
+
96.6 %57 / 5983.3 %5 / 6
Load.cpp +
100.0%
+
100.0 %11 / 1183.3 %5 / 6
Restart.cpp +
100.0%
+
100.0 %19 / 1983.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/setup/index.html b/coverage/setup/index.html new file mode 100644 index 0000000000..a4b1d25d72 --- /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:878997.8 %
Date:2024-06-10 08:19:14Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Load.cpp +
100.0%
+
100.0 %11 / 1183.3 %5 / 6
Restart.cpp +
100.0%
+
100.0 %19 / 1983.3 %5 / 6
Units.cpp +
96.6%96.6%
+
96.6 %57 / 5983.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..fb08a08a68 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/Angle.cpp.func.html b/coverage/tools/Angle.cpp.func.html new file mode 100644 index 0000000000..20b9484f7b --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/Angle.cpp.gcov.html b/coverage/tools/Angle.cpp.gcov.html new file mode 100644 index 0000000000..c48d1dbd64 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..d2e582755d --- /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:1717100.0 %
Date:2024-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj696
_ZN4PLMD10AtomNumber9setSerialEj470622
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/AtomNumber.h.func.html b/coverage/tools/AtomNumber.h.func.html new file mode 100644 index 0000000000..2c72254d0d --- /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:1717100.0 %
Date:2024-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj696
_ZN4PLMD10AtomNumber9setSerialEj470622
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/AtomNumber.h.gcov.html b/coverage/tools/AtomNumber.h.gcov.html new file mode 100644 index 0000000000..bf721234d1 --- /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:1717100.0 %
Date:2024-06-10 08:19:14Functions: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      508219 : AtomNumber::AtomNumber() {
+      75      508171 :   index_=0;
+      76             : }
+      77             : 
+      78             : inline
+      79             : AtomNumber::AtomNumber(unsigned i) {
+      80             :   index_=i;
+      81             : }
+      82             : 
+      83             : inline
+      84             : unsigned AtomNumber::serial()const {
+      85      255646 :   return index_+1;
+      86             : }
+      87             : 
+      88             : inline
+      89             : unsigned AtomNumber::index()const {
+      90    33897702 :   return index_;
+      91             : }
+      92             : 
+      93             : inline
+      94      470622 : AtomNumber & AtomNumber::setSerial(unsigned i) {
+      95      470622 :   plumed_massert(i>0,"serial of an atom cannot be zero");
+      96      470622 :   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
+      97      470622 :   index_=i-1;
+      98      470622 :   return *this;
+      99             : }
+     100             : 
+     101             : inline
+     102             : AtomNumber & AtomNumber::setIndex(unsigned i) {
+     103          56 :   index_=i;
+     104             :   return *this;
+     105             : }
+     106             : 
+     107             : inline
+     108         696 : AtomNumber AtomNumber::serial(unsigned i) {
+     109         696 :   plumed_massert(i>0,"serial of an atom cannot be zero");
+     110         696 :   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
+     111         696 :   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   387873128 :   return a.index_<b.index_;
+     122             : }
+     123             : 
+     124             : inline
+     125             : bool operator>(const AtomNumber&a,const AtomNumber&b) {
+     126             :   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   169238549 :   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.15
+
+ + + 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 0000000000..0db2dd0c11 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.func.html b/coverage/tools/BiasRepresentation.cpp.func.html new file mode 100644 index 0000000000..fda5791c6a --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.gcov.html b/coverage/tools/BiasRepresentation.cpp.gcov.html new file mode 100644 index 0000000000..4bea308c74 --- /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-06-10 08:19:14Functions: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       10125 :     } 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.15
+
+ + + 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 0000000000..7c70f7c4f3 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.func.html b/coverage/tools/Brent1DRootSearch.h.func.html new file mode 100644 index 0000000000..009952a5f5 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.gcov.html b/coverage/tools/Brent1DRootSearch.h.gcov.html new file mode 100644 index 0000000000..d0b74be685 --- /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-06-10 08:19:14Functions: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        8929 :   for(unsigned iter=0; iter<ITMAX; iter++) {
+      88        8929 :     if ( (fb>0.0 && fc>0.0) || (fb<0.0 && fc<0.0) ) { cx=ax; fc=fa; e=d=bx-ax; }
+      89        8929 :     if( std::fabs(fc) < std::fabs(fb) ) { ax=bx; bx=cx; cx=ax; fa=fb; fb=fc; fc=fa; }
+      90        8929 :     tol1=2*EPS*std::fabs(bx)+0.5*tol; xm=0.5*(cx-bx);
+      91        8929 :     if( std::fabs(xm) <= tol1 || fb == 0.0 ) return bx;
+      92        7413 :     if( std::fabs(e) >= tol1 && std::fabs(fa) > std::fabs(fb) ) {
+      93        7349 :       s=fb/fa;
+      94        7349 :       if( ax==cx ) {
+      95        5192 :         p=2.0*xm*s; q=1.0-s;
+      96             :       } else {
+      97        2157 :         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        7349 :       if (p > 0.0) q = -q;
+     100        7349 :       p=std::fabs(p); min1=3.0*xm*q-std::fabs(tol1*q); min2=std::fabs(e*q);
+     101       14274 :       if (2.0*p < (min1 < min2 ? min1 : min2)) {
+     102        7090 :         e=d; d=p/q;
+     103             :       } else {
+     104             :         d=xm; e=d;
+     105             :       }
+     106             :     } else {
+     107             :       d=xm; e=d;
+     108             :     }
+     109        7413 :     ax=bx; fa=fb;
+     110        7413 :     if( std::fabs(d) > tol1 ) bx+=d;
+     111        1426 :     else if(xm<0 ) bx -= std::fabs(tol1); // SIGN(tol1,xm);
+     112         697 :     else bx += tol1;
+     113        7413 :     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.15
+
+ + + 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 0000000000..816532765f --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9Citations5emptyEv314
_ZN4PLMD9Citations5clearEv353
_ZN4PLMDlsERSoRKNS_9CitationsE916
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3576
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Citations.cpp.func.html b/coverage/tools/Citations.cpp.func.html new file mode 100644 index 0000000000..7b98dcde4b --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3576
_ZN4PLMD9Citations5clearEv353
_ZN4PLMDlsERSoRKNS_9CitationsE916
_ZNK4PLMD9Citations5emptyEv314
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Citations.cpp.gcov.html b/coverage/tools/Citations.cpp.gcov.html new file mode 100644 index 0000000000..892e8f2748 --- /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-06-10 08:19:14Functions: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        3576 : std::string Citations::cite(const std::string & item) {
+      30             :   unsigned i;
+      31       10037 :   for(i=0; i<items.size(); ++i) if(items[i]==item) break;
+      32        3576 :   if(i==items.size()) items.push_back(item);
+      33        3576 :   plumed_assert(i<items.size());
+      34             :   std::string ret;
+      35        3576 :   Tools::convert(i+1,ret);
+      36        7152 :   ret="["+ret+"]";
+      37        3576 :   return ret;
+      38             : }
+      39             : 
+      40         916 : std::ostream & operator<<(std::ostream &log,const Citations&cit) {
+      41        3845 :   for(unsigned i=0; i<cit.items.size(); ++i)
+      42        5858 :     log<<"  ["<<i+1<<"] "<<cit.items[i]<<"\n";
+      43         916 :   return log;
+      44             : }
+      45             : 
+      46         353 : void Citations::clear() {
+      47         353 :   items.clear();
+      48         353 : }
+      49             : 
+      50         314 : bool Citations::empty()const {
+      51         314 :   return items.empty();
+      52             : }
+      53             : 
+      54             : }
+      55             : 
+      56             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..0b54b66c15 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Citations.h.func.html b/coverage/tools/Citations.h.func.html new file mode 100644 index 0000000000..568ce0c711 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Citations.h.gcov.html b/coverage/tools/Citations.h.gcov.html new file mode 100644 index 0000000000..75f8f4bc7a --- /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-06-10 08:19:14Functions: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      404395 : 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.15
+
+ + + 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 0000000000..0ecb734ae2 --- /dev/null +++ b/coverage/tools/Communicator.cpp.func-sort-c.html @@ -0,0 +1,213 @@ + + + + + + + + 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:9912082.5 %
Date:2024-06-10 08:19:14Functions:283580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatoraSERKS0_0
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv24
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1195
_ZN4PLMD12Communicator8Get_commEv1578
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2074
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5838
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7589
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14902
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15302
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15302
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv43043
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv59470
_ZN4PLMD12CommunicatorD0Ev812643
_ZN4PLMD12CommunicatorC2Ev1218619
_ZN4PLMD12CommunicatorD2Ev1218619
_ZNK4PLMD12Communicator8Get_sizeEv2583746
_ZN4PLMD12Communicator3SumENS0_4DataE4283766
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv4516409
_ZNK4PLMD12Communicator7BarrierEv4521574
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4550365
_ZN4PLMD12Communicator5BcastENS0_4DataEi4797684
_ZNK4PLMD12Communicator8Get_rankEv6688343
_ZN4PLMD12Communicator11initializedEv24179933
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Communicator.cpp.func.html b/coverage/tools/Communicator.cpp.func.html new file mode 100644 index 0000000000..78fcde365f --- /dev/null +++ b/coverage/tools/Communicator.cpp.func.html @@ -0,0 +1,213 @@ + + + + + + + + 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:9912082.5 %
Date:2024-06-10 08:19:14Functions:283580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv24
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4550365
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv59470
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv43043
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv4516409
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator11initializedEv24179933
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator3SumENS0_4DataE4283766
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15302
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator5BcastENS0_4DataEi4797684
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15302
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14902
_ZN4PLMD12Communicator8Get_commEv1578
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2074
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1195
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5838
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatorC2Ev1218619
_ZN4PLMD12CommunicatorD0Ev812643
_ZN4PLMD12CommunicatorD2Ev1218619
_ZN4PLMD12CommunicatoraSERKS0_0
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7589
_ZNK4PLMD12Communicator7BarrierEv4521574
_ZNK4PLMD12Communicator8Get_rankEv6688343
_ZNK4PLMD12Communicator8Get_sizeEv2583746
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Communicator.cpp.gcov.html b/coverage/tools/Communicator.cpp.gcov.html new file mode 100644 index 0000000000..c9ad7623ee --- /dev/null +++ b/coverage/tools/Communicator.cpp.gcov.html @@ -0,0 +1,387 @@ + + + + + + + + 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:9912082.5 %
Date:2024-06-10 08:19:14Functions:283580.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 "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     1218619 : Communicator::Communicator()
+      32             : #ifdef __PLUMED_HAS_MPI
+      33     1218619 :   : communicator(MPI_COMM_SELF)
+      34             : #endif
+      35             : {
+      36     1218619 : }
+      37             : 
+      38           0 : Communicator::Communicator(const Communicator&pc) {
+      39           0 :   Set_comm(pc.communicator);
+      40           0 : }
+      41             : 
+      42             : Communicator::Status Communicator::StatusIgnore;
+      43             : 
+      44           0 : Communicator& Communicator::operator=(const Communicator&pc) {
+      45           0 :   if (this != &pc) {
+      46           0 :     Set_comm(pc.communicator);
+      47             :   }
+      48           0 :   return *this;
+      49             : }
+      50             : 
+      51     6688343 : int Communicator::Get_rank()const {
+      52     6688343 :   int r=0;
+      53             : #ifdef __PLUMED_HAS_MPI
+      54     6688343 :   if(initialized()) MPI_Comm_rank(communicator,&r);
+      55             : #endif
+      56     6688343 :   return r;
+      57             : }
+      58             : 
+      59     2583746 : int Communicator::Get_size()const {
+      60     2583746 :   int s=1;
+      61             : #ifdef __PLUMED_HAS_MPI
+      62     2583746 :   if(initialized()) MPI_Comm_size(communicator,&s);
+      63             : #endif
+      64     2583746 :   return s;
+      65             : }
+      66             : 
+      67        2074 : void Communicator::Set_comm(MPI_Comm c) {
+      68             : #ifdef __PLUMED_HAS_MPI
+      69        2074 :   if(initialized()) {
+      70        1665 :     if(communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      71        1665 :     if(c!=MPI_COMM_SELF) MPI_Comm_dup(c,&communicator);
+      72             :   }
+      73             : #else
+      74             :   (void) c;
+      75             : #endif
+      76        2074 : }
+      77             : 
+      78     2031262 : Communicator::~Communicator() {
+      79             : #ifdef __PLUMED_HAS_MPI
+      80     1218619 :   if(initialized() && communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      81             : #endif
+      82     2031262 : }
+      83             : 
+      84        1195 : void Communicator::Set_comm(const TypesafePtr & val) {
+      85             : #ifdef __PLUMED_HAS_MPI
+      86        1195 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+      87        2390 :   if(val) Set_comm(*(const MPI_Comm*)val.get<const void*>());
+      88             : #else
+      89             :   (void) val;
+      90             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+      91             : #endif
+      92        1195 : }
+      93             : 
+      94           0 : void Communicator::Set_fcomm(const TypesafePtr & val) {
+      95             : #ifdef __PLUMED_HAS_MPI
+      96           0 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+      97           0 :   if(val) {
+      98           0 :     MPI_Comm comm=MPI_Comm_f2c(*(const MPI_Fint*)val.get<const void*>());
+      99           0 :     Set_comm(comm);
+     100             :   }
+     101             : #else
+     102             :   (void) val;
+     103             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     104             : #endif
+     105           0 : }
+     106             : 
+     107           0 : void Communicator::Abort(int errorcode) {
+     108             : #ifdef __PLUMED_HAS_MPI
+     109           0 :   if(initialized()) {
+     110           0 :     MPI_Abort(communicator,errorcode);
+     111             :   }
+     112             : #endif
+     113           0 :   std::fprintf(stderr,"aborting with error code %d\n",errorcode);
+     114           0 :   std::abort();
+     115             : }
+     116             : 
+     117     4797684 : void Communicator::Bcast(Data data,int root) {
+     118             : #if defined(__PLUMED_HAS_MPI)
+     119     4797684 :   if(initialized()) MPI_Bcast(data.pointer,data.size,data.type,root,communicator);
+     120             : #else
+     121             :   (void) data;
+     122             :   (void) root;
+     123             : #endif
+     124     4797684 : }
+     125             : 
+     126     4283766 : void Communicator::Sum(Data data) {
+     127             : #if defined(__PLUMED_HAS_MPI)
+     128     4283766 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_SUM,communicator);
+     129             : #else
+     130             :   (void) data;
+     131             : #endif
+     132     4283766 : }
+     133             : 
+     134           3 : void Communicator::Prod(Data data) {
+     135             : #if defined(__PLUMED_HAS_MPI)
+     136           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_PROD,communicator);
+     137             : #else
+     138             :   (void) data;
+     139             : #endif
+     140           3 : }
+     141             : 
+     142         155 : void Communicator::Max(Data data) {
+     143             : #if defined(__PLUMED_HAS_MPI)
+     144         155 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MAX,communicator);
+     145             : #else
+     146             :   (void) data;
+     147             : #endif
+     148         155 : }
+     149             : 
+     150           3 : void Communicator::Min(Data data) {
+     151             : #if defined(__PLUMED_HAS_MPI)
+     152           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MIN,communicator);
+     153             : #else
+     154             :   (void) data;
+     155             : #endif
+     156           3 : }
+     157             : 
+     158       15302 : Communicator::Request Communicator::Isend(ConstData data,int source,int tag) {
+     159             :   Request req;
+     160             : #ifdef __PLUMED_HAS_MPI
+     161       15302 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     162       15302 :   void*s=const_cast<void*>((const void*)data.pointer);
+     163       15302 :   MPI_Isend(s,data.size,data.type,source,tag,communicator,&req.r);
+     164             : #else
+     165             :   (void) data;
+     166             :   (void) source;
+     167             :   (void) tag;
+     168             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     169             : #endif
+     170       15302 :   return req;
+     171             : }
+     172             : 
+     173       19063 : void Communicator::Allgatherv(ConstData in,Data out,const int*recvcounts,const int*displs) {
+     174       19063 :   void*s=const_cast<void*>((const void*)in.pointer);
+     175       19063 :   void*r=const_cast<void*>((const void*)out.pointer);
+     176             :   int*rc=const_cast<int*>(recvcounts);
+     177             :   int*di=const_cast<int*>(displs);
+     178             : #if defined(__PLUMED_HAS_MPI)
+     179       19063 :   if(initialized()) {
+     180       19062 :     if(s==NULL)s=MPI_IN_PLACE;
+     181       19062 :     MPI_Allgatherv(s,in.size,in.type,r,rc,di,out.type,communicator);
+     182             :   } else {
+     183           1 :     plumed_assert(in.nbytes==out.nbytes);
+     184           1 :     plumed_assert(in.size==out.size);
+     185           1 :     plumed_assert(rc);
+     186           1 :     plumed_assert(rc[0]==in.size);
+     187           1 :     plumed_assert(di);
+     188           1 :     if(s) std::memcpy(static_cast<char*>(r)+displs[0]*in.nbytes,s,size_t(in.size)*in.nbytes);
+     189             :   }
+     190             : #else
+     191             :   plumed_assert(in.nbytes==out.nbytes);
+     192             :   plumed_assert(in.size==out.size);
+     193             :   plumed_assert(rc);
+     194             :   plumed_assert(rc[0]==in.size);
+     195             :   plumed_assert(di);
+     196             :   if(s) std::memcpy(static_cast<char*>(r)+displs[0]*in.nbytes,s,size_t(in.size)*in.nbytes);
+     197             : #endif
+     198       19063 : }
+     199             : 
+     200        5838 : void Communicator::Allgather(ConstData in,Data out) {
+     201        5838 :   void*s=const_cast<void*>((const void*)in.pointer);
+     202        5838 :   void*r=const_cast<void*>((const void*)out.pointer);
+     203             : #if defined(__PLUMED_HAS_MPI)
+     204        5838 :   if(initialized()) {
+     205        5837 :     if(s==NULL)s=MPI_IN_PLACE;
+     206        5837 :     MPI_Allgather(s,in.size,in.type,r,out.size/Get_size(),out.type,communicator);
+     207             :   } else {
+     208           1 :     plumed_assert(in.nbytes==out.nbytes);
+     209           1 :     plumed_assert(in.size==out.size);
+     210           1 :     if(s) std::memcpy(r,s,size_t(in.size)*in.nbytes);
+     211             :   }
+     212             : #else
+     213             :   plumed_assert(in.nbytes==out.nbytes);
+     214             :   plumed_assert(in.size==out.size);
+     215             :   if(s) std::memcpy(r,s,size_t(in.size)*in.nbytes);
+     216             : #endif
+     217        5838 : }
+     218             : 
+     219       15302 : void Communicator::Recv(Data data,int source,int tag,Status&status) {
+     220             : #ifdef __PLUMED_HAS_MPI
+     221       15302 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     222       15302 :   if(&status==&StatusIgnore) MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,MPI_STATUS_IGNORE);
+     223        7589 :   else                       MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,&status.s);
+     224             : #else
+     225             :   (void) data;
+     226             :   (void) source;
+     227             :   (void) tag;
+     228             :   (void) status;
+     229             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     230             : #endif
+     231       15302 : }
+     232             : 
+     233     4521574 : void Communicator::Barrier()const {
+     234             : #ifdef __PLUMED_HAS_MPI
+     235     4521574 :   if(initialized()) MPI_Barrier(communicator);
+     236             : #endif
+     237     4521574 : }
+     238             : 
+     239        1578 : MPI_Comm & Communicator::Get_comm() {
+     240        1578 :   return communicator;
+     241             : }
+     242             : 
+     243    24179933 : bool Communicator::initialized() {
+     244             : #if defined(__PLUMED_HAS_MPI)
+     245    24179933 :   int flag=0;
+     246    24179933 :   MPI_Initialized(&flag);
+     247    24179933 :   if(flag) return true;
+     248    15062118 :   else return false;
+     249             : #endif
+     250             :   return false;
+     251             : }
+     252             : 
+     253       14902 : void Communicator::Request::wait(Status&s) {
+     254             : #ifdef __PLUMED_HAS_MPI
+     255       14902 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     256       14902 :   if(&s==&StatusIgnore) MPI_Wait(&r,MPI_STATUS_IGNORE);
+     257           1 :   else MPI_Wait(&r,&s.s);
+     258             : #else
+     259             :   (void) s;
+     260             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     261             : #endif
+     262       14902 : }
+     263             : 
+     264             : #ifdef __PLUMED_HAS_MPI
+     265           0 : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_FLOAT;}
+     266     4550365 : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_DOUBLE;}
+     267       59470 : template<> MPI_Datatype Communicator::getMPIType<int>()   { return MPI_INT;}
+     268         295 : template<> MPI_Datatype Communicator::getMPIType<char>()   { return MPI_CHAR;}
+     269       43043 : template<> MPI_Datatype Communicator::getMPIType<unsigned>()   { return MPI_UNSIGNED;}
+     270          24 : template<> MPI_Datatype Communicator::getMPIType<AtomNumber>()   { return MPI_UNSIGNED;}
+     271     4516409 : template<> MPI_Datatype Communicator::getMPIType<long unsigned>()   { return MPI_UNSIGNED_LONG;}
+     272           0 : template<> MPI_Datatype Communicator::getMPIType<long long unsigned>() { return MPI_UNSIGNED_LONG_LONG;}
+     273           0 : template<> MPI_Datatype Communicator::getMPIType<long double>()   { return MPI_LONG_DOUBLE;}
+     274             : #else
+     275             : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_Datatype();}
+     276             : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_Datatype();}
+     277             : template<> MPI_Datatype Communicator::getMPIType<int>() { return MPI_Datatype();}
+     278             : template<> MPI_Datatype Communicator::getMPIType<char>() { return MPI_Datatype();}
+     279             : template<> MPI_Datatype Communicator::getMPIType<unsigned>() { return MPI_Datatype();}
+     280             : template<> MPI_Datatype Communicator::getMPIType<AtomNumber>()   { return MPI_Datatype();}
+     281             : template<> MPI_Datatype Communicator::getMPIType<long unsigned>() { return MPI_Datatype();}
+     282             : template<> MPI_Datatype Communicator::getMPIType<long long unsigned>() { return MPI_Datatype();}
+     283             : template<> MPI_Datatype Communicator::getMPIType<long double>() { return MPI_Datatype();}
+     284             : #endif
+     285             : 
+     286         406 : void Communicator::Split(int color,int key,Communicator&pc)const {
+     287             : #ifdef __PLUMED_HAS_MPI
+     288         406 :   MPI_Comm_split(communicator,color,key,&pc.communicator);
+     289             : #else
+     290             :   (void) color;
+     291             :   (void) key;
+     292             :   (void) pc;
+     293             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     294             : #endif
+     295         406 : }
+     296             : 
+     297        7589 : int Communicator::Status::Get_count(MPI_Datatype type)const {
+     298             :   int i;
+     299             : #ifdef __PLUMED_HAS_MPI
+     300        7589 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     301        7589 :   MPI_Get_count(const_cast<MPI_Status*>(&s),type,&i);
+     302             : #else
+     303             :   i=0;
+     304             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     305             : #endif
+     306        7589 :   return i;
+     307             : }
+     308             : 
+     309             : }
+     310             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9add9979e2 --- /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-06-10 08:19:14Functions: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
_ZN4PLMD12Communicator5BcastISt6vectorImSaImEEEEvRT_i2
_ZN4PLMD12Communicator9AllgatherImSt6vectorImSaImEEEEvRKT_RT0_2
_ZN4PLMD12Communicator4DataC2ImEERSt6vectorIT_SaIS4_EE4
_ZN4PLMD12Communicator3SumISt6vectorINS_13TensorGenericILj3ELj3EEESaIS4_EEEEvRT_16
_ZN4PLMD12Communicator4DataC2INS_13TensorGenericILj3ELj3EEEEERSt6vectorIT_SaIS6_EE16
_ZN4PLMD12Communicator3SumINS_6MatrixIdEEEEvRT_17
_ZN4PLMD12Communicator4DataC2IdEERNS_6MatrixIT_EE17
_ZN4PLMD12Communicator4DataC2INS_10AtomNumberEEERSt6vectorIT_SaIS5_EE24
_ZN4PLMD12Communicator5BcastISt6vectorINS_10AtomNumberESaIS3_EEEEvRT_i24
_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
_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
_ZN4PLMD12Communicator3SumIjEEvPT_i489
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator9AllgatherISt6vectorIdSaIdEES4_EEvRKT_RT0_580
_ZN4PLMD12Communicator9ConstDataC2IdEERKSt6vectorIT_SaIS4_EE582
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE861
_ZN4PLMD12Communicator3SumIjEEvRT_1082
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_3488
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE3834
_ZN4PLMD12Communicator9AllgatherIdSt6vectorIdSaIdEEEEvRKT_RT0_4777
_ZN4PLMD12Communicator4RecvIdEEvPT_iiiRNS0_6StatusE7588
_ZN4PLMD12Communicator4RecvIiEEvPT_iiiRNS0_6StatusE7588
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestEPKT_iii7588
_ZN4PLMD12Communicator5IsendIiEENS0_7RequestEPKT_iii7588
_ZNK4PLMD12Communicator6Status9Get_countIiEEiv7588
_ZN4PLMD12Communicator3SumISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEEvRT_11179
_ZN4PLMD12Communicator4DataC2INS_13VectorGenericILj3EEEEERSt6vectorIT_SaIS6_EE11179
_ZN4PLMD12Communicator5BcastIiEEvRT_i15136
_ZN4PLMD12Communicator10AllgathervIjjEEvPKT_iPT0_PKiS8_18459
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumINS_13TensorGenericILj3ELj3EEEEEvRT_19986
_ZN4PLMD12Communicator5BcastINS_13TensorGenericILj3ELj3EEEEEvRT_i21725
_ZN4PLMD12Communicator3SumIdEEvPT_i68236
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i242644
_ZN4PLMD12Communicator3SumIdEEvRT_2033708
_ZN4PLMD12Communicator3SumISt6vectorIdSaIdEEEEvRT_2125726
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2373729
_ZN4PLMD12Communicator5BcastImEEvRT_i4516403
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Communicator.h.func.html b/coverage/tools/Communicator.h.func.html new file mode 100644 index 0000000000..3376ec58c3 --- /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-06-10 08:19:14Functions: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_19986
_ZN4PLMD12Communicator3SumINS_6MatrixIdEEEEvRT_17
_ZN4PLMD12Communicator3SumISt6vectorINS_13TensorGenericILj3ELj3EEESaIS4_EEEEvRT_16
_ZN4PLMD12Communicator3SumISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEEvRT_11179
_ZN4PLMD12Communicator3SumISt6vectorIdSaIdEEEEvRT_2125726
_ZN4PLMD12Communicator3SumISt6vectorIfSaIfEEEEvRT_0
_ZN4PLMD12Communicator3SumISt6vectorIiSaIiEEEEvRT_150
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_3488
_ZN4PLMD12Communicator3SumIdEEvPT_i68236
_ZN4PLMD12Communicator3SumIdEEvRT_2033708
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumIiEEvRT_204
_ZN4PLMD12Communicator3SumIjEEvPT_i489
_ZN4PLMD12Communicator3SumIjEEvRT_1082
_ZN4PLMD12Communicator4DataC2ERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE61
_ZN4PLMD12Communicator4DataC2INS_10AtomNumberEEERSt6vectorIT_SaIS5_EE24
_ZN4PLMD12Communicator4DataC2INS_13TensorGenericILj3ELj3EEEEERSt6vectorIT_SaIS6_EE16
_ZN4PLMD12Communicator4DataC2INS_13VectorGenericILj3EEEEERSt6vectorIT_SaIS6_EE11179
_ZN4PLMD12Communicator4DataC2IdEERNS_6MatrixIT_EE17
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2373729
_ZN4PLMD12Communicator4DataC2IfEERSt6vectorIT_SaIS4_EE0
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE861
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE3834
_ZN4PLMD12Communicator4DataC2ImEERSt6vectorIT_SaIS4_EE4
_ZN4PLMD12Communicator4RecvISt6vectorIcSaIcEEEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIdEEvPT_iiiRNS0_6StatusE7588
_ZN4PLMD12Communicator4RecvIdEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIiEEvPT_iiiRNS0_6StatusE7588
_ZN4PLMD12Communicator5BcastINS_13TensorGenericILj3ELj3EEEEEvRT_i21725
_ZN4PLMD12Communicator5BcastINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_i61
_ZN4PLMD12Communicator5BcastISt6vectorINS_10AtomNumberESaIS3_EEEEvRT_i24
_ZN4PLMD12Communicator5BcastISt6vectorIcSaIcEEEEvRT_i114
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i242644
_ZN4PLMD12Communicator5BcastISt6vectorIfSaIfEEEEvRT_i0
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator5BcastISt6vectorIjSaIjEEEEvRT_i56
_ZN4PLMD12Communicator5BcastISt6vectorImSaImEEEEvRT_i2
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator5BcastIiEEvRT_i15136
_ZN4PLMD12Communicator5BcastIjEEvRT_i430
_ZN4PLMD12Communicator5BcastImEEvRT_i4516403
_ZN4PLMD12Communicator5IsendINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestEPKT_iii7588
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIiEENS0_7RequestEPKT_iii7588
_ZN4PLMD12Communicator9AllgatherISt6vectorIdSaIdEES4_EEvRKT_RT0_580
_ZN4PLMD12Communicator9AllgatherIdSt6vectorIdSaIdEEEEvRKT_RT0_4777
_ZN4PLMD12Communicator9AllgatherIiSt6vectorIiSaIiEEEEvRKT_RT0_131
_ZN4PLMD12Communicator9AllgatherIiiEEvPKT_iPT0_i204
_ZN4PLMD12Communicator9AllgatherIjSt6vectorIjSaIjEEEEvRKT_RT0_140
_ZN4PLMD12Communicator9AllgatherImSt6vectorImSaImEEEEvRKT_RT0_2
_ZN4PLMD12Communicator9ConstDataC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD12Communicator9ConstDataC2IdEERKSt6vectorIT_SaIS4_EE582
_ZN4PLMD12Communicator9ConstDataC2IjEERKSt6vectorIT_SaIS4_EE150
_ZNK4PLMD12Communicator6Status9Get_countIiEEiv7588
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Communicator.h.gcov.html b/coverage/tools/Communicator.h.gcov.html new file mode 100644 index 0000000000..423bcec973 --- /dev/null +++ b/coverage/tools/Communicator.h.gcov.html @@ -0,0 +1,326 @@ + + + + + + + + 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-06-10 08:19:14Functions: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     2615460 :     template <typename T> Data(T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+      73             : /// Init from reference
+      74    13135344 :     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       83422 :     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     2389647 :     template <typename T> explicit Data(std::vector<T>&v) {
+      85     2389818 :       Data d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
+      86     2389647 :     }
+      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             : /// Wrapper class for MPI_Status
+     125             :   class Status {
+     126             :     int Get_count(MPI_Datatype)const;
+     127             :   public:
+     128             :     MPI_Status s;
+     129             :     template <class T>
+     130        7588 :     int Get_count()const {return Get_count(getMPIType<T>());}
+     131             :   };
+     132             : /// Special status used when status should be ignored.
+     133             : /// E.g. `Recv(a,0,1,Communicator::StatusIgnore);`
+     134             : /// Notice that this is the default for Recv, so this is equivalent to
+     135             : /// `Recv(a,0,1);`
+     136             :   static Status StatusIgnore;
+     137             : /// Wrapper class for MPI_Request
+     138             :   class Request {
+     139             :   public:
+     140             :     MPI_Request r;
+     141             :     void wait(Status&s=StatusIgnore);
+     142             :   };
+     143             : /// Default constructor
+     144             :   Communicator();
+     145             : /// Copy constructor.
+     146             : /// It effectively "clones" the communicator, providing a new one acting on the same group
+     147             :   Communicator(const Communicator&);
+     148             : /// Assignment operator.
+     149             : /// It effectively "clones" the communicator, providing a new one acting on the same group
+     150             :   Communicator& operator=(const Communicator&);
+     151             : /// Destructor
+     152             :   virtual ~Communicator();
+     153             : /// Obtain the rank of the present process
+     154             :   int Get_rank()const;
+     155             : /// Obtain the number of processes
+     156             :   int Get_size()const;
+     157             : /// Set from a real MPI communicator.
+     158             : /// \param comm MPI communicator
+     159             :   void Set_comm(MPI_Comm comm);
+     160             : /// Reference to MPI communicator
+     161             :   MPI_Comm & Get_comm();
+     162             : /// Set from a pointer to a real MPI communicator (C).
+     163             : /// \param comm Pointer to a C MPI communicator
+     164             :   void Set_comm(const TypesafePtr & comm);
+     165             : /// Set from a pointer to a real MPI communicator (FORTRAN).
+     166             : /// \param comm Pointer to a FORTRAN MPI communicator (INTEGER)
+     167             :   void Set_fcomm(const TypesafePtr & comm);
+     168             : /// Wrapper to MPI_Abort.
+     169             : /// \param code Error code
+     170             :   void Abort(int code);
+     171             : /// Wrapper to MPI_Barrier
+     172             :   void Barrier()const;
+     173             : /// Tests if MPI library is initialized
+     174             :   static bool initialized();
+     175             : /// Wrapper for MPI_Allreduce with MPI_SUM (data struct)
+     176             :   void Sum(Data);
+     177             : /// Wrapper for MPI_Allreduce with MPI_SUM (pointer)
+     178       88206 :   template <class T> void Sum(T*buf,int count) {Sum(Data(buf,count));}
+     179             : /// Wrapper for MPI_Allreduce with MPI_SUM (reference)
+     180     4195556 :   template <class T> void Sum(T&buf) {Sum(Data(buf));}
+     181             : /// Wrapper for MPI_Allreduce with MPI_PROD (data struct)
+     182             :   void Prod(Data);
+     183             : /// Wrapper for MPI_Allreduce with MPI_PROD (pointer)
+     184             :   template <class T> void Prod(T*buf,int count) {Prod(Data(buf,count));}
+     185             : /// Wrapper for MPI_Allreduce with MPI_PROD (reference)
+     186             :   template <class T> void Prod(T&buf) {Prod(Data(buf));}
+     187             : /// Wrapper for MPI_Allreduce with MPI_MAX (data struct)
+     188             :   void Max(Data);
+     189             : /// Wrapper for MPI_Allreduce with MPI_MAX (pointer)
+     190             :   template <class T> void Max(T*buf,int count) {Max(Data(buf,count));}
+     191             : /// Wrapper for MPI_Allreduce with MPI_MAX (reference)
+     192         152 :   template <class T> void Max(T&buf) {Max(Data(buf));}
+     193             : /// Wrapper for MPI_Allreduce with MPI_MIN (data struct)
+     194             :   void Min(Data);
+     195             : /// Wrapper for MPI_Allreduce with MPI_MIN (pointer)
+     196             :   template <class T> void Min(T*buf,int count) {Min(Data(buf,count));}
+     197             : /// Wrapper for MPI_Allreduce with MPI_MIN (reference)
+     198           0 :   template <class T> void Min(T&buf) {Min(Data(buf));}
+     199             : 
+     200             : /// Wrapper for MPI_Bcast (data struct)
+     201             :   void Bcast(Data,int);
+     202             : /// Wrapper for MPI_Bcast (pointer)
+     203             :   template <class T> void Bcast(T*buf,int count,int root) {Bcast(Data(buf,count),root);}
+     204             : /// Wrapper for MPI_Bcast (reference)
+     205     4797675 :   template <class T> void Bcast(T&buf,int root) {Bcast(Data(buf),root);}
+     206             : 
+     207             : /// Wrapper for MPI_Isend (data struct)
+     208             :   Request Isend(ConstData,int,int);
+     209             : /// Wrapper for MPI_Isend (pointer)
+     210       15176 :   template <class T> Request Isend(const T*buf,int count,int source,int tag) {return Isend(ConstData(buf,count),source,tag);}
+     211             : /// Wrapper for MPI_Isend (reference)
+     212         114 :   template <class T> Request Isend(const T&buf,int source,int tag) {return Isend(ConstData(buf),source,tag);}
+     213             : 
+     214             : /// Wrapper for MPI_Allgatherv (data struct)
+     215             :   void Allgatherv(ConstData in,Data out,const int*,const int*);
+     216             : /// Wrapper for MPI_Allgatherv (pointer)
+     217       18907 :   template <class T,class S> void Allgatherv(const T*sendbuf,int sendcount,S*recvbuf,const int*recvcounts,const int*displs) {
+     218       18907 :     Allgatherv(ConstData(sendbuf,sendcount),Data(recvbuf,0),recvcounts,displs);
+     219       18907 :   }
+     220             : /// Wrapper for MPI_Allgatherv (reference)
+     221         152 :   template <class T,class S> void Allgatherv(const T&sendbuf,S&recvbuf,const int*recvcounts,const int*displs) {
+     222         152 :     Allgatherv(ConstData(sendbuf),Data(recvbuf),recvcounts,displs);
+     223         152 :   }
+     224             : 
+     225             : /// Wrapper for MPI_Allgather (data struct)
+     226             :   void Allgather(ConstData in,Data out);
+     227             : /// Wrapper for MPI_Allgatherv (pointer)
+     228         204 :   template <class T,class S> void Allgather(const T*sendbuf,int sendcount,S*recvbuf,int recvcount) {
+     229         408 :     Allgather(ConstData(sendbuf,sendcount),Data(recvbuf,recvcount*Get_size()));
+     230         204 :   }
+     231             : /// Wrapper for MPI_Allgatherv (reference)
+     232        5630 :   template <class T,class S> void Allgather(const T&sendbuf,S&recvbuf) {
+     233       10680 :     Allgather(ConstData(sendbuf),Data(recvbuf));
+     234        5630 :   }
+     235             : 
+     236             : /// Wrapper for MPI_Recv (data struct)
+     237             :   void Recv(Data,int,int,Status&s=StatusIgnore);
+     238             : /// Wrapper for MPI_Recv (pointer)
+     239       15176 :   template <class T> void Recv(T*buf,int count,int source,int tag,Status&s=StatusIgnore) {Recv(Data(buf,count),source,tag,s);}
+     240             : /// Wrapper for MPI_Recv (reference)
+     241         114 :   template <class T> void Recv(T&buf,int source,int tag,Status&s=StatusIgnore) {Recv(Data(buf),source,tag,s);}
+     242             : 
+     243             : /// Wrapper to MPI_Comm_split
+     244             :   void Split(int,int,Communicator&)const;
+     245             : };
+     246             : 
+     247             : }
+     248             : 
+     249             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..28ea9824a9 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.func.html b/coverage/tools/ConjugateGradient.h.func.html new file mode 100644 index 0000000000..ce8da99a46 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.gcov.html b/coverage/tools/ConjugateGradient.h.gcov.html new file mode 100644 index 0000000000..030a8aa771 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..c18c4334f5 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + 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:172181.0 %
Date:2024-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader5errorB5cxx11Ev0
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD8DLLoader9installedEv2
_ZN4PLMD8DLLoaderC2Ev407840
_ZN4PLMD8DLLoaderD2Ev407840
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.func.html b/coverage/tools/DLLoader.cpp.func.html new file mode 100644 index 0000000000..6ff5f0a127 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + 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:172181.0 %
Date:2024-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD8DLLoader5errorB5cxx11Ev0
_ZN4PLMD8DLLoader9installedEv2
_ZN4PLMD8DLLoaderC2Ev407840
_ZN4PLMD8DLLoaderD2Ev407840
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.gcov.html b/coverage/tools/DLLoader.cpp.gcov.html new file mode 100644 index 0000000000..2dcc989d09 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + + 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:172181.0 %
Date:2024-06-10 08:19:14Functions: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 "DLLoader.h"
+      23             : #include <cstdlib>
+      24             : 
+      25             : #ifdef __PLUMED_HAS_DLOPEN
+      26             : #include <dlfcn.h>
+      27             : #endif
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31           2 : bool DLLoader::installed() {
+      32             : #ifdef __PLUMED_HAS_DLOPEN
+      33           2 :   return true;
+      34             : #else
+      35             :   return false;
+      36             : #endif
+      37             : }
+      38             : 
+      39             : 
+      40           1 : void* DLLoader::load(const std::string&s) {
+      41             : #ifdef __PLUMED_HAS_DLOPEN
+      42           1 :   void* p=dlopen(s.c_str(),RTLD_NOW|RTLD_LOCAL);
+      43           1 :   if(!p) {
+      44           0 :     lastError=dlerror();
+      45             :   } else {
+      46           1 :     lastError="";
+      47             :     handles.push(p);
+      48             :   }
+      49           1 :   return p;
+      50             : #else
+      51             :   return NULL;
+      52             : #endif
+      53             : }
+      54             : 
+      55           0 : const std::string & DLLoader::error() {
+      56           0 :   return lastError;
+      57             : }
+      58             : 
+      59      407840 : DLLoader::~DLLoader() {
+      60      407840 :   auto debug=std::getenv("PLUMED_LOAD_DEBUG");
+      61      407840 :   if(debug) std::fprintf(stderr,"delete dlloader\n");
+      62             : #ifdef __PLUMED_HAS_DLOPEN
+      63      407841 :   while(!handles.empty()) {
+      64           1 :     int ret=dlclose(handles.top());
+      65           1 :     if(ret) {
+      66           0 :       std::fprintf(stderr,"+++ error reported by dlclose: %s\n",dlerror());
+      67             :     }
+      68             :     handles.pop();
+      69             :   }
+      70             : #endif
+      71      407840 :   if(debug) std::fprintf(stderr,"end delete dlloader\n");
+      72      407840 : }
+      73             : 
+      74      407840 : DLLoader::DLLoader() {
+      75             :   // do nothing
+      76      407840 : }
+      77             : 
+      78             : 
+      79             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9413df93c3 --- /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-06-10 08:19:14Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11DynamicListIjE14addIndexToListERKj91
_ZN4PLMD11DynamicListIjE5clearEv41854
_ZN4PLMD11DynamicListIjE14sortActiveListEv56305
_ZN4PLMD11DynamicListIjE19updateActiveMembersEv62072
_ZN4PLMD11DynamicListIjE25createIndexListFromVectorERKSt6vectorIjSaIjEE402085
_ZN4PLMD11DynamicListIjE14completeUpdateEv876487
_ZN4PLMD11DynamicListIjE18emptyActiveMembersEv932792
_ZN4PLMD11DynamicListIjE13deactivateAllEv2098930
_ZNK4PLMD11DynamicListIjE14updateCompleteEv4878569
_ZNK4PLMD11DynamicListIjE15getNumberActiveEv54364606
_ZN4PLMD11DynamicListIjE21putIndexInActiveArrayERKj77407190
_ZNK4PLMD11DynamicListIjE8isActiveERKj424151148
_ZN4PLMD11DynamicListIjE8activateEj1544105863
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/DynamicList.h.func.html b/coverage/tools/DynamicList.h.func.html new file mode 100644 index 0000000000..c3d9b58d72 --- /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-06-10 08:19:14Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11DynamicListIjE13deactivateAllEv2098930
_ZN4PLMD11DynamicListIjE14addIndexToListERKj91
_ZN4PLMD11DynamicListIjE14completeUpdateEv876487
_ZN4PLMD11DynamicListIjE14sortActiveListEv56305
_ZN4PLMD11DynamicListIjE18emptyActiveMembersEv932792
_ZN4PLMD11DynamicListIjE19updateActiveMembersEv62072
_ZN4PLMD11DynamicListIjE21putIndexInActiveArrayERKj77407190
_ZN4PLMD11DynamicListIjE25createIndexListFromVectorERKSt6vectorIjSaIjEE402085
_ZN4PLMD11DynamicListIjE5clearEv41854
_ZN4PLMD11DynamicListIjE8activateEj1544105863
_ZNK4PLMD11DynamicListIjE14updateCompleteEv4878569
_ZNK4PLMD11DynamicListIjE15getNumberActiveEv54364606
_ZNK4PLMD11DynamicListIjE8isActiveERKj424151148
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/DynamicList.h.gcov.html b/coverage/tools/DynamicList.h.gcov.html new file mode 100644 index 0000000000..89c8e55a0c --- /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-06-10 08:19:14Functions: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      360232 :   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   642995410 :     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       41854 : void DynamicList<T>::clear() {
+     219       41854 :   all.resize(0);
+     220       41854 :   onoff.resize(0); active.resize(0);
+     221       41854 : }
+     222             : 
+     223             : template <typename T>
+     224   424151148 : bool DynamicList<T>::isActive( const unsigned& i ) const {
+     225   424151148 :   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    54364606 : unsigned DynamicList<T>::getNumberActive() const {
+     235    54364606 :   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      402085 : void DynamicList<T>::createIndexListFromVector( const std::vector<T>& myind ) {
+     245      402085 :   plumed_dbg_assert( all.size()==0 ); onoff.resize( myind.size(), 0 );
+     246      402085 :   active.resize( myind.size() );
+     247      402085 :   all.insert( all.end(), myind.begin(), myind.end() );
+     248      402085 : }
+     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     2098930 : void DynamicList<T>::deactivateAll() {
+     275     2098930 :   allWereDeactivated=true; allWereActivated=false;
+     276    82073774 :   for(unsigned i=0; i<nactive; ++i) onoff[ active[i] ]= 0;
+     277     2098930 :   nactive=0;
+     278             : #ifndef NDEBUG
+     279             :   for(unsigned i=0; i<onoff.size(); ++i) plumed_dbg_assert( onoff[i]==0 );
+     280             : #endif
+     281     2098930 : }
+     282             : 
+     283             : template <typename T>
+     284  1544105863 : 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  1544105863 :   onoff[ii]=nprocessors;
+     288  1544105863 : }
+     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      932792 : void DynamicList<T>::emptyActiveMembers() {
+     318             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     319      932792 :   nactive=0;
+     320      932792 : }
+     321             : 
+     322             : template <typename T>
+     323    77407190 : 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    77407190 :   active[nactive]=ii; nactive++;
+     327    77407190 : }
+     328             : 
+     329             : template <typename T>
+     330      876487 : void DynamicList<T>::completeUpdate() {
+     331             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     332      876487 :   allWereActivated=allWereDeactivated=false;
+     333      876487 : }
+     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     4878569 : bool DynamicList<T>::updateComplete() const {
+     344     4878569 :   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.15
+
+ + + 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 0000000000..b002e08893 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.func.html b/coverage/tools/ERMSD.cpp.func.html new file mode 100644 index 0000000000..63fd7f37a2 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.gcov.html b/coverage/tools/ERMSD.cpp.gcov.html new file mode 100644 index 0000000000..84c8fc20ba --- /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-06-10 08:19:14Functions: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           8 : }
+      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       16046 :     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       16046 :     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       16046 :     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.15
+
+ + + 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 0000000000..8e822e9281 --- /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:11100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/ERMSD.h.func.html b/coverage/tools/ERMSD.h.func.html new file mode 100644 index 0000000000..832ab17006 --- /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:11100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/ERMSD.h.gcov.html b/coverage/tools/ERMSD.h.gcov.html new file mode 100644 index 0000000000..ace72254c5 --- /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:11100.0 %
Date:2024-06-10 08:19:14Functions: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             : 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.15
+
+ + + 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 0000000000..774b6e584d --- /dev/null +++ b/coverage/tools/Exception.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + 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:3333100.0 %
Date:2024-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE9
_ZN4PLMD9ExceptionlsERKNS0_8LocationE54
_ZN4PLMD9ExceptionC2Ev65
_ZNK4PLMD9Exception5stackEv65
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE98
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Exception.cpp.func.html b/coverage/tools/Exception.cpp.func.html new file mode 100644 index 0000000000..2d973990d6 --- /dev/null +++ b/coverage/tools/Exception.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + 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:3333100.0 %
Date:2024-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ExceptionC2Ev65
_ZN4PLMD9ExceptionlsERKNS0_8LocationE54
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE9
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE98
_ZNK4PLMD9Exception5stackEv65
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Exception.cpp.gcov.html b/coverage/tools/Exception.cpp.gcov.html new file mode 100644 index 0000000000..fe2679518e --- /dev/null +++ b/coverage/tools/Exception.cpp.gcov.html @@ -0,0 +1,177 @@ + + + + + + + + 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:3333100.0 %
Date:2024-06-10 08:19:14Functions: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 "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             : 
+      32             : namespace PLMD {
+      33             : 
+      34          65 : Exception::Exception()
+      35             : {
+      36             :   callstack.fill(nullptr);
+      37             : #ifdef __PLUMED_HAS_EXECINFO
+      38          65 :   callstack_n = backtrace(&callstack[0], callstack.size()-1);
+      39          65 :   const char* env=std::getenv("PLUMED_STACK_TRACE");
+      40          65 :   if(env && !std::strcmp(env,"yes")) {
+      41             :     msg+="\n\n********** STACK DUMP **********\n";
+      42          65 :     msg+=stack();
+      43             :     msg+="\n********** END STACK DUMP **********\n";
+      44             :   }
+      45             : #endif
+      46             :   msg+="\n+++ PLUMED error";
+      47          65 : }
+      48             : 
+      49          98 : Exception& Exception::operator<<(const std::string&msg)
+      50             : {
+      51          98 :   if(msg.length()>0) {
+      52          98 :     if(note) this->msg +="\n+++ message follows +++\n";
+      53          98 :     this->msg +=msg;
+      54          98 :     note=false;
+      55             :   }
+      56          98 :   return *this;
+      57             : }
+      58             : 
+      59          54 : Exception& Exception::operator<<(const Location&loc)
+      60             : {
+      61          54 :   if(loc.file) {
+      62             :     char cline[1000];
+      63          54 :     std::sprintf(cline,"%u",loc.line);
+      64          54 :     this->msg += "\n+++ at ";
+      65          54 :     this->msg += loc.file;
+      66             :     this->msg += ":";
+      67             :     this->msg += cline;
+      68          54 :     if(loc.pretty && loc.pretty[0]) {
+      69             :       this->msg += ", function ";
+      70          54 :       this->msg += loc.pretty;
+      71             :     }
+      72             :   }
+      73          54 :   note=true;
+      74          54 :   return *this;
+      75             : }
+      76             : 
+      77           9 : Exception& Exception::operator<<(const Assertion&as)
+      78             : {
+      79           9 :   if(as.assertion) {
+      80           9 :     this->msg += "\n+++ assertion failed: ";
+      81           9 :     this->msg += as.assertion;
+      82             :   }
+      83           9 :   note=true;
+      84           9 :   return *this;
+      85             : }
+      86             : 
+      87          65 : const char* Exception::stack() const {
+      88             : #ifdef __PLUMED_HAS_EXECINFO
+      89          65 :   if(stackTrace.length()==0) {
+      90          65 :     char** strs = backtrace_symbols(&callstack[0], callstack_n);
+      91         987 :     for (int i = 0; i < callstack_n; ++i) {stackTrace+=strs[i]; stackTrace+="\n";}
+      92          65 :     free(strs);
+      93             :   }
+      94             : #endif
+      95          65 :   return stackTrace.c_str();
+      96             : }
+      97             : 
+      98             : }
+      99             : 
+     100             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..d3fcee142a --- /dev/null +++ b/coverage/tools/Exception.h.func-sort-c.html @@ -0,0 +1,609 @@ + + + + + + + + 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:3030100.0 %
Date:2024-06-10 08:19:14Functions:2013414.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_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
_ZN4PLMD9ExceptionlsIA23_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA24_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA256_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA25_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA26_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA27_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA28_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA29_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA31_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
_ZN4PLMD9ExceptionlsIA3_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
_ZN4PLMD9ExceptionlsIA61_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA62_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA63_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA64_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA65_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA66_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
_ZN4PLMD9ExceptionlsIA89_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
_ZN4PLMD9ExceptionlsIA95_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA96_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA98_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj3ELj3EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj4ELj4EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsIdEERS0_RKT_0
_ZN4PLMD9ExceptionlsIiEERS0_RKT_0
_ZN4PLMD9ExceptionlsIjEERS0_RKT_0
_ZN4PLMD9ExceptionlsIlEERS0_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
_ZN4PLMD9ExceptionlsIPKcEERS0_RKT_1
_ZN4PLMD9ExceptionlsIPcEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA18_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA19_cEERS0_RKT_2
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD9ExceptionlsIA60_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA30_cEERS0_RKT_4
_ZN4PLMD9ExceptionlsImEERS0_RKT_4
_ZN4PLMD9ExceptionlsIA50_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsIA9_cEERS0_RKT_5
_ZN4PLMD9ExceptionC2ERKS0_11
_ZNK4PLMD9Exception4whatEv15
_ZN4PLMD9ExceptionD2Ev22
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Exception.h.func.html b/coverage/tools/Exception.h.func.html new file mode 100644 index 0000000000..37e020f12a --- /dev/null +++ b/coverage/tools/Exception.h.func.html @@ -0,0 +1,609 @@ + + + + + + + + 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:3030100.0 %
Date:2024-06-10 08:19:14Functions:2013414.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD9ExceptionC2ERKS0_11
_ZN4PLMD9ExceptionD0Ev0
_ZN4PLMD9ExceptionD2Ev22
_ZN4PLMD9ExceptionlsIA100_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA102_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA103_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA104_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA105_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA108_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_0
_ZN4PLMD9ExceptionlsIA24_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA256_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA25_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA26_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA27_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA28_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA29_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA2_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA30_cEERS0_RKT_4
_ZN4PLMD9ExceptionlsIA31_cEERS0_RKT_0
_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_0
_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_3
_ZN4PLMD9ExceptionlsIA61_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA62_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA63_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA64_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA65_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA66_cEERS0_RKT_0
_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_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
_ZN4PLMD9ExceptionlsIA95_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA96_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA98_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA9_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj3ELj3EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj4ELj4EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsIPKcEERS0_RKT_1
_ZN4PLMD9ExceptionlsIPcEERS0_RKT_1
_ZN4PLMD9ExceptionlsIdEERS0_RKT_0
_ZN4PLMD9ExceptionlsIiEERS0_RKT_0
_ZN4PLMD9ExceptionlsIjEERS0_RKT_0
_ZN4PLMD9ExceptionlsIlEERS0_RKT_0
_ZN4PLMD9ExceptionlsImEERS0_RKT_4
_ZNK4PLMD9Exception4whatEv15
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Exception.h.gcov.html b/coverage/tools/Exception.h.gcov.html new file mode 100644 index 0000000000..585d97cc44 --- /dev/null +++ b/coverage/tools/Exception.h.gcov.html @@ -0,0 +1,446 @@ + + + + + + + + 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:3030100.0 %
Date:2024-06-10 08:19:14Functions:2013414.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             : #ifndef __PLUMED_tools_Exception_h
+      23             : #define __PLUMED_tools_Exception_h
+      24             : 
+      25             : #include <string>
+      26             : #include <stdexcept>
+      27             : #include <sstream>
+      28             : #include <array>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : /**
+      33             : \ingroup TOOLBOX
+      34             : Class to deal with Plumed runtime errors.
+      35             : 
+      36             : This class and the related macros can be used to detect programming
+      37             : errors. Typical cases are internal inconsistencies or errors in the plumed<->MD
+      38             : interface. Mistakes made by final users (i.e. in the `plumed.dat` file)
+      39             : should probably be documented in some better way (e.g. printing parts of the manual in the output).
+      40             : However, also this class allows for significant information to be attached.
+      41             : Let's try to make error messages as informative as possible!
+      42             : 
+      43             : \note This class has been rewritten in PLUMED 2.5. It works in a backward compatible manner,
+      44             : but is much more flexible. The main novelty is that we can use insertion operators to
+      45             : add arbitrary messages, as in `plumed_error()<<"check this vector "<<v;`
+      46             : See below for more details.
+      47             : 
+      48             : To throw an error, just throw a c++ exception
+      49             : \verbatim
+      50             :   if(something_bad) throw Exception();
+      51             : \endverbatim
+      52             : or better add an error message to that
+      53             : \verbatim
+      54             :   if(something_bad) throw Exception("describe the error here");
+      55             : \endverbatim
+      56             : 
+      57             : As of PLUMED 2.5 you can add multiple messages, they will just be concatenated,
+      58             : but to do se you should use the insertion operator. Notice that anything that
+      59             : can be formatted with an insertion operator can go to the exception, even a \ref Vector
+      60             : \verbatim
+      61             :   Vector v;
+      62             :   if(something_bad) throw Exception()<<"problem with this "<<v;
+      63             : \endverbatim
+      64             : In principle you can mix the two syntax (add a message as an argument and insert others with `<<`),
+      65             : however it is not very clear and should be avoided.
+      66             : We only allow using arguments in parenthesis in order to keep backward compatibility.
+      67             : 
+      68             : \par Using macros
+      69             : 
+      70             : In order to provide more context, especially for debugging, it might be useful to know where the exception
+      71             : originated from. The macros below add information about the exact location of the error in the file (filename, line
+      72             : and, when available, function name). Macros ending in "error" unconditionally throw
+      73             : the exception, whereas macros ending in "assert" first perform a conditional check
+      74             : (similarly to standard assert()).
+      75             : An extra `m` in the name (e.g. `plumed_merror`) indicates a macro that provides a message as its argument.
+      76             : However, as of PLUMED 2.5 we should prefer adding messages using insertion operators.
+      77             : \verbatim
+      78             : // this is correct but not recommended. add a message please!
+      79             :   plumed_assert(a>0);
+      80             : 
+      81             : // this is the old syntax (with argument).
+      82             : // this syntax is basically available for backward compatibility.
+      83             :   plumed_massert(a>0,"a should be larger than zero);
+      84             : 
+      85             : // this is the recommended syntax, with insertion operators.
+      86             : // it allows to easily insert multiple objects
+      87             :   plumed_assert(a>0)<<"a should be larger than zero. a="<<a;
+      88             : 
+      89             : // same as above, but the test is made explicitly:
+      90             :   if(a<=0) plumed_error();
+      91             :   if(a<=0) plumed_error("a should be larger than zero);
+      92             :   if(a<=0) plumed_error()<<"a should be larger than zero. a="<<a;
+      93             : \endverbatim
+      94             : 
+      95             : The additional macros
+      96             : plumed_dbg_assert() and plumed_dbg_massert() are similar
+      97             : to plumed_assert() and plumed_massert() respectively, but the corresponding
+      98             : check is only performed when NDEBUG macro is not defined. They should
+      99             : be used when the check is expensive and should be skipped in production
+     100             : code. So, for instance, in the following case:
+     101             : \verbatim
+     102             :   plumed_dbg_assert(expensive_function(i)>0)<<"message";
+     103             : \endverbatim
+     104             : `expensive_function()` is not called in the production code.
+     105             : Notice that the compiler should be able to completely optimize away the
+     106             : whole statement including functions used to produce the message as in this example:
+     107             : \verbatim
+     108             :   plumed_dbg_assert(expensive_function(i)>0)<<"I did this check "<<other_expensive_function(i);
+     109             : \endverbatim
+     110             : 
+     111             : Finally, notice that there is another macro available, \ref plumed_here.
+     112             : In can be used in order to create an exception with information about the
+     113             : line/file coordinates without trowing it. That is, the two following syntaxes
+     114             : are equivalent
+     115             : \verbatim
+     116             : // First way, all at once
+     117             : plumed_error()<<"some message";
+     118             : /////////////////////////////////
+     119             : // Second way, one step at a time
+     120             : // Create exception
+     121             : Exception e;
+     122             : // Append information about line and file
+     123             : e<<plumed_here;
+     124             : // Append some other message
+     125             : e<<"some message";
+     126             : // Throw the resulting exception
+     127             : throw e;
+     128             : \endverbatim
+     129             : 
+     130             : Exceptions can be caught within plumed or outside of it.
+     131             : E.g., in an external c++ code using PLUMED as a library, one can type
+     132             : \verbatim
+     133             :   try{
+     134             :     plumed.cmd("setPrecision",n);
+     135             :   } catch (const std::exception & e) {
+     136             :     std::printf("ee %s",e.what());
+     137             :     exit(1);
+     138             :   }
+     139             : \endverbatim
+     140             : This can be useful if an external code wants to exit in a controlled manner
+     141             : (e.g. flushing files, printing the error message in a specific file, etc.)
+     142             : but is anyway limited to c++ codes. Moreover,
+     143             : since these errors are expected to be unrecoverable, the MD code will
+     144             : usually not be able to do something more clever than exiting.
+     145             : 
+     146             : \note
+     147             : We store message and stack trace in growing strings. This is in
+     148             : principle not recommended, since copying the exception might fail if
+     149             : copying the string throw another exception. However, this has been like
+     150             : this in all previous PLUMED versions. In case it is necessary, we can replace
+     151             : it later with a fixed size array placed on the stack.
+     152             : 
+     153             : */
+     154             : class Exception : public std::exception
+     155             : {
+     156             : /// Reported message. Can be updated.
+     157             :   std::string msg;
+     158             : /// Flag to remember if we have to write the `+++ message follows +++` string.
+     159             : /// Needed so that the string appears only at the beginning of the message.
+     160             :   bool note=true;
+     161             : /// Stream used to insert objects.
+     162             : /// It is not copied when the Exception is copied.
+     163             :   std::stringstream stream;
+     164             : /// Stack trace, computed at construction
+     165             :   std::array<void*,128> callstack;
+     166             : /// Number of frames in stack, computed at construction
+     167             :   int callstack_n=0;
+     168             : /// Parsed stack trace. Built at first use, thus mutable.
+     169             :   mutable std::string stackTrace;
+     170             : 
+     171             : public:
+     172             : 
+     173             : /// Auxiliary containing the location of the exception in the file.
+     174             : /// Typically used from the macros below.
+     175             :   class Location {
+     176             :   public:
+     177             :     const char*file;
+     178             :     const unsigned line;
+     179             :     const char* pretty;
+     180          53 :     explicit Location(const char*file,unsigned line,const char* pretty=nullptr):
+     181          53 :       file(file),
+     182          53 :       line(line),
+     183          53 :       pretty(pretty)
+     184             :     {}
+     185             :   };
+     186             : 
+     187             : /// Auxiliary containing the failed assertion.
+     188             : /// Typically used from the macros below.
+     189             :   class Assertion {
+     190             :   public:
+     191             :     const char*assertion;
+     192           8 :     explicit Assertion(const char*assertion=nullptr):
+     193           8 :       assertion(assertion)
+     194             :     {}
+     195             :   };
+     196             : 
+     197             : /// Default constructor with no message.
+     198             : /// Only records the stack trace.
+     199             :   Exception();
+     200             : 
+     201             : /// Constructor compatible with PLUMED <=2.4.
+     202           3 :   explicit Exception(const std::string & msg):
+     203           3 :     Exception()
+     204             :   {
+     205           3 :     *this << msg;
+     206           3 :   }
+     207             : 
+     208             : /// Copy constructor.
+     209             : /// Needed to make sure stream is not copied
+     210          11 :   Exception(const Exception & e):
+     211          11 :     msg(e.msg),
+     212          11 :     note(e.note),
+     213          11 :     callstack(e.callstack),
+     214          11 :     callstack_n(e.callstack_n),
+     215          11 :     stackTrace(e.stackTrace)
+     216             :   {
+     217          11 :   }
+     218             : 
+     219             : /// Assignment.
+     220             : /// Needed to make sure stream is not copied
+     221             :   Exception & operator=(const Exception & e) {
+     222             :     msg=e.msg;
+     223             :     note=e.note;
+     224             :     callstack=e.callstack;
+     225             :     callstack_n=e.callstack_n;
+     226             :     stackTrace=e.stackTrace;
+     227             :     stream.str("");
+     228             :     return *this;
+     229             :   }
+     230             : 
+     231             : /// Returns the error message.
+     232             : /// In case the environment variable PLUMED_STACK_TRACE was defined
+     233             : /// and equal to `yes` when the exception was raised,
+     234             : /// the error message will contain the stack trace as well.
+     235          15 :   const char* what() const noexcept override {return msg.c_str();}
+     236             : 
+     237             : /// Returns the stack trace as a string.
+     238             : /// This function is slow as it requires building a parsed string.
+     239             : /// If storing the stack for later usage, you might prefer to use trace().
+     240             :   const char* stack() const;
+     241             : 
+     242             : /// Returns the callstack.
+     243             :   const std::array<void*,128> & trace() const noexcept {return callstack;}
+     244             : 
+     245             : /// Returns the number of elements in the trace array
+     246             :   int trace_n() const noexcept {return callstack_n;}
+     247             : 
+     248             : /// Destructor should be defined and should not throw other exceptions
+     249          66 :   ~Exception() noexcept override {}
+     250             : 
+     251             : /// Insert location.
+     252             : /// Format the location properly.
+     253             :   Exception& operator<<(const Location&);
+     254             : 
+     255             : /// Insert assertion.
+     256             : /// Format the assertion properly
+     257             :   Exception& operator<<(const Assertion&);
+     258             : 
+     259             : /// Insert string.
+     260             : /// Append this string to the message.
+     261             :   Exception& operator<<(const std::string&);
+     262             : 
+     263             : /// Insert anything else.
+     264             : /// This allows to dump also other types (e.g. double, or even Vector).
+     265             : /// Anything that can be written on a stream can go here.
+     266             :   template<typename T>
+     267          34 :   Exception& operator<<(const T & x) {
+     268          34 :     stream<<x;
+     269          34 :     (*this)<<stream.str();
+     270          34 :     stream.str("");
+     271          34 :     return *this;
+     272             :   }
+     273             : };
+     274             : 
+     275             : /// Class representing a generic error
+     276         147 : class ExceptionError :
+     277             :   public Exception {
+     278             : public:
+     279           1 :   using Exception::Exception;
+     280             :   template<typename T>
+     281             :   ExceptionError& operator<<(const T & x) {
+     282          94 :     *static_cast<Exception*>(this) <<x;
+     283             :     return *this;
+     284             :   }
+     285             : };
+     286             : 
+     287             : /// Class representing a debug error (can only be thrown when using debug options)
+     288             : class ExceptionDebug :
+     289             :   public Exception {
+     290             : public:
+     291           1 :   using Exception::Exception;
+     292             :   template<typename T>
+     293             :   ExceptionDebug& operator<<(const T & x) {
+     294             :     *static_cast<Exception*>(this) <<x;
+     295             :     return *this;
+     296             :   }
+     297             : };
+     298             : 
+     299             : /// Class representing a type error in the PLMD::Plumed interface
+     300          24 : class ExceptionTypeError :
+     301             :   public Exception {
+     302             : public:
+     303             :   using Exception::Exception;
+     304             :   template<typename T>
+     305             :   ExceptionTypeError& operator<<(const T & x) {
+     306          21 :     *static_cast<Exception*>(this) <<x;
+     307             :     return *this;
+     308             :   }
+     309             : };
+     310             : 
+     311             : #ifdef __GNUG__
+     312             : // With GNU compiler, we can use __PRETTY_FUNCTION__ to get the function name
+     313             : #define __PLUMED_FUNCNAME __PRETTY_FUNCTION__
+     314             : #else
+     315             : // Otherwise, we use the standard C++11 variable
+     316             : #define __PLUMED_FUNCNAME __func__
+     317             : #endif
+     318             : 
+     319             : /// \relates PLMD::Exception
+     320             : /// Auxiliary macro that generates a PLMD::Exception::Location object.
+     321             : /// Might be useful if we want to use derived exceptions that could
+     322             : /// be thrown using `throw DerivedException()<<plumed_here<<" "<<other stuff"`.
+     323             : /// It is used in the macros below to throw PLMD::Exception.
+     324             : #define plumed_here PLMD::Exception::Location(__FILE__,__LINE__,__PLUMED_FUNCNAME)
+     325             : 
+     326             : /// \relates PLMD::Exception
+     327             : /// Throw an exception with information about the position in the file.
+     328             : /// Messages can be inserted with `plumed_error()<<"message"`.
+     329             : #define plumed_error() throw PLMD::ExceptionError() << plumed_here
+     330             : 
+     331             : /// \relates PLMD::Exception
+     332             : /// Throw an exception with information about the position in the file
+     333             : /// and a message. Mostly available for backward compatibility
+     334             : #define plumed_merror(msg) plumed_error() << msg
+     335             : 
+     336             : /// \relates PLMD::Exception
+     337             : /// Launches plumed_merror only if test evaluates to false.
+     338             : /// The string describing the test is also reported.
+     339             : /// Further messages can be inserted with `<<`.
+     340             : #define plumed_assert(test) if(!(test)) plumed_error() << PLMD::Exception::Assertion(#test)
+     341             : 
+     342             : /// \relates PLMD::Exception
+     343             : /// Launches plumed_merror only if test evaluates to false.
+     344             : /// The string describing the test is also reported, in addition to
+     345             : /// messages reported in the extra argument. Mostly available for backward compatibility.
+     346             : #define plumed_massert(test,msg) plumed_assert(test) << msg
+     347             : 
+     348             : #ifdef NDEBUG
+     349             : 
+     350             : // These are the versions used when compiling with NDEBUG flag.
+     351             : // The condition is always true, so that the rest of the statement
+     352             : // should be optimized away.
+     353             : #define plumed_dbg_assert(test) plumed_assert(true)
+     354             : #define plumed_dbg_massert(test,msg) plumed_massert(true,msg)
+     355             : 
+     356             : #else
+     357             : 
+     358             : /// \relates PLMD::Exception
+     359             : /// Same as \ref plumed_assert, but only evaluates the condition if NDEBUG is not defined.
+     360             : #define plumed_dbg_assert(test) if(!(test)) throw PLMD::ExceptionDebug() << plumed_here << PLMD::Exception::Assertion(#test) << "(this check is enabled only in debug builds)\n"
+     361             : 
+     362             : /// \relates PLMD::Exception
+     363             : /// Same as \ref plumed_massert, but only evaluates the condition if NDEBUG is not defined.
+     364             : #define plumed_dbg_massert(test,msg) plumed_dbg_assert(test) << msg
+     365             : 
+     366             : #endif
+     367             : 
+     368             : }
+     369             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..3937aebf15 --- /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:7979100.0 %
Date:2024-06-10 08:19:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase5closeEv992
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1792
_ZN4PLMD8FileBase4linkERNS_6ActionE3815
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE4607
_ZN4PLMD8FileBase5flushEv4719
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev5310
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6505
_ZN4PLMD8FileBase4linkEP8_IO_FILE20867
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE409217
_ZN4PLMD8FileBase6isOpenEv411529
_ZN4PLMD8FileBaseC2Ev430294
_ZN4PLMD8FileBaseD2Ev430294
_ZNK4PLMD8FileBasecvbEv29217355
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/FileBase.cpp.func.html b/coverage/tools/FileBase.cpp.func.html new file mode 100644 index 0000000000..2be753f2a0 --- /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:7979100.0 %
Date:2024-06-10 08:19:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6505
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase4linkEP8_IO_FILE20867
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE4607
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE409217
_ZN4PLMD8FileBase4linkERNS_6ActionE3815
_ZN4PLMD8FileBase5closeEv992
_ZN4PLMD8FileBase5flushEv4719
_ZN4PLMD8FileBase6isOpenEv411529
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1792
_ZN4PLMD8FileBaseC2Ev430294
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBaseD2Ev430294
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev5310
_ZNK4PLMD8FileBasecvbEv29217355
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/FileBase.cpp.gcov.html b/coverage/tools/FileBase.cpp.gcov.html new file mode 100644 index 0000000000..6fb067d954 --- /dev/null +++ b/coverage/tools/FileBase.cpp.gcov.html @@ -0,0 +1,246 @@ + + + + + + + + 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:7979100.0 %
Date:2024-06-10 08:19:14Functions: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       20867 : FileBase& FileBase::link(FILE*fp) {
+      43       20867 :   plumed_massert(!this->fp,"cannot link an already open file");
+      44       20867 :   this->fp=fp;
+      45       20867 :   cloned=true;
+      46       20867 :   return *this;
+      47             : }
+      48             : 
+      49        4719 : FileBase& FileBase::flush() {
+      50        4719 :   if(fp) fflush(fp);
+      51        4719 :   return *this;
+      52             : }
+      53             : 
+      54      409217 : FileBase& FileBase::link(Communicator&comm) {
+      55      409217 :   plumed_massert(!fp,"cannot link an already open file");
+      56      409217 :   this->comm=&comm;
+      57      409217 :   return *this;
+      58             : }
+      59             : 
+      60        4607 : FileBase& FileBase::link(PlumedMain&plumed) {
+      61        4607 :   plumed_massert(!fp,"cannot link an already open file");
+      62        4607 :   this->plumed=&plumed;
+      63        4607 :   link(plumed.comm);
+      64        4607 :   return *this;
+      65             : }
+      66             : 
+      67        3815 : FileBase& FileBase::link(Action&action) {
+      68        3815 :   plumed_massert(!fp,"cannot link an already open file");
+      69        3815 :   this->action=&action;
+      70        3815 :   link(action.plumed);
+      71        3815 :   return *this;
+      72             : }
+      73             : 
+      74        1792 : bool FileBase::FileExist(const std::string& path) {
+      75             :   bool do_exist=false;
+      76        3584 :   this->path=appendSuffix(path,getSuffix());
+      77        1792 :   mode="r";
+      78        1792 :   FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      79        1792 :   if(!ff) {
+      80             :     this->path=path;
+      81         563 :     ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      82             :     mode="r";
+      83             :   }
+      84        1792 :   if(ff) {do_exist=true; fclose(ff);}
+      85        1792 :   if(comm) comm->Barrier();
+      86        1792 :   return do_exist;
+      87             : }
+      88             : 
+      89      411529 : bool FileBase::isOpen() {
+      90             :   bool isopen=false;
+      91      411529 :   if(fp) isopen=true;
+      92      411529 :   return isopen;
+      93             : }
+      94             : 
+      95         992 : void        FileBase::close() {
+      96         992 :   plumed_assert(!cloned);
+      97         992 :   eof=false;
+      98         992 :   err=false;
+      99         992 :   if(fp)   std::fclose(fp);
+     100             : #ifdef __PLUMED_HAS_ZLIB
+     101         992 :   if(gzfp) gzclose(gzFile(gzfp));
+     102             : #endif
+     103         992 :   fp=NULL;
+     104         992 :   gzfp=NULL;
+     105         992 : }
+     106             : 
+     107      430294 : FileBase::FileBase():
+     108      430294 :   fp(NULL),
+     109      430294 :   gzfp(NULL),
+     110      430294 :   comm(NULL),
+     111      430294 :   plumed(NULL),
+     112      430294 :   action(NULL),
+     113      430294 :   cloned(false),
+     114      430294 :   eof(false),
+     115      430294 :   err(false),
+     116      430294 :   heavyFlush(false),
+     117      430294 :   enforcedSuffix_(false)
+     118             : {
+     119      430294 : }
+     120             : 
+     121      430294 : FileBase::~FileBase()
+     122             : {
+     123      430294 :   if(plumed) plumed->eraseFile(*this);
+     124      430294 :   if(!cloned && fp)   fclose(fp);
+     125             : #ifdef __PLUMED_HAS_ZLIB
+     126      430294 :   if(!cloned && gzfp) gzclose(gzFile(gzfp));
+     127             : #endif
+     128      430294 : }
+     129             : 
+     130    29217355 : FileBase::operator bool()const {
+     131    29217355 :   return !eof;
+     132             : }
+     133             : 
+     134        6505 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) {
+     135        6505 :   if(path=="/dev/null") return path; // do not append a suffix to /dev/null
+     136        6330 :   std::string ret=path;
+     137        6330 :   std::string ext=Tools::extension(path);
+     138             : 
+     139             : // These are the recognized extensions so far:
+     140             : // gz xtc trr
+     141             : // If a file name ends with one of these extensions, the suffix is added *before*
+     142             : // the extension. This is useful when extensions are conventionally used
+     143             : // to detect file type, so as to allow easier file manipulation.
+     144             : // Removing this line, any extension recognized by Tools::extension() would be considered
+     145             : //  if(ext!="gz" && ext!="xtc" && ext!="trr") ext="";
+     146             : 
+     147        6330 :   if(ext.length()>0) {
+     148        4577 :     int l=path.length()-(ext.length()+1);
+     149        4577 :     plumed_assert(l>=0);
+     150        9154 :     ret=ret.substr(0,l);
+     151             :   }
+     152             :   ret+=suffix;
+     153       10907 :   if(ext.length()>0)ret+="."+ext;
+     154             :   return ret;
+     155             : }
+     156             : 
+     157         258 : FileBase& FileBase::enforceSuffix(const std::string&suffix) {
+     158         258 :   enforcedSuffix_=true;
+     159         258 :   enforcedSuffix=suffix;
+     160         258 :   return *this;
+     161             : }
+     162             : 
+     163        5310 : std::string FileBase::getSuffix()const {
+     164        5310 :   if(enforcedSuffix_) return enforcedSuffix;
+     165        5046 :   if(plumed) return plumed->getSuffix();
+     166         501 :   return "";
+     167             : }
+     168             : 
+     169             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..28945fb646 --- /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:55100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/FileBase.h.func.html b/coverage/tools/FileBase.h.func.html new file mode 100644 index 0000000000..b17729aa3f --- /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:55100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/FileBase.h.gcov.html b/coverage/tools/FileBase.h.gcov.html new file mode 100644 index 0000000000..c2c30c8d3f --- /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:55100.0 %
Date:2024-06-10 08:19:14Functions: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             :   class FieldBase {
+      48             : // everything is public to simplify usage
+      49             :   public:
+      50             :     std::string name;
+      51             :     std::string value;
+      52             :     bool constant;
+      53    16209163 :     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         627 :   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         741 :   return path;
+     138             : }
+     139             : 
+     140             : inline
+     141             : std::string FileBase::getMode()const {
+     142          90 :   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.15
+
+ + + 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 0000000000..3d38b29276 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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-06-10 08:19:14Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_84
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_581
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_5AtomsEEC2IJRNS_10PlumedMainEEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_414504
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_812643
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.func.html b/coverage/tools/ForwardDecl.h.func.html new file mode 100644 index 0000000000..6df7d99d63 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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-06-10 08:19:14Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_812643
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_84
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_414504
_ZN4PLMD11ForwardDeclINS_5AtomsEEC2IJRNS_10PlumedMainEEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_404395
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_581
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_404395
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.gcov.html b/coverage/tools/ForwardDecl.h.gcov.html new file mode 100644 index 0000000000..9b03009404 --- /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-06-10 08:19:14Functions:1313100.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     2440793 : 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     4867367 : ForwardDecl<T>::ForwardDecl(Args &&...args):
+      49     4867367 :   std::unique_ptr<T>(new T(std::forward<Args>(args)...))
+      50     4867367 : {}
+      51             : 
+      52             : 
+      53             : }
+      54             : 
+      55             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..5232cb7415 --- /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:44062071.0 %
Date:2024-06-10 08:19:14Functions: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
_ZNK4PLMD8GridBase8getValueERKSt6vectorIdSaIdEE305
_ZNK4PLMD8GridBase6getMaxB5cxx11Ev336
_ZN4PLMD4Grid28scaleAllValuesAndDerivativesERKd594
_ZNK4PLMD4Grid11getMaxValueEv629
_ZNK4PLMD4Grid11getMinValueEv861
_ZN4PLMD4Grid11writeToFileERNS_5OFileE1146
_ZN4PLMD8GridBase11writeHeaderERNS_5OFileE1146
_ZN4PLMD8GridBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb1320
_ZN4PLMD4Grid12setMinToZeroEv1329
_ZN4PLMD8GridBase4InitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_1448
_ZNK4PLMD8GridBase13getIsPeriodicEv2240
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEERS1_IjSaIjEE3621
_ZNK4PLMD8GridBase18getSplineNeighborsERKSt6vectorIjSaIjEERS1_ImSaImEERj3621
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIdSaIdEERS3_3621
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIdSaIdEERKS1_IjSaIjEE4171
_ZNK4PLMD8GridBase10getIndicesEmRSt6vectorIjSaIjEE8712
_ZNK4PLMD8GridBase11getArgNamesB5cxx11Ev9436
_ZNK4PLMD8GridBase19getNearestNeighborsEm9577
_ZNK4PLMD8GridBase5getDxEm11656
_ZNK4PLMD8GridBase12getNeighborsEmRKSt6vectorIjSaIjEE19153
_ZN4PLMD10SparseGrid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE19999
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIjSaIjEES5_23324
_ZN4PLMD10indexed_ltERKSt4pairImdES3_59573
_ZN4PLMD4Grid21projectOnLowDimensionERdRSt6vectorIiSaIiEEPNS_10WeightBaseE1010062
_ZNK4PLMD8GridBase7getNbinEv1012510
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIdSaIdEE1100069
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEE1104241
_ZNK4PLMD8GridBase8getPointEmRSt6vectorIdSaIdEE1109261
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEERS1_IdSaIdEE1112882
_ZN4PLMD4Grid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE1170278
_ZNK4PLMD8GridBase8getValueERKSt6vectorIjSaIjEE1193613
_ZNK4PLMD8GridBase5getDxEv1319529
_ZNK4PLMD8GridBase6getMinB5cxx11Ev1360387
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIjSaIjEERS1_IdSaIdEE2527708
_ZN4PLMD4Grid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE2552369
_ZNK4PLMD4Grid22getValueAndDerivativesEmRSt6vectorIdSaIdEE3079545
_ZN4PLMD4Grid8setValueEmd6444104
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIjSaIjEE7144137
_ZNK4PLMD8GridBase12getDimensionEv18321217
_ZNK4PLMD4Grid8getValueEm27284983
_ZNK4PLMD8GridBase8getPointEm28822305
_ZNK4PLMD4Grid7getSizeEv28865188
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEE31542407
_ZNK4PLMD8GridBase10getIndicesEm37828400
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Grid.cpp.func.html b/coverage/tools/Grid.cpp.func.html new file mode 100644 index 0000000000..c463c39ea1 --- /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:44062071.0 %
Date:2024-06-10 08:19:14Functions:557771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SparseGrid11writeToFileERNS_5OFileE0
_ZN4PLMD10SparseGrid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE19999
_ZN4PLMD10SparseGrid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE0
_ZN4PLMD10SparseGrid8addValueEmd0
_ZN4PLMD10SparseGrid8setValueEmd0
_ZN4PLMD10indexed_ltERKSt4pairImdES3_59573
_ZN4PLMD4Grid11writeToFileERNS_5OFileE1146
_ZN4PLMD4Grid12setMinToZeroEv1329
_ZN4PLMD4Grid21projectOnLowDimensionERdRSt6vectorIiSaIiEEPNS_10WeightBaseE1010062
_ZN4PLMD4Grid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE1170278
_ZN4PLMD4Grid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE2552369
_ZN4PLMD4Grid24findSetOfPointsOnContourERKdRKSt6vectorIbSaIbEERjRS3_IS3_IdSaIdEESaISA_EE0
_ZN4PLMD4Grid26logAllValuesAndDerivativesERKd0
_ZN4PLMD4Grid26mpiSumValuesAndDerivativesERNS_12CommunicatorE0
_ZN4PLMD4Grid28scaleAllValuesAndDerivativesERKd594
_ZN4PLMD4Grid36applyFunctionAllValuesAndDerivativesEPFddES2_1
_ZN4PLMD4Grid5clearEv1
_ZN4PLMD4Grid7projectERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEPNS_10WeightBaseE81
_ZN4PLMD4Grid8addValueEmd1
_ZN4PLMD4Grid8setValueEmd6444104
_ZN4PLMD4Grid9integrateERSt6vectorIjSaIjEE0
_ZN4PLMD8GridBase11writeHeaderERNS_5OFileE1146
_ZN4PLMD8GridBase13writeCubeFileERNS_5OFileERKd0
_ZN4PLMD8GridBase22addValueAndDerivativesERKSt6vectorIjSaIjEEdRS1_IdSaIdEE0
_ZN4PLMD8GridBase22findMaximalPathMinimumERKSt6vectorIdSaIdEES5_273
_ZN4PLMD8GridBase22setValueAndDerivativesERKSt6vectorIjSaIjEEdRS1_IdSaIdEE0
_ZN4PLMD8GridBase4InitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_1448
_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_IjSaIjEEbb1320
_ZN4PLMD8GridBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_128
_ZNK4PLMD10SparseGrid10getMaxSizeEv0
_ZNK4PLMD10SparseGrid11getMaxValueEv9
_ZNK4PLMD10SparseGrid11getMinValueEv0
_ZNK4PLMD10SparseGrid22getValueAndDerivativesEmRSt6vectorIdSaIdEE200
_ZNK4PLMD10SparseGrid7getSizeEv0
_ZNK4PLMD10SparseGrid8getValueEm0
_ZNK4PLMD4Grid11getMaxValueEv629
_ZNK4PLMD4Grid11getMinValueEv861
_ZNK4PLMD4Grid22getValueAndDerivativesEmRSt6vectorIdSaIdEE3079545
_ZNK4PLMD4Grid24getDifferenceFromContourERKSt6vectorIdSaIdEERS3_0
_ZNK4PLMD4Grid7getSizeEv28865188
_ZNK4PLMD4Grid8getValueEm27284983
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEE1104241
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEERS1_IjSaIjEE3621
_ZNK4PLMD8GridBase10getIndicesEm37828400
_ZNK4PLMD8GridBase10getIndicesEmRSt6vectorIjSaIjEE8712
_ZNK4PLMD8GridBase11getArgNamesB5cxx11Ev9436
_ZNK4PLMD8GridBase12getBinVolumeEv37
_ZNK4PLMD8GridBase12getDimensionEv18321217
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIdSaIdEERKS1_IjSaIjEE4171
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIjSaIjEES5_23324
_ZNK4PLMD8GridBase12getNeighborsEmRKSt6vectorIjSaIjEE19153
_ZNK4PLMD8GridBase13getIsPeriodicEv2240
_ZNK4PLMD8GridBase18getSplineNeighborsERKSt6vectorIjSaIjEERS1_ImSaImEERj3621
_ZNK4PLMD8GridBase19getNearestNeighborsERKSt6vectorIjSaIjEE0
_ZNK4PLMD8GridBase19getNearestNeighborsEm9577
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIdSaIdEERS3_3621
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIjSaIjEERS1_IdSaIdEE2527708
_ZNK4PLMD8GridBase5getDxEm11656
_ZNK4PLMD8GridBase5getDxEv1319529
_ZNK4PLMD8GridBase6getMaxB5cxx11Ev336
_ZNK4PLMD8GridBase6getMinB5cxx11Ev1360387
_ZNK4PLMD8GridBase7getNbinEv1012510
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIdSaIdEE1100069
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIjSaIjEE7144137
_ZNK4PLMD8GridBase8getPointERKSt6vectorIdSaIdEE0
_ZNK4PLMD8GridBase8getPointERKSt6vectorIdSaIdEERS3_0
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEE31542407
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEERS1_IdSaIdEE1112882
_ZNK4PLMD8GridBase8getPointEm28822305
_ZNK4PLMD8GridBase8getPointEmRSt6vectorIdSaIdEE1109261
_ZNK4PLMD8GridBase8getValueERKSt6vectorIdSaIdEE305
_ZNK4PLMD8GridBase8getValueERKSt6vectorIjSaIjEE1193613
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Grid.cpp.gcov.html b/coverage/tools/Grid.cpp.gcov.html new file mode 100644 index 0000000000..c78e8362ef --- /dev/null +++ b/coverage/tools/Grid.cpp.gcov.html @@ -0,0 +1,1206 @@ + + + + + + + + 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:44062071.0 %
Date:2024-06-10 08:19:14Functions: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        1320 : GridBase::GridBase(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+      45        1320 :                    const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv) {
+      46             : // various checks
+      47        1320 :   plumed_assert(args.size()<=maxdim) << "grid dim cannot exceed "<<maxdim;
+      48        1320 :   plumed_massert(args.size()==gmin.size(),"grid min dimensions in input do not match number of arguments");
+      49        1320 :   plumed_massert(args.size()==nbin.size(),"number of bins on input do not match number of arguments");
+      50        1320 :   plumed_massert(args.size()==gmax.size(),"grid max dimensions in input do not match number of arguments");
+      51        1320 :   unsigned dim=gmax.size();
+      52             :   std::vector<std::string> names;
+      53             :   std::vector<bool> isperiodic;
+      54             :   std::vector<std::string> pmin,pmax;
+      55        1320 :   names.resize( dim );
+      56        1320 :   isperiodic.resize( dim );
+      57        1320 :   pmin.resize( dim );
+      58        1320 :   pmax.resize( dim );
+      59        2918 :   for(unsigned int i=0; i<dim; ++i) {
+      60        1598 :     names[i]=args[i]->getName();
+      61        1598 :     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        1320 :   Init(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax);
+      72        2640 : }
+      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        1448 : 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        1448 :   fmt_="%14.9f";
+      85             : // various checks
+      86        1448 :   plumed_assert(names.size()<=maxdim) << "grid size cannot exceed "<<maxdim;
+      87        1448 :   plumed_massert(names.size()==gmin.size(),"grid dimensions in input do not match number of arguments");
+      88        1448 :   plumed_massert(names.size()==nbin.size(),"grid dimensions in input do not match number of arguments");
+      89        1448 :   plumed_massert(names.size()==gmax.size(),"grid dimensions in input do not match number of arguments");
+      90        1448 :   dimension_=gmax.size();
+      91        1448 :   str_min_=gmin; str_max_=gmax;
+      92        1448 :   argnames.resize( dimension_ );
+      93        1448 :   min_.resize( dimension_ );
+      94        1448 :   max_.resize( dimension_ );
+      95        1448 :   pbc_.resize( dimension_ );
+      96        3174 :   for(unsigned int i=0; i<dimension_; ++i) {
+      97        1726 :     argnames[i]=names[i];
+      98        1726 :     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        1726 :     Tools::convert(str_min_[i],min_[i]);
+     106        1726 :     Tools::convert(str_max_[i],max_[i]);
+     107        1726 :     funcname=funcl;
+     108        1726 :     plumed_massert(max_[i]>min_[i],"maximum in grid must be larger than minimum");
+     109        1726 :     plumed_massert(nbin[i]>0,"number of grid points must be greater than zero");
+     110             :   }
+     111        1448 :   nbin_=nbin;
+     112        1448 :   dospline_=dospline;
+     113        1448 :   usederiv_=usederiv;
+     114        1448 :   if(dospline_) plumed_assert(dospline_==usederiv_);
+     115        1448 :   maxsize_=1;
+     116        3174 :   for(unsigned int i=0; i<dimension_; ++i) {
+     117        1726 :     dx_.push_back( (max_[i]-min_[i])/static_cast<double>( nbin_[i] ) );
+     118        1726 :     if( !pbc_[i] ) { max_[i] += dx_[i]; nbin_[i] += 1; }
+     119        1726 :     maxsize_*=nbin_[i];
+     120             :   }
+     121        1448 : }
+     122             : 
+     123     1360387 : std::vector<std::string> GridBase::getMin() const {
+     124     1360387 :   return str_min_;
+     125             : }
+     126             : 
+     127         336 : std::vector<std::string> GridBase::getMax() const {
+     128         336 :   return str_max_;
+     129             : }
+     130             : 
+     131     1319529 : std::vector<double> GridBase::getDx() const {
+     132     1319529 :   return dx_;
+     133             : }
+     134             : 
+     135       11656 : double GridBase::getDx(index_t j) const {
+     136       11656 :   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     7144137 : GridBase::index_t GridBase::getIndex(const std::vector<unsigned> & indices) const {
+     163             :   plumed_dbg_assert(indices.size()==dimension_);
+     164    19315840 :   for(unsigned int i=0; i<dimension_; i++)
+     165    12171703 :     if(indices[i]>=nbin_[i]) {
+     166             :       std::string is;
+     167           0 :       Tools::convert(i,is);
+     168           0 :       std::string msg="ERROR: the system is looking for a value outside the grid along the " + is + " ("+getArgNames()[i]+")";
+     169           0 :       plumed_merror(msg+" index!");
+     170             :     }
+     171     7144137 :   index_t index=indices[dimension_-1];
+     172    12171703 :   for(unsigned int i=dimension_-1; i>0; --i) {
+     173     5027566 :     index=index*nbin_[i-1]+indices[i-1];
+     174             :   }
+     175     7144137 :   return index;
+     176             : }
+     177             : 
+     178     1100069 : GridBase::index_t GridBase::getIndex(const std::vector<double> & x) const {
+     179             :   plumed_dbg_assert(x.size()==dimension_);
+     180     2200138 :   return getIndex(getIndices(x));
+     181             : }
+     182             : 
+     183             : // we are flattening arrays using a column-major order
+     184    37828400 : std::vector<unsigned> GridBase::getIndices(index_t index) const {
+     185    37828400 :   std::vector<unsigned> indices(dimension_);
+     186             :   index_t kk=index;
+     187    37828400 :   indices[0]=(index%nbin_[0]);
+     188    54777109 :   for(unsigned int i=1; i<dimension_-1; ++i) {
+     189    16948709 :     kk=(kk-indices[i-1])/nbin_[i-1];
+     190    16948709 :     indices[i]=(kk%nbin_[i]);
+     191             :   }
+     192    37828400 :   if(dimension_>=2) {
+     193    36999790 :     indices[dimension_-1]=((kk-indices[dimension_-2])/nbin_[dimension_-2]);
+     194             :   }
+     195    37828400 :   return indices;
+     196             : }
+     197             : 
+     198        8712 : void GridBase::getIndices(index_t index, std::vector<unsigned>& indices) const {
+     199        8712 :   if (indices.size()!=dimension_) indices.resize(dimension_);
+     200             :   index_t kk=index;
+     201        8712 :   indices[0]=(index%nbin_[0]);
+     202        8712 :   for(unsigned int i=1; i<dimension_-1; ++i) {
+     203           0 :     kk=(kk-indices[i-1])/nbin_[i-1];
+     204           0 :     indices[i]=(kk%nbin_[i]);
+     205             :   }
+     206        8712 :   if(dimension_>=2) {
+     207        2944 :     indices[dimension_-1]=((kk-indices[dimension_-2])/nbin_[dimension_-2]);
+     208             :   }
+     209        8712 : }
+     210             : 
+     211     1104241 : std::vector<unsigned> GridBase::getIndices(const std::vector<double> & x) const {
+     212             :   plumed_dbg_assert(x.size()==dimension_);
+     213     1104241 :   std::vector<unsigned> indices(dimension_);
+     214     3307985 :   for(unsigned int i=0; i<dimension_; ++i) {
+     215     2203744 :     indices[i] = unsigned(std::floor((x[i]-min_[i])/dx_[i]));
+     216             :   }
+     217     1104241 :   return indices;
+     218             : }
+     219             : 
+     220        3621 : void GridBase::getIndices(const std::vector<double> & x, std::vector<unsigned>& indices) const {
+     221             :   plumed_dbg_assert(x.size()==dimension_);
+     222        3621 :   if (indices.size()!=dimension_) indices.resize(dimension_);
+     223        7978 :   for(unsigned int i=0; i<dimension_; ++i) {
+     224        4357 :     indices[i] = unsigned(std::floor((x[i]-min_[i])/dx_[i]));
+     225             :   }
+     226        3621 : }
+     227             : 
+     228    31542407 : std::vector<double> GridBase::getPoint(const std::vector<unsigned> & indices) const {
+     229             :   plumed_dbg_assert(indices.size()==dimension_);
+     230    31542407 :   std::vector<double> x(dimension_);
+     231   108460806 :   for(unsigned int i=0; i<dimension_; ++i) {
+     232    76918399 :     x[i]=min_[i]+(double)(indices[i])*dx_[i];
+     233             :   }
+     234    31542407 :   return x;
+     235             : }
+     236             : 
+     237    28822305 : std::vector<double> GridBase::getPoint(index_t index) const {
+     238             :   plumed_dbg_assert(index<maxsize_);
+     239    57644610 :   return getPoint(getIndices(index));
+     240             : }
+     241             : 
+     242           0 : std::vector<double> GridBase::getPoint(const std::vector<double> & x) const {
+     243             :   plumed_dbg_assert(x.size()==dimension_);
+     244           0 :   return getPoint(getIndices(x));
+     245             : }
+     246             : 
+     247     1109261 : void GridBase::getPoint(index_t index,std::vector<double> & point) const {
+     248             :   plumed_dbg_assert(index<maxsize_);
+     249     1109261 :   getPoint(getIndices(index),point);
+     250     1109261 : }
+     251             : 
+     252     1112882 : void GridBase::getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const {
+     253             :   plumed_dbg_assert(indices.size()==dimension_);
+     254             :   plumed_dbg_assert(point.size()==dimension_);
+     255     3326995 :   for(unsigned int i=0; i<dimension_; ++i) {
+     256     2214113 :     point[i]=min_[i]+(double)(indices[i])*dx_[i];
+     257             :   }
+     258     1112882 : }
+     259             : 
+     260           0 : void GridBase::getPoint(const std::vector<double> & x,std::vector<double> & point) const {
+     261             :   plumed_dbg_assert(x.size()==dimension_);
+     262           0 :   getPoint(getIndices(x),point);
+     263           0 : }
+     264             : 
+     265       23324 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<unsigned> &indices,const std::vector<unsigned> &nneigh)const {
+     266             :   plumed_dbg_assert(indices.size()==dimension_ && nneigh.size()==dimension_);
+     267             : 
+     268             :   std::vector<index_t> neighbors;
+     269       23324 :   std::vector<unsigned> small_bin(dimension_);
+     270             : 
+     271             :   unsigned small_nbin=1;
+     272       69508 :   for(unsigned j=0; j<dimension_; ++j) {
+     273       46184 :     small_bin[j]=(2*nneigh[j]+1);
+     274       46184 :     small_nbin*=small_bin[j];
+     275             :   }
+     276             : 
+     277       23324 :   std::vector<unsigned> small_indices(dimension_);
+     278             :   std::vector<unsigned> tmp_indices;
+     279     1269270 :   for(unsigned index=0; index<small_nbin; ++index) {
+     280     1245946 :     tmp_indices.resize(dimension_);
+     281             :     unsigned kk=index;
+     282     1245946 :     small_indices[0]=(index%small_bin[0]);
+     283     1245946 :     for(unsigned i=1; i<dimension_-1; ++i) {
+     284           0 :       kk=(kk-small_indices[i-1])/small_bin[i-1];
+     285           0 :       small_indices[i]=(kk%small_bin[i]);
+     286             :     }
+     287     1245946 :     if(dimension_>=2) {
+     288     1234250 :       small_indices[dimension_-1]=((kk-small_indices[dimension_-2])/small_bin[dimension_-2]);
+     289             :     }
+     290             :     unsigned ll=0;
+     291     3726142 :     for(unsigned i=0; i<dimension_; ++i) {
+     292     2480196 :       int i0=small_indices[i]-nneigh[i]+indices[i];
+     293     2480196 :       if(!pbc_[i] && i0<0)         continue;
+     294     2479162 :       if(!pbc_[i] && i0>=static_cast<int>(nbin_[i])) continue;
+     295     2478046 :       if( pbc_[i] && i0<0)         i0=nbin_[i]-(-i0)%nbin_[i];
+     296     2478046 :       if( pbc_[i] && i0>=static_cast<int>(nbin_[i])) i0%=nbin_[i];
+     297     2478046 :       tmp_indices[ll]=static_cast<unsigned>(i0);
+     298     2478046 :       ll++;
+     299             :     }
+     300     1245946 :     tmp_indices.resize(ll);
+     301     1245946 :     if(tmp_indices.size()==dimension_) {neighbors.push_back(getIndex(tmp_indices));}
+     302             :   }
+     303       23324 :   return neighbors;
+     304             : }
+     305             : 
+     306        4171 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & nneigh)const {
+     307             :   plumed_dbg_assert(x.size()==dimension_ && nneigh.size()==dimension_);
+     308        8342 :   return getNeighbors(getIndices(x),nneigh);
+     309             : }
+     310             : 
+     311       19153 : std::vector<GridBase::index_t> GridBase::getNeighbors(index_t index,const std::vector<unsigned> & nneigh)const {
+     312             :   plumed_dbg_assert(index<maxsize_ && nneigh.size()==dimension_);
+     313       38306 :   return getNeighbors(getIndices(index),nneigh);
+     314             : }
+     315             : 
+     316        3621 : void GridBase::getSplineNeighbors(const std::vector<unsigned> & indices, std::vector<GridBase::index_t>& neighbors, unsigned& nneighbors)const {
+     317             :   plumed_dbg_assert(indices.size()==dimension_);
+     318        3621 :   unsigned nneigh=unsigned(std::pow(2.0,int(dimension_)));
+     319        3621 :   if (neighbors.size()!=nneigh) neighbors.resize(nneigh);
+     320             : 
+     321        3621 :   std::vector<unsigned> nindices(dimension_);
+     322        3621 :   unsigned inind; nneighbors = 0;
+     323       12335 :   for(unsigned int i=0; i<nneigh; ++i) {
+     324             :     unsigned tmp=i; inind=0;
+     325       20372 :     for(unsigned int j=0; j<dimension_; ++j) {
+     326       11658 :       unsigned i0=tmp%2+indices[j];
+     327       11658 :       tmp/=2;
+     328       11658 :       if(!pbc_[j] && i0==nbin_[j]) continue;
+     329       11656 :       if( pbc_[j] && i0==nbin_[j]) i0=0;
+     330       11656 :       nindices[inind++]=i0;
+     331             :     }
+     332        8714 :     if(inind==dimension_) neighbors[nneighbors++]=getIndex(nindices);
+     333             :   }
+     334        3621 : }
+     335             : 
+     336        9577 : std::vector<GridBase::index_t> GridBase::getNearestNeighbors(const index_t index) const {
+     337        9577 :   std::vector<index_t> nearest_neighs = std::vector<index_t>();
+     338       28730 :   for (unsigned i = 0; i < dimension_; i++) {
+     339       19153 :     std::vector<unsigned> neighsneeded = std::vector<unsigned>(dimension_, 0);
+     340       19153 :     neighsneeded[i] = 1;
+     341       19153 :     std::vector<index_t> singledim_nearest_neighs = getNeighbors(index, neighsneeded);
+     342       74978 :     for (unsigned j = 0; j < singledim_nearest_neighs.size(); j++) {
+     343       55825 :       index_t neigh = singledim_nearest_neighs[j];
+     344       55825 :       if (neigh != index) {
+     345       36672 :         nearest_neighs.push_back(neigh);
+     346             :       }
+     347             :     }
+     348             :   }
+     349        9577 :   return nearest_neighs;
+     350             : }
+     351             : 
+     352           0 : std::vector<GridBase::index_t> GridBase::getNearestNeighbors(const std::vector<unsigned> &indices) const {
+     353             :   plumed_dbg_assert(indices.size() == dimension_);
+     354           0 :   return getNearestNeighbors(getIndex(indices));
+     355             : }
+     356             : 
+     357           0 : void GridBase::addKernel( const KernelFunctions& kernel ) {
+     358             :   plumed_dbg_assert( kernel.ndim()==dimension_ );
+     359           0 :   std::vector<unsigned> nneighb=kernel.getSupport( dx_ );
+     360           0 :   std::vector<index_t> neighbors=getNeighbors( kernel.getCenter(), nneighb );
+     361           0 :   std::vector<double> xx( dimension_ );
+     362           0 :   std::vector<std::unique_ptr<Value>> vv( dimension_ );
+     363             :   std::string str_min, str_max;
+     364           0 :   for(unsigned i=0; i<dimension_; ++i) {
+     365           0 :     vv[i]=Tools::make_unique<Value>();
+     366           0 :     if( pbc_[i] ) {
+     367           0 :       Tools::convert(min_[i],str_min);
+     368           0 :       Tools::convert(max_[i],str_max);
+     369           0 :       vv[i]->setDomain( str_min, str_max );
+     370             :     } else {
+     371           0 :       vv[i]->setNotPeriodic();
+     372             :     }
+     373             :   }
+     374             : 
+     375             : // vv_ptr contains plain pointers obtained from vv.
+     376             : // this is the simplest way to replace a unique_ptr here.
+     377             : // perhaps the interface of kernel.evaluate() should be changed
+     378             : // in order to accept a std::vector<std::unique_ptr<Value>>
+     379           0 :   auto vv_ptr=Tools::unique2raw(vv);
+     380             : 
+     381           0 :   std::vector<double> der( dimension_ );
+     382           0 :   for(unsigned i=0; i<neighbors.size(); ++i) {
+     383           0 :     index_t ineigh=neighbors[i];
+     384           0 :     getPoint( ineigh, xx );
+     385           0 :     for(unsigned j=0; j<dimension_; ++j) vv[j]->set(xx[j]);
+     386           0 :     double newval = kernel.evaluate( vv_ptr, der, usederiv_ );
+     387           0 :     if( usederiv_ ) addValueAndDerivatives( ineigh, newval, der );
+     388           0 :     else addValue( ineigh, newval );
+     389             :   }
+     390           0 : }
+     391             : 
+     392     1193613 : double GridBase::getValue(const std::vector<unsigned> & indices) const {
+     393     1193613 :   return getValue(getIndex(indices));
+     394             : }
+     395             : 
+     396         305 : double GridBase::getValue(const std::vector<double> & x) const {
+     397         305 :   if(!dospline_) {
+     398          18 :     return getValue(getIndex(x));
+     399             :   } else {
+     400         287 :     std::vector<double> der(dimension_);
+     401         287 :     return getValueAndDerivatives(x,der);
+     402             :   }
+     403             : }
+     404             : 
+     405     2527708 : double GridBase::getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const {
+     406     2527708 :   return getValueAndDerivatives(getIndex(indices),der);
+     407             : }
+     408             : 
+     409        3621 : double GridBase::getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const {
+     410             :   plumed_dbg_assert(der.size()==dimension_ && usederiv_);
+     411             : 
+     412        3621 :   if(dospline_) {
+     413             :     double X,X2,X3,value;
+     414             :     std::array<double,maxdim> fd, C, D;
+     415        3621 :     std::vector<double> dder(dimension_);
+     416             : // reset
+     417             :     value=0.0;
+     418        7978 :     for(unsigned int i=0; i<dimension_; ++i) der[i]=0.0;
+     419             : 
+     420        3621 :     std::vector<unsigned> indices(dimension_);
+     421        3621 :     getIndices(x, indices);
+     422        3621 :     std::vector<double> xfloor(dimension_);
+     423        3621 :     getPoint(indices, xfloor);
+     424        3621 :     std::vector<index_t> neigh; unsigned nneigh; getSplineNeighbors(indices, neigh, nneigh);
+     425             : 
+     426             : // loop over neighbors
+     427             :     std::vector<unsigned> nindices;
+     428       12333 :     for(unsigned int ipoint=0; ipoint<nneigh; ++ipoint) {
+     429        8712 :       double grid=getValueAndDerivatives(neigh[ipoint],dder);
+     430        8712 :       getIndices(neigh[ipoint], nindices);
+     431             :       double ff=1.0;
+     432             : 
+     433       20368 :       for(unsigned j=0; j<dimension_; ++j) {
+     434             :         int x0=1;
+     435       11656 :         if(nindices[j]==indices[j]) x0=0;
+     436       11656 :         double dx=getDx(j);
+     437       11656 :         X=std::abs((x[j]-xfloor[j])/dx-(double)x0);
+     438       11656 :         X2=X*X;
+     439       11656 :         X3=X2*X;
+     440             :         double yy;
+     441       11656 :         if(std::abs(grid)<0.0000001) yy=0.0;
+     442        8888 :         else yy=-dder[j]/grid;
+     443       11656 :         C[j]=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*dx;
+     444       11656 :         D[j]=( -6.0*X +6.0*X2) - (x0?-1.0:1.0)*yy*(1.0-4.0*X +3.0*X2)*dx;
+     445       11656 :         D[j]*=(x0?-1.0:1.0)/dx;
+     446       11656 :         ff*=C[j];
+     447             :       }
+     448       20368 :       for(unsigned j=0; j<dimension_; ++j) {
+     449       11656 :         fd[j]=D[j];
+     450       29200 :         for(unsigned i=0; i<dimension_; ++i) if(i!=j) fd[j]*=C[i];
+     451             :       }
+     452        8712 :       value+=grid*ff;
+     453       20368 :       for(unsigned j=0; j<dimension_; ++j) der[j]+=grid*fd[j];
+     454             :     }
+     455             :     return value;
+     456             :   } else {
+     457           0 :     return getValueAndDerivatives(getIndex(x),der);
+     458             :   }
+     459             : }
+     460             : 
+     461           0 : void GridBase::setValue(const std::vector<unsigned> & indices, double value) {
+     462           0 :   setValue(getIndex(indices),value);
+     463           0 : }
+     464             : 
+     465           0 : void GridBase::setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der) {
+     466           0 :   setValueAndDerivatives(getIndex(indices),value,der);
+     467           0 : }
+     468             : 
+     469           0 : void GridBase::addValue(const std::vector<unsigned> & indices, double value) {
+     470           0 :   addValue(getIndex(indices),value);
+     471           0 : }
+     472             : 
+     473           0 : void GridBase::addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der) {
+     474           0 :   addValueAndDerivatives(getIndex(indices),value,der);
+     475           0 : }
+     476             : 
+     477        1146 : void GridBase::writeHeader(OFile& ofile) {
+     478        2608 :   for(unsigned i=0; i<dimension_; ++i) {
+     479        2924 :     ofile.addConstantField("min_" + argnames[i]);
+     480        2924 :     ofile.addConstantField("max_" + argnames[i]);
+     481        2924 :     ofile.addConstantField("nbins_" + argnames[i]);
+     482        2924 :     ofile.addConstantField("periodic_" + argnames[i]);
+     483             :   }
+     484        1146 : }
+     485             : 
+     486           1 : void Grid::clear() {
+     487           1 :   grid_.assign(maxsize_,0.0);
+     488           1 :   if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     489           1 : }
+     490             : 
+     491        1146 : void Grid::writeToFile(OFile& ofile) {
+     492        1146 :   std::vector<double> xx(dimension_);
+     493        1146 :   std::vector<double> der(dimension_);
+     494             :   double f;
+     495        1146 :   writeHeader(ofile);
+     496     2533378 :   for(index_t i=0; i<getSize(); ++i) {
+     497     2532232 :     xx=getPoint(i);
+     498     2532232 :     if(usederiv_) {f=getValueAndDerivatives(i,der);}
+     499     1989707 :     else {f=getValue(i);}
+     500     4914837 :     if(i>0 && dimension_>1 && getIndices(i)[dimension_-2]==0) ofile.printf("\n");
+     501     7484425 :     for(unsigned j=0; j<dimension_; ++j) {
+     502     9904386 :       ofile.printField("min_" + argnames[j], str_min_[j] );
+     503     9904386 :       ofile.printField("max_" + argnames[j], str_max_[j] );
+     504     9904386 :       ofile.printField("nbins_" + argnames[j], static_cast<int>(nbin_[j]) );
+     505     6986541 :       if( pbc_[j] ) ofile.printField("periodic_" + argnames[j], "true" );
+     506     5835690 :       else          ofile.printField("periodic_" + argnames[j], "false" );
+     507             :     }
+     508     7484425 :     for(unsigned j=0; j<dimension_; ++j) { ofile.fmtField(" "+fmt_); ofile.printField(argnames[j],xx[j]); }
+     509     5064464 :     ofile.fmtField(" "+fmt_); ofile.printField(funcname,f);
+     510     5194099 :     if(usederiv_) for(unsigned j=0; j<dimension_; ++j) { ofile.fmtField(" "+fmt_); ofile.printField("der_" + argnames[j],der[j]); }
+     511     2532232 :     ofile.printField();
+     512             :   }
+     513        1146 : }
+     514             : 
+     515           0 : void GridBase::writeCubeFile(OFile& ofile, const double& lunit) {
+     516           0 :   plumed_assert( dimension_==3 );
+     517           0 :   ofile.printf("PLUMED CUBE FILE\n");
+     518           0 :   ofile.printf("OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n");
+     519             :   // Number of atoms followed by position of origin (origin set so that center of grid is in center of cell)
+     520           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]));
+     521           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
+     522           0 :   ofile.printf("%u %f %f %f\n",nbin_[1],0.0,lunit*dx_[1],0.0);  // shape of voxel
+     523           0 :   ofile.printf("%u %f %f %f\n",nbin_[2],0.0,0.0,lunit*dx_[2]);
+     524           0 :   ofile.printf("%d %f %f %f\n",1,0.0,0.0,0.0); // Fake atom otherwise VMD doesn't work
+     525           0 :   std::vector<unsigned> pp(3);
+     526           0 :   for(pp[0]=0; pp[0]<nbin_[0]; ++pp[0]) {
+     527           0 :     for(pp[1]=0; pp[1]<nbin_[1]; ++pp[1]) {
+     528           0 :       for(pp[2]=0; pp[2]<nbin_[2]; ++pp[2]) {
+     529           0 :         ofile.printf("%f ",getValue(pp) );
+     530           0 :         if(pp[2]%6==5) ofile.printf("\n");
+     531             :       }
+     532           0 :       ofile.printf("\n");
+     533             :     }
+     534             :   }
+     535           0 : }
+     536             : 
+     537          20 : std::unique_ptr<GridBase> GridBase::create(const std::string& funcl, const std::vector<Value*> & args, IFile& ifile,
+     538             :     const std::vector<std::string> & gmin,const std::vector<std::string> & gmax,
+     539             :     const std::vector<unsigned> & nbin,bool dosparse, bool dospline, bool doder) {
+     540          20 :   std::unique_ptr<GridBase> grid=GridBase::create(funcl,args,ifile,dosparse,dospline,doder);
+     541          20 :   std::vector<unsigned> cbin( grid->getNbin() );
+     542          20 :   std::vector<std::string> cmin( grid->getMin() ), cmax( grid->getMax() );
+     543          49 :   for(unsigned i=0; i<args.size(); ++i) {
+     544          29 :     plumed_massert( cmin[i]==gmin[i], "mismatched grid min" );
+     545          29 :     plumed_massert( cmax[i]==gmax[i], "mismatched grid max" );
+     546          29 :     if( args[i]->isPeriodic() ) {
+     547           8 :       plumed_massert( cbin[i]==nbin[i], "mismatched grid nbins" );
+     548             :     } else {
+     549          21 :       plumed_massert( (cbin[i]-1)==nbin[i], "mismatched grid nbins");
+     550             :     }
+     551             :   }
+     552          20 :   return grid;
+     553          20 : }
+     554             : 
+     555          70 : std::unique_ptr<GridBase> GridBase::create(const std::string& funcl, const std::vector<Value*> & args, IFile& ifile, bool dosparse, bool dospline, bool doder)
+     556             : {
+     557          70 :   std::unique_ptr<GridBase> grid;
+     558          70 :   unsigned nvar=args.size(); bool hasder=false; std::string pstring;
+     559          70 :   std::vector<int> gbin1(nvar); std::vector<unsigned> gbin(nvar);
+     560          70 :   std::vector<std::string> labels(nvar),gmin(nvar),gmax(nvar);
+     561          70 :   std::vector<std::string> fieldnames; ifile.scanFieldList( fieldnames );
+     562             : // Retrieve names for fields
+     563         158 :   for(unsigned i=0; i<args.size(); ++i) labels[i]=args[i]->getName();
+     564             : // And read the stuff from the header
+     565          70 :   plumed_massert( ifile.FieldExist( funcl ), "no column labelled " + funcl + " in in grid input");
+     566         158 :   for(unsigned i=0; i<args.size(); ++i) {
+     567         176 :     ifile.scanField( "min_" + labels[i], gmin[i]);
+     568         176 :     ifile.scanField( "max_" + labels[i], gmax[i]);
+     569         176 :     ifile.scanField( "periodic_" + labels[i], pstring );
+     570         176 :     ifile.scanField( "nbins_" + labels[i], gbin1[i]);
+     571          88 :     plumed_assert( gbin1[i]>0 );
+     572          88 :     if( args[i]->isPeriodic() ) {
+     573          26 :       plumed_massert( pstring=="true", "input value is periodic but grid is not");
+     574             :       std::string pmin, pmax;
+     575          26 :       args[i]->getDomain( pmin, pmax ); gbin[i]=gbin1[i];
+     576          26 :       if( pmin!=gmin[i] || pmax!=gmax[i] ) plumed_merror("mismatch between grid boundaries and periods of values");
+     577             :     } else {
+     578          62 :       gbin[i]=gbin1[i]-1;  // Note header in grid file indicates one more bin that there should be when data is not periodic
+     579          62 :       plumed_massert( pstring=="false", "input value is not periodic but grid is");
+     580             :     }
+     581          88 :     hasder=ifile.FieldExist( "der_" + args[i]->getName() );
+     582          88 :     if( doder && !hasder ) plumed_merror("missing derivatives from grid file");
+     583         106 :     for(unsigned j=0; j<fieldnames.size(); ++j) {
+     584         124 :       for(unsigned k=i+1; k<args.size(); ++k) {
+     585          18 :         if( fieldnames[j]==labels[k] ) plumed_merror("arguments in input are not in same order as in grid file");
+     586             :       }
+     587         106 :       if( fieldnames[j]==labels[i] ) break;
+     588             :     }
+     589             :   }
+     590             : 
+     591          70 :   if(!dosparse) {grid=Tools::make_unique<Grid>(funcl,args,gmin,gmax,gbin,dospline,doder);}
+     592           0 :   else {grid=Tools::make_unique<SparseGrid>(funcl,args,gmin,gmax,gbin,dospline,doder);}
+     593             : 
+     594          70 :   std::vector<double> xx(nvar),dder(nvar);
+     595          70 :   std::vector<double> dx=grid->getDx();
+     596             :   double f,x;
+     597     1099575 :   while( ifile.scanField(funcl,f) ) {
+     598     3294553 :     for(unsigned i=0; i<nvar; ++i) {
+     599     2195048 :       ifile.scanField(labels[i],x); xx[i]=x+dx[i]/2.0;
+     600     4390096 :       ifile.scanField( "min_" + labels[i], gmin[i]);
+     601     4390096 :       ifile.scanField( "max_" + labels[i], gmax[i]);
+     602     4390096 :       ifile.scanField( "nbins_" + labels[i], gbin1[i]);
+     603     4390096 :       ifile.scanField( "periodic_" + labels[i], pstring );
+     604             :     }
+     605     3211140 :     if(hasder) { for(unsigned i=0; i<nvar; ++i) { ifile.scanField( "der_" + args[i]->getName(), dder[i] ); } }
+     606     1099505 :     index_t index=grid->getIndex(xx);
+     607     1099505 :     if(doder) {grid->setValueAndDerivatives(index,f,dder);}
+     608       42717 :     else {grid->setValue(index,f);}
+     609     1099505 :     ifile.scanField();
+     610             :   }
+     611          70 :   return grid;
+     612          70 : }
+     613             : 
+     614         861 : double Grid::getMinValue() const {
+     615             :   double minval;
+     616             :   minval=DBL_MAX;
+     617     2258311 :   for(index_t i=0; i<grid_.size(); ++i) {
+     618     2257450 :     if(grid_[i]<minval)minval=grid_[i];
+     619             :   }
+     620         861 :   return minval;
+     621             : }
+     622             : 
+     623         629 : double Grid::getMaxValue() const {
+     624             :   double maxval;
+     625             :   maxval=DBL_MIN;
+     626     3755246 :   for(index_t i=0; i<grid_.size(); ++i) {
+     627     3754617 :     if(grid_[i]>maxval)maxval=grid_[i];
+     628             :   }
+     629         629 :   return maxval;
+     630             : }
+     631             : 
+     632         594 : void Grid::scaleAllValuesAndDerivatives( const double& scalef ) {
+     633         594 :   if(usederiv_) {
+     634       21474 :     for(index_t i=0; i<grid_.size(); ++i) {
+     635       21463 :       grid_[i]*=scalef;
+     636       63888 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j]*=scalef;
+     637             :     }
+     638             :   } else {
+     639     1572834 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i]*=scalef;
+     640             :   }
+     641         594 : }
+     642             : 
+     643           0 : void Grid::logAllValuesAndDerivatives( const double& scalef ) {
+     644           0 :   if(usederiv_) {
+     645           0 :     for(index_t i=0; i<grid_.size(); ++i) {
+     646           0 :       grid_[i] = scalef*std::log(grid_[i]);
+     647           0 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j] = scalef/der_[i*dimension_+j];
+     648             :     }
+     649             :   } else {
+     650           0 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i] = scalef*std::log(grid_[i]);
+     651             :   }
+     652           0 : }
+     653             : 
+     654        1329 : void Grid::setMinToZero() {
+     655        1329 :   double min=grid_[0];
+     656     3518541 :   for(index_t i=1; i<grid_.size(); ++i) if(grid_[i]<min) min=grid_[i];
+     657     3519870 :   for(index_t i=0; i<grid_.size(); ++i) grid_[i] -= min;
+     658        1329 : }
+     659             : 
+     660           1 : void Grid::applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) ) {
+     661           1 :   if(usederiv_) {
+     662         901 :     for(index_t i=0; i<grid_.size(); ++i) {
+     663         900 :       grid_[i]=func(grid_[i]);
+     664        2700 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j]=funcder(der_[i*dimension_+j]);
+     665             :     }
+     666             :   } else {
+     667           0 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i]=func(grid_[i]);
+     668             :   }
+     669           1 : }
+     670             : 
+     671           0 : double Grid::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) const {
+     672           0 :   return getValueAndDerivatives( x, der ) - contour_location;
+     673             : }
+     674             : 
+     675           0 : void Grid::findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch,
+     676             :                                     unsigned& npoints, std::vector<std::vector<double> >& points ) {
+     677             : // Set contour location for function
+     678           0 :   contour_location=target;
+     679             : // Resize points to maximum possible value
+     680           0 :   points.resize( dimension_*maxsize_ );
+     681             : 
+     682             : // Two points for search
+     683           0 :   std::vector<unsigned> ind(dimension_);
+     684           0 :   std::vector<double> direction( dimension_, 0 );
+     685             : 
+     686             : // Run over whole grid
+     687           0 :   npoints=0; RootFindingBase<Grid> mymin( this );
+     688           0 :   for(unsigned i=0; i<maxsize_; ++i) {
+     689           0 :     for(unsigned j=0; j<dimension_; ++j) ind[j]=getIndices(i)[j];
+     690             : 
+     691             :     // Get the value of a point on the grid
+     692           0 :     double val1=getValue(i) - target;
+     693             : 
+     694             :     // Now search for contour in each direction
+     695             :     bool edge=false;
+     696           0 :     for(unsigned j=0; j<dimension_; ++j) {
+     697           0 :       if( nosearch[j] ) continue ;
+     698             :       // Make sure we don't search at the edge of the grid
+     699           0 :       if( !pbc_[j] && (ind[j]+1)==nbin_[j] ) continue;
+     700           0 :       else if( (ind[j]+1)==nbin_[j] ) { edge=true; ind[j]=0; }
+     701           0 :       else ind[j]+=1;
+     702           0 :       double val2=getValue(ind) - target;
+     703           0 :       if( val1*val2<0 ) {
+     704             :         // Use initial point location as first guess for search
+     705           0 :         points[npoints].resize(dimension_); for(unsigned k=0; k<dimension_; ++k) points[npoints][k]=getPoint(i)[k];
+     706             :         // Setup direction vector
+     707           0 :         direction[j]=0.999999999*dx_[j];
+     708             :         // And do proper search for contour point
+     709           0 :         mymin.linesearch( direction, points[npoints], &Grid::getDifferenceFromContour );
+     710           0 :         direction[j]=0.0; npoints++;
+     711             :       }
+     712           0 :       if( pbc_[j] && edge ) { edge=false; ind[j]=nbin_[j]-1; }
+     713           0 :       else ind[j]-=1;
+     714             :     }
+     715             :   }
+     716           0 : }
+     717             : 
+     718             : /// OVERRIDES ARE BELOW
+     719             : 
+     720    28865188 : Grid::index_t Grid::getSize() const {
+     721    28865188 :   return maxsize_;
+     722             : }
+     723             : 
+     724    27284983 : double Grid::getValue(index_t index) const {
+     725             :   plumed_dbg_assert(index<maxsize_);
+     726    27284983 :   return grid_[index];
+     727             : }
+     728             : 
+     729     3079545 : double Grid::getValueAndDerivatives(index_t index, std::vector<double>& der) const {
+     730             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     731     3079545 :   der.resize(dimension_);
+     732     6679000 :   for(unsigned i=0; i<dimension_; i++) der[i]=der_[dimension_*index+i];
+     733     3079545 :   return grid_[index];
+     734             : }
+     735             : 
+     736     6444104 : void Grid::setValue(index_t index, double value) {
+     737             :   plumed_dbg_assert(index<maxsize_ && !usederiv_);
+     738     6444104 :   grid_[index]=value;
+     739     6444104 : }
+     740             : 
+     741     2552369 : void Grid::setValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     742             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     743     2552369 :   grid_[index]=value;
+     744     7609163 :   for(unsigned i=0; i<dimension_; i++) der_[dimension_*index+i]=der[i];
+     745     2552369 : }
+     746             : 
+     747           1 : void Grid::addValue(index_t index, double value) {
+     748             :   plumed_dbg_assert(index<maxsize_ && !usederiv_);
+     749           1 :   grid_[index]+=value;
+     750           1 : }
+     751             : 
+     752     1170278 : void Grid::addValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     753             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     754     1170278 :   grid_[index]+=value;
+     755     3497419 :   for(unsigned int i=0; i<dimension_; ++i) der_[index*dimension_+i]+=der[i];
+     756     1170278 : }
+     757             : 
+     758           0 : Grid::index_t SparseGrid::getSize() const {
+     759           0 :   return map_.size();
+     760             : }
+     761             : 
+     762           0 : Grid::index_t SparseGrid::getMaxSize() const {
+     763           0 :   return maxsize_;
+     764             : }
+     765             : 
+     766           0 : double SparseGrid::getValue(index_t index)const {
+     767           0 :   plumed_assert(index<maxsize_);
+     768             :   double value=0.0;
+     769             :   const auto it=map_.find(index);
+     770           0 :   if(it!=map_.end()) value=it->second;
+     771           0 :   return value;
+     772             : }
+     773             : 
+     774         200 : double SparseGrid::getValueAndDerivatives(index_t index, std::vector<double>& der)const {
+     775         200 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     776             :   double value=0.0;
+     777         580 :   for(unsigned int i=0; i<dimension_; ++i) der[i]=0.0;
+     778             :   const auto it=map_.find(index);
+     779         200 :   if(it!=map_.end()) value=it->second;
+     780             :   const auto itder=der_.find(index);
+     781         200 :   if(itder!=der_.end()) der=itder->second;
+     782         200 :   return value;
+     783             : }
+     784             : 
+     785           0 : void SparseGrid::setValue(index_t index, double value) {
+     786           0 :   plumed_assert(index<maxsize_ && !usederiv_);
+     787           0 :   map_[index]=value;
+     788           0 : }
+     789             : 
+     790           0 : void SparseGrid::setValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     791           0 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     792           0 :   map_[index]=value;
+     793           0 :   der_[index]=der;
+     794           0 : }
+     795             : 
+     796           0 : void SparseGrid::addValue(index_t index, double value) {
+     797           0 :   plumed_assert(index<maxsize_ && !usederiv_);
+     798           0 :   map_[index]+=value;
+     799           0 : }
+     800             : 
+     801       19999 : void SparseGrid::addValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     802       19999 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     803       19999 :   map_[index]+=value;
+     804       19999 :   der_[index].resize(dimension_);
+     805       59682 :   for(unsigned int i=0; i<dimension_; ++i) der_[index][i]+=der[i];
+     806       19999 : }
+     807             : 
+     808           0 : void SparseGrid::writeToFile(OFile& ofile) {
+     809           0 :   std::vector<double> xx(dimension_);
+     810           0 :   std::vector<double> der(dimension_);
+     811             :   double f;
+     812           0 :   writeHeader(ofile);
+     813           0 :   ofile.fmtField(" "+fmt_);
+     814           0 :   for(const auto & it : map_) {
+     815           0 :     index_t i=it.first;
+     816           0 :     xx=getPoint(i);
+     817           0 :     if(usederiv_) {f=getValueAndDerivatives(i,der);}
+     818           0 :     else {f=getValue(i);}
+     819           0 :     if(i>0 && dimension_>1 && getIndices(i)[dimension_-2]==0) ofile.printf("\n");
+     820           0 :     for(unsigned j=0; j<dimension_; ++j) {
+     821           0 :       ofile.printField("min_" + argnames[j], str_min_[j] );
+     822           0 :       ofile.printField("max_" + argnames[j], str_max_[j] );
+     823           0 :       ofile.printField("nbins_" + argnames[j], static_cast<int>(nbin_[j]) );
+     824           0 :       if( pbc_[j] ) ofile.printField("periodic_" + argnames[j], "true" );
+     825           0 :       else          ofile.printField("periodic_" + argnames[j], "false" );
+     826             :     }
+     827           0 :     for(unsigned j=0; j<dimension_; ++j) ofile.printField(argnames[j],xx[j]);
+     828           0 :     ofile.printField(funcname, f);
+     829           0 :     if(usederiv_) { for(unsigned j=0; j<dimension_; ++j) ofile.printField("der_" + argnames[j],der[j]); }
+     830           0 :     ofile.printField();
+     831             :   }
+     832           0 : }
+     833             : 
+     834           0 : double SparseGrid::getMinValue() const {
+     835             :   double minval;
+     836             :   minval=0.0;
+     837           0 :   for(auto const & i : map_) {
+     838           0 :     if(i.second<minval) minval=i.second;
+     839             :   }
+     840           0 :   return minval;
+     841             : }
+     842             : 
+     843           9 : double SparseGrid::getMaxValue() const {
+     844             :   double maxval;
+     845             :   maxval=0.0;
+     846         590 :   for(auto const & i : map_) {
+     847         581 :     if(i.second>maxval) maxval=i.second;
+     848             :   }
+     849           9 :   return maxval;
+     850             : }
+     851             : 
+     852     1010062 : void Grid::projectOnLowDimension(double &val, std::vector<int> &vHigh, WeightBase * ptr2obj ) {
+     853             :   unsigned i=0;
+     854     3016945 :   for(i=0; i<vHigh.size(); i++) {
+     855     2015726 :     if(vHigh[i]<0) { // this bin needs to be integrated out
+     856             :       // parallelize here???
+     857     2020124 :       for(unsigned j=0; j<(getNbin())[i]; j++) {
+     858     1001219 :         vHigh[i]=int(j);
+     859     1001219 :         projectOnLowDimension(val,vHigh,ptr2obj); // recursive function: this is the core of the mechanism
+     860     1001219 :         vHigh[i]=-1;
+     861             :       }
+     862             :       return; //
+     863             :     }
+     864             :   }
+     865             :   // when there are no more bin to dig in then retrieve the value
+     866     1001219 :   if(i==vHigh.size()) {
+     867             :     //std::cerr<<"POINT: ";
+     868             :     //for(unsigned j=0;j<vHigh.size();j++){
+     869             :     //   std::cerr<<vHigh[j]<<" ";
+     870             :     //}
+     871     1001219 :     std::vector<unsigned> vv(vHigh.size());
+     872     3003657 :     for(unsigned j=0; j<vHigh.size(); j++)vv[j]=unsigned(vHigh[j]);
+     873             :     //
+     874             :     // this is the real assignment !!!!! (hack this to have bias or other stuff)
+     875             :     //
+     876             : 
+     877             :     // this case: produce fes
+     878             :     //val+=exp(beta*getValue(vv)) ;
+     879     1001219 :     double myv=getValue(vv);
+     880     1001219 :     val=ptr2obj->projectInnerLoop(val,myv) ;
+     881             :     // to be added: bias (same as before without negative sign)
+     882             :     //std::cerr<<" VAL: "<<val <<endl;
+     883             :   }
+     884             : }
+     885             : 
+     886          81 : Grid Grid::project(const std::vector<std::string> & proj, WeightBase *ptr2obj ) {
+     887             :   // find extrema only for the projection
+     888             :   std::vector<std::string>   smallMin,smallMax;
+     889             :   std::vector<unsigned> smallBin;
+     890             :   std::vector<unsigned> dimMapping;
+     891             :   std::vector<bool> smallIsPeriodic;
+     892             :   std::vector<std::string> smallName;
+     893             : 
+     894             :   // check if the two key methods are there
+     895             :   WeightBase* pp = dynamic_cast<WeightBase*>(ptr2obj);
+     896          81 :   if (!pp)plumed_merror("This WeightBase is not complete: you need a projectInnerLoop and projectOuterLoop ");
+     897             : 
+     898         162 :   for(unsigned j=0; j<proj.size(); j++) {
+     899         120 :     for(unsigned i=0; i<getArgNames().size(); i++) {
+     900         120 :       if(proj[j]==getArgNames()[i]) {
+     901             :         unsigned offset;
+     902             :         // note that at sizetime the non periodic dimension get a bin more
+     903         162 :         if(getIsPeriodic()[i]) {offset=0;} else {offset=1;}
+     904          81 :         smallMax.push_back(getMax()[i]);
+     905          81 :         smallMin.push_back(getMin()[i]);
+     906          81 :         smallBin.push_back(getNbin()[i]-offset);
+     907         162 :         smallIsPeriodic.push_back(getIsPeriodic()[i]);
+     908          81 :         dimMapping.push_back(i);
+     909          81 :         smallName.push_back(getArgNames()[i]);
+     910          81 :         break;
+     911             :       }
+     912             :     }
+     913             :   }
+     914          81 :   Grid smallgrid("projection",smallName,smallMin,smallMax,smallBin,false,false,smallIsPeriodic,smallMin,smallMax);
+     915             :   // check that the two grids are commensurate
+     916         162 :   for(unsigned i=0; i<dimMapping.size(); i++) {
+     917          81 :     plumed_massert(  (smallgrid.getMax())[i] == (getMax())[dimMapping[i]],  "the two input grids are not compatible in max"   );
+     918          81 :     plumed_massert(  (smallgrid.getMin())[i] == (getMin())[dimMapping[i]],  "the two input grids are not compatible in min"   );
+     919         243 :     plumed_massert(  (smallgrid.getNbin())[i]== (getNbin())[dimMapping[i]], "the two input grids are not compatible in bin"   );
+     920             :   }
+     921             :   std::vector<unsigned> toBeIntegrated;
+     922         243 :   for(unsigned i=0; i<getArgNames().size(); i++) {
+     923             :     bool doappend=true;
+     924         243 :     for(unsigned j=0; j<dimMapping.size(); j++) {
+     925         162 :       if(dimMapping[j]==i) {doappend=false; break;}
+     926             :     }
+     927         162 :     if(doappend)toBeIntegrated.push_back(i);
+     928             :   }
+     929             : 
+     930             :   // loop over all the points in the Grid, find the corresponding fixed index, rotate over all the other ones
+     931        8924 :   for(unsigned i=0; i<smallgrid.getSize(); i++) {
+     932             :     std::vector<unsigned> v;
+     933        8843 :     v=smallgrid.getIndices(i);
+     934        8843 :     std::vector<int> vHigh((getArgNames()).size(),-1);
+     935       17686 :     for(unsigned j=0; j<dimMapping.size(); j++)vHigh[dimMapping[j]]=int(v[j]);
+     936             :     // the vector vhigh now contains at the beginning the index of the low dimension and -1 for the values that need to be integrated
+     937        8843 :     double initval=0.;
+     938        8843 :     projectOnLowDimension(initval,vHigh, ptr2obj);
+     939        8843 :     smallgrid.setValue(i,ptr2obj->projectOuterLoop(initval));
+     940             :   }
+     941             : 
+     942          81 :   return smallgrid;
+     943         162 : }
+     944             : 
+     945           0 : double Grid::integrate( std::vector<unsigned>& npoints ) {
+     946           0 :   plumed_dbg_assert( npoints.size()==dimension_ ); plumed_assert( dospline_ );
+     947             : 
+     948             :   unsigned ntotgrid=1; double box_vol=1.0;
+     949           0 :   std::vector<double> ispacing( npoints.size() );
+     950           0 :   for(unsigned j=0; j<dimension_; ++j) {
+     951           0 :     if( !pbc_[j] ) {
+     952           0 :       ispacing[j] = ( max_[j] - dx_[j] - min_[j] ) / static_cast<double>( npoints[j] );
+     953           0 :       npoints[j]+=1;
+     954             :     } else {
+     955           0 :       ispacing[j] = ( max_[j] - min_[j] ) / static_cast<double>( npoints[j] );
+     956             :     }
+     957           0 :     ntotgrid*=npoints[j]; box_vol*=ispacing[j];
+     958             :   }
+     959             : 
+     960           0 :   std::vector<double> vals( dimension_ );
+     961           0 :   std::vector<unsigned> t_index( dimension_ ); double integral=0.0;
+     962           0 :   for(unsigned i=0; i<ntotgrid; ++i) {
+     963           0 :     t_index[0]=(i%npoints[0]);
+     964             :     unsigned kk=i;
+     965           0 :     for(unsigned j=1; j<dimension_-1; ++j) { kk=(kk-t_index[j-1])/npoints[j-1]; t_index[j]=(kk%npoints[j]); }
+     966           0 :     if( dimension_>=2 ) t_index[dimension_-1]=((kk-t_index[dimension_-2])/npoints[dimension_-2]);
+     967             : 
+     968           0 :     for(unsigned j=0; j<dimension_; ++j) vals[j]=min_[j] + t_index[j]*ispacing[j];
+     969             : 
+     970           0 :     integral += getValue( vals );
+     971             :   }
+     972             : 
+     973           0 :   return box_vol*integral;
+     974             : }
+     975             : 
+     976           0 : void Grid::mpiSumValuesAndDerivatives( Communicator& comm ) {
+     977           0 :   comm.Sum( grid_ ); for(unsigned i=0; i<der_.size(); ++i) comm.Sum( der_[i] );
+     978           0 : }
+     979             : 
+     980             : 
+     981       59573 : bool indexed_lt(std::pair<Grid::index_t, double> const &x, std::pair<Grid::index_t, double> const   &y) {
+     982       59573 :   return x.second < y.second;
+     983             : }
+     984             : 
+     985         273 : double GridBase::findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink) {
+     986             :   plumed_dbg_assert(source.size() == dimension_);
+     987             :   plumed_dbg_assert(sink.size() == dimension_);
+     988             :   // Start and end indices
+     989         273 :   index_t source_idx = getIndex(source);
+     990         273 :   index_t sink_idx = getIndex(sink);
+     991             :   // Path cost
+     992             :   double maximal_minimum = 0;
+     993             :   // In one dimension, path searching is very easy--either go one way if it's not periodic,
+     994             :   // or go both ways if it is periodic. There's no reason to pay the cost of Dijkstra.
+     995         273 :   if (dimension_ == 1) {
+     996             :     // Do a search from the grid source to grid sink that does not
+     997             :     // cross the grid boundary.
+     998         147 :     double curr_min_bias = getValue(source_idx);
+     999             :     // Either search from a high source to a low sink.
+    1000         147 :     if (source_idx > sink_idx) {
+    1001         735 :       for (index_t i = source_idx; i >= sink_idx; i--) {
+    1002         588 :         if (curr_min_bias == 0.0) {
+    1003             :           break;
+    1004             :         }
+    1005         588 :         curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1006             :       }
+    1007             :       // Or search from a low source to a high sink.
+    1008           0 :     } else if (source_idx < sink_idx) {
+    1009           0 :       for (index_t i = source_idx; i <= sink_idx; i++) {
+    1010           0 :         if (curr_min_bias == 0.0) {
+    1011             :           break;
+    1012             :         }
+    1013           0 :         curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1014             :       }
+    1015             :     }
+    1016             :     maximal_minimum = curr_min_bias;
+    1017             :     // If the grid is periodic, also do the search that crosses
+    1018             :     // the grid boundary.
+    1019         147 :     if (pbc_[0]) {
+    1020          42 :       double curr_min_bias = getValue(source_idx);
+    1021             :       // Either go from a high source to the upper boundary and
+    1022             :       // then from the bottom boundary to the sink
+    1023          42 :       if (source_idx > sink_idx) {
+    1024         210 :         for (index_t i = source_idx; i < maxsize_; i++) {
+    1025         168 :           if (curr_min_bias == 0.0) {
+    1026             :             break;
+    1027             :           }
+    1028         168 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1029             :         }
+    1030         210 :         for (index_t i = 0; i <= sink_idx; i++) {
+    1031         168 :           if (curr_min_bias == 0.0) {
+    1032             :             break;
+    1033             :           }
+    1034         168 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1035             :         }
+    1036             :         // Or go from a low source to the bottom boundary and
+    1037             :         // then from the high boundary to the sink
+    1038           0 :       } else if (source_idx < sink_idx) {
+    1039           0 :         for (index_t i = source_idx; i > 0; i--) {
+    1040           0 :           if (curr_min_bias == 0.0) {
+    1041             :             break;
+    1042             :           }
+    1043           0 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1044             :         }
+    1045           0 :         curr_min_bias = fmin(curr_min_bias, getValue(0));
+    1046           0 :         for (index_t i = maxsize_ - 1; i <= sink_idx; i--) {
+    1047           0 :           if (curr_min_bias == 0.0) {
+    1048             :             break;
+    1049             :           }
+    1050           0 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1051             :         }
+    1052             :       }
+    1053             :       // If the boundary crossing paths was more biased, it's
+    1054             :       // minimal bias replaces the non-boundary-crossing path's
+    1055             :       // minimum.
+    1056          42 :       maximal_minimum = fmax(maximal_minimum, curr_min_bias);
+    1057             :     }
+    1058             :     // The one dimensional path search is complete.
+    1059         147 :     return maximal_minimum;
+    1060             :     // In two or more dimensions, path searching isn't trivial and we really
+    1061             :     // do need to use a path search algorithm. Dijkstra is the simplest decent
+    1062             :     // one. Using it we've never found the path search to be performance
+    1063             :     // limiting in any solvated biomolecule test system, but faster options are
+    1064             :     // easy to imagine if they become necessary. NB-In this case, we're actually
+    1065             :     // using a greedy variant of Dijkstra's algorithm where the first possible
+    1066             :     // path to a point always controls the path cost to that point. The structure
+    1067             :     // of the cost function in this case guarantees that the calculated costs will
+    1068             :     // be correct using this variant even though fine details of the paths may not
+    1069             :     // match a normal Dijkstra search.
+    1070         126 :   } else if (dimension_ > 1) {
+    1071             :     // Prepare calculation temporaries for Dijkstra's algorithm.
+    1072             :     // Minimal path costs from source to a given grid point
+    1073         126 :     std::vector<double> mins_from_source = std::vector<double>(maxsize_, -1.0);
+    1074             :     // Heap for tracking available steps, steps are recorded as std::pairs of
+    1075             :     // an index and a value.
+    1076             :     std::vector< std::pair<index_t, double> > next_steps;
+    1077             :     std::pair<index_t, double> curr_indexed_val;
+    1078         126 :     std::make_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1079             :     // The search begins at the source index.
+    1080         252 :     next_steps.push_back(std::pair<index_t, double>(source_idx, getValue(source_idx)));
+    1081         126 :     std::push_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1082             :     // At first no points have been examined and the optimal path has not been found.
+    1083             :     index_t n_examined = 0;
+    1084             :     bool path_not_found = true;
+    1085             :     // Until a path is found,
+    1086             :     while (path_not_found) {
+    1087             :       // Examine the grid point currently most accessible from
+    1088             :       // the set of all previously explored grid points by popping
+    1089             :       // it from the top of the heap.
+    1090        9702 :       std::pop_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1091             :       curr_indexed_val = next_steps.back();
+    1092             :       next_steps.pop_back();
+    1093             :       n_examined++;
+    1094             :       // Check if this point is the sink point, and if so
+    1095             :       // finish the loop.
+    1096        9702 :       if (curr_indexed_val.first == sink_idx) {
+    1097             :         path_not_found = false;
+    1098             :         maximal_minimum = curr_indexed_val.second;
+    1099         126 :         break;
+    1100             :         // Check if this point has reached the worst possible
+    1101             :         // value, and if so stop looking for paths.
+    1102        9576 :       } else if (curr_indexed_val.second == 0.0) {
+    1103             :         maximal_minimum = 0.0;
+    1104             :         break;
+    1105             :       }
+    1106             :       // If the search is not over, add this grid point's neighbors to the
+    1107             :       // possible next points to search for the sink.
+    1108        9576 :       std::vector<index_t> neighs = getNearestNeighbors(curr_indexed_val.first);
+    1109       46246 :       for (unsigned k = 0; k < neighs.size(); k++) {
+    1110       36670 :         index_t i = neighs[k];
+    1111             :         // If the neighbor has not already been added to the list of possible next steps,
+    1112       36670 :         if (mins_from_source[i] == -1.0) {
+    1113             :           // Set the cost to reach it via a path through the current point being examined.
+    1114       12284 :           mins_from_source[i] = fmin(curr_indexed_val.second, getValue(i));
+    1115             :           // Add the neighboring point to the heap of potential next steps.
+    1116       12284 :           next_steps.push_back(std::pair<index_t, double>(i, mins_from_source[i]));
+    1117       12284 :           std::push_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1118             :         }
+    1119             :       }
+    1120             :       // Move on to the next best looking step along any of the paths
+    1121             :       // growing from the source.
+    1122             :     }
+    1123             :     // The multidimensional path search is now complete.
+    1124             :     return maximal_minimum;
+    1125             :   }
+    1126             :   return 0.0;
+    1127             : }
+    1128             : 
+    1129             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..c2b98c75a7 --- /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-06-10 08:19:14Functions: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_IjSaIjEEbb1314
_ZN4PLMD8GridBaseD2Ev1497
_ZN4PLMD10BiasWeight16projectInnerLoopERdS1_13603
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Grid.h.func.html b/coverage/tools/Grid.h.func.html new file mode 100644 index 0000000000..be1a365f79 --- /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-06-10 08:19:14Functions: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_IjSaIjEEbb1314
_ZN4PLMD4GridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_128
_ZN4PLMD8GridBaseD0Ev0
_ZN4PLMD8GridBaseD2Ev1497
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Grid.h.gcov.html b/coverage/tools/Grid.h.gcov.html new file mode 100644 index 0000000000..c9cc42d5a4 --- /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-06-10 08:19:14Functions: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        2994 :   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        1314 :   Grid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     237             :        const std::vector<std::string> & gmax,
+     238        1314 :        const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
+     239        1314 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv)
+     240             :   {
+     241        1314 :     grid_.assign(maxsize_,0.0);
+     242        1314 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     243        1314 :   }
+     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.15
+
+ + + 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 0000000000..9a7afc23d6 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.func.html b/coverage/tools/HistogramBead.cpp.func.html new file mode 100644 index 0000000000..3d6bf5b1d9 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.gcov.html b/coverage/tools/HistogramBead.cpp.gcov.html new file mode 100644 index 0000000000..0bb2258c22 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..d0a281003a --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead10isPeriodicERKdS2_1
_ZNK4PLMD13HistogramBead10differenceERKdS2_595780
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/HistogramBead.h.func.html b/coverage/tools/HistogramBead.h.func.html new file mode 100644 index 0000000000..96686a359f --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead10isPeriodicERKdS2_1
_ZNK4PLMD13HistogramBead10differenceERKdS2_595780
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/HistogramBead.h.gcov.html b/coverage/tools/HistogramBead.h.gcov.html new file mode 100644 index 0000000000..2e8cab8844 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..55a5d57067 --- /dev/null +++ b/coverage/tools/IFile.cpp.func-sort-c.html @@ -0,0 +1,165 @@ + + + + + + + + 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:14214498.6 %
Date:2024-06-10 08:19:14Functions:212391.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5IFileC2Ev0
_ZN4PLMD5IFileD2Ev0
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm15
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj17
_ZN4PLMD5IFileD0Ev341
_ZN4PLMD5IFile10allowNoEOLEv792
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1227
_ZN4PLMD5IFile18allowIgnoredFieldsEv5778
_ZN4PLMD5IFile5resetEb6136
_ZN4PLMD5IFileC1Ev11484
_ZN4PLMD5IFileD1Ev11484
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1101428
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1137181
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1137278
_ZN4PLMD5IFile9scanFieldEv1319122
_ZN4PLMD5IFile12advanceFieldEv1325530
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1469597
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2213283
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7007926
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15847679
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_15854014
_ZN4PLMD5IFile6llreadEPcm99918049
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/IFile.cpp.func.html b/coverage/tools/IFile.cpp.func.html new file mode 100644 index 0000000000..67a214a8a4 --- /dev/null +++ b/coverage/tools/IFile.cpp.func.html @@ -0,0 +1,165 @@ + + + + + + + + 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:14214498.6 %
Date:2024-06-10 08:19:14Functions:212391.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1137181
_ZN4PLMD5IFile10allowNoEOLEv792
_ZN4PLMD5IFile12advanceFieldEv1325530
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1137278
_ZN4PLMD5IFile18allowIgnoredFieldsEv5778
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1227
_ZN4PLMD5IFile5resetEb6136
_ZN4PLMD5IFile6llreadEPcm99918049
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1469597
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1101428
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_15854014
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7007926
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2213283
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj17
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm15
_ZN4PLMD5IFile9scanFieldEv1319122
_ZN4PLMD5IFileC1Ev11484
_ZN4PLMD5IFileC2Ev0
_ZN4PLMD5IFileD0Ev341
_ZN4PLMD5IFileD1Ev11484
_ZN4PLMD5IFileD2Ev0
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15847679
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/IFile.cpp.gcov.html b/coverage/tools/IFile.cpp.gcov.html new file mode 100644 index 0000000000..1b5c8966f7 --- /dev/null +++ b/coverage/tools/IFile.cpp.gcov.html @@ -0,0 +1,358 @@ + + + + + + + + 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:14214498.6 %
Date:2024-06-10 08:19:14Functions:212391.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 "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    99918049 : size_t IFile::llread(char*ptr,size_t s) {
+      42    99918049 :   plumed_assert(fp);
+      43             :   size_t r;
+      44    99918049 :   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    99914527 :     if(std::feof(fp))   eof=true;
+      56    99914527 :     if(std::ferror(fp)) err=true;
+      57             :   }
+      58    99918049 :   return r;
+      59             : }
+      60             : 
+      61     1325530 : IFile& IFile::advanceField() {
+      62     1325530 :   plumed_assert(!inMiddleOfField);
+      63             :   std::string line;
+      64             :   bool done=false;
+      65     2652867 :   while(!done) {
+      66     1333748 :     getline(line);
+      67             : // using explicit conversion not to confuse cppcheck 1.86
+      68     1333748 :     if(!bool(*this)) {return *this;}
+      69     1327337 :     std::vector<std::string> words=Tools::getWords(line);
+      70     2654429 :     if(words.size()>=2 && words[0]=="#!" && words[1]=="FIELDS") {
+      71         711 :       fields.clear();
+      72        4712 :       for(unsigned i=2; i<words.size(); i++) {
+      73             :         Field field;
+      74             :         field.name=words[i];
+      75        4001 :         fields.push_back(field);
+      76             :       }
+      77     1348302 :     } else if(words.size()==4 && words[0]=="#!" && words[1]=="SET") {
+      78             :       Field field;
+      79             :       field.name=words[2];
+      80             :       field.value=words[3];
+      81        3252 :       field.constant=true;
+      82        3252 :       fields.push_back(field);
+      83             :     } else {
+      84             :       unsigned nf=0;
+      85    17098745 :       for(unsigned i=0; i<fields.size(); i++) if(!fields[i].constant) nf++;
+      86     1323374 :       Tools::trimComments(line);
+      87     2646748 :       words=Tools::getWords(line);
+      88     1323374 :       if( words.size()==nf ) {
+      89             :         unsigned j=0;
+      90    17044133 :         for(unsigned i=0; i<fields.size(); i++) {
+      91    15725014 :           if(fields[i].constant) continue;
+      92     6858749 :           fields[i].value=words[j];
+      93     6858749 :           fields[i].read=false;
+      94     6858749 :           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     1327337 :   }
+     102     1319119 :   inMiddleOfField=true;
+     103     1319119 :   return *this;
+     104             : }
+     105             : 
+     106        1227 : IFile& IFile::open(const std::string&path) {
+     107        1227 :   plumed_massert(!cloned,"file "+path+" appears to be cloned");
+     108        1227 :   eof=false;
+     109        1227 :   err=false;
+     110        1227 :   fp=NULL;
+     111        1227 :   gzfp=NULL;
+     112        1227 :   bool do_exist=FileExist(path);
+     113        1229 :   plumed_massert(do_exist,"file " + path + " cannot be found");
+     114        1226 :   fp=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+     115        2452 :   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        1226 :   if(plumed) plumed->insertFile(*this);
+     123        1226 :   return *this;
+     124             : }
+     125             : 
+     126     1137278 : IFile& IFile::scanFieldList(std::vector<std::string>&s) {
+     127     1137278 :   if(!inMiddleOfField) advanceField();
+     128             : // using explicit conversion not to confuse cppcheck 1.86
+     129     1137278 :   if(!bool(*this)) return *this;
+     130     1137202 :   s.clear();
+     131     9179239 :   for(unsigned i=0; i<fields.size(); i++)
+     132     8042037 :     s.push_back(fields[i].name);
+     133             :   return *this;
+     134             : }
+     135             : 
+     136     1137181 : bool IFile::FieldExist(const std::string& s) {
+     137             :   std::vector<std::string> slist;
+     138     1137181 :   scanFieldList(slist);
+     139     1137181 :   int mycount = (int) std::count(slist.begin(), slist.end(), s);
+     140     1137181 :   if(mycount>0) return true;
+     141     1114189 :   else return false;
+     142     1137181 : }
+     143             : 
+     144    15854014 : IFile& IFile::scanField(const std::string&name,std::string&str) {
+     145    15854014 :   if(!inMiddleOfField) advanceField();
+     146             : // using explicit conversion not to confuse cppcheck 1.86
+     147    15854014 :   if(!bool(*this)) return *this;
+     148    15847679 :   unsigned i=findField(name);
+     149    15847679 :   str=fields[i].value;
+     150    15847679 :   fields[i].read=true;
+     151    15847679 :   return *this;
+     152             : }
+     153             : 
+     154     7007926 : IFile& IFile::scanField(const std::string&name,double &x) {
+     155             :   std::string str;
+     156     7007926 :   scanField(name,str);
+     157     7007926 :   if(*this) Tools::convert(str,x);
+     158     7007926 :   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          17 : IFile& IFile::scanField(const std::string&name,unsigned &x) {
+     176             :   std::string str;
+     177          17 :   scanField(name,str);
+     178          17 :   if(*this) Tools::convert(str,x);
+     179          17 :   return *this;
+     180             : }
+     181             : 
+     182          15 : IFile& IFile::scanField(const std::string&name,long unsigned &x) {
+     183             :   std::string str;
+     184          15 :   scanField(name,str);
+     185          15 :   if(*this) Tools::convert(str,x);
+     186          15 :   return *this;
+     187             : }
+     188             : 
+     189     1101428 : IFile& IFile::scanField(Value* val) {
+     190     1101428 :   double ff=std::numeric_limits<double>::quiet_NaN(); // this is to be sure a NaN value is replaced upon failure
+     191     1101428 :   scanField(  val->getName(), ff );
+     192     1101428 :   val->set( ff );
+     193     2202856 :   if( FieldExist("min_" + val->getName() ) ) {
+     194             :     std::string min, max;
+     195        3309 :     scanField("min_" + val->getName(), min );
+     196        3309 :     scanField("max_" + val->getName(), max );
+     197        3309 :     val->setDomain( min, max );
+     198             :   } else {
+     199     1098119 :     val->setNotPeriodic();
+     200             :   }
+     201     1101428 :   return *this;
+     202             : }
+     203             : 
+     204     1319122 : IFile& IFile::scanField() {
+     205     1319122 :   if(!ignoreFields) {
+     206    15341777 :     for(unsigned i=0; i<fields.size(); i++) {
+     207    14237228 :       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" );
+     208             :     }
+     209             :   }
+     210     1319122 :   inMiddleOfField=false;
+     211     1319122 :   return *this;
+     212             : }
+     213             : 
+     214       11484 : IFile::IFile():
+     215       11484 :   inMiddleOfField(false),
+     216       11484 :   ignoreFields(false),
+     217       11484 :   noEOL(false)
+     218             : {
+     219       11484 : }
+     220             : 
+     221       11825 : IFile::~IFile() {
+     222       11484 :   if(inMiddleOfField) std::cerr<<"WARNING: IFile closed in the middle of reading. seems strange!\n";
+     223       11825 : }
+     224             : 
+     225     1469597 : IFile& IFile::getline(std::string &str) {
+     226     1469597 :   char tmp=0;
+     227             :   str="";
+     228             :   fpos_t pos;
+     229     1469597 :   fgetpos(fp,&pos);
+     230    99917996 :   while(llread(&tmp,1)==1 && tmp && tmp!='\n' && tmp!='\r' && !eof && !err) {
+     231    98448399 :     str+=tmp;
+     232             :   }
+     233     1469597 :   if(tmp=='\r') {
+     234          53 :     llread(&tmp,1);
+     235          53 :     plumed_massert(tmp=='\n',"plumed only accepts \\n (unix) or \\r\\n (dos) new lines");
+     236             :   }
+     237     1469597 :   if(eof && noEOL) {
+     238         777 :     if(str.length()>0) eof=false;
+     239     1468820 :   } else if(eof || err || tmp!='\n') {
+     240        6437 :     eof = true;
+     241             :     str="";
+     242        6437 :     if(!err) fsetpos(fp,&pos);
+     243             : // there was a fsetpos here that apparently is not necessary
+     244             : //  fsetpos(fp,&pos);
+     245             : // I think it was necessary to have rewind working correctly
+     246             : // after end of file. Since rewind is not used now anywhere,
+     247             : // it should be ok not to reset position.
+     248             : // This is necessary so that eof works properly for emacs files
+     249             : // with no endline at end of file.
+     250             :   }
+     251     1469597 :   return *this;
+     252             : }
+     253             : 
+     254    15847679 : unsigned IFile::findField(const std::string&name)const {
+     255             :   unsigned i;
+     256   105129016 :   for(i=0; i<fields.size(); i++) if(fields[i].name==name) break;
+     257    15847679 :   if(i>=fields.size()) {
+     258           0 :     plumed_merror("file " + getPath() + ": field " + name + " cannot be found");
+     259             :   }
+     260    15847679 :   return i;
+     261             : }
+     262             : 
+     263        6136 : void IFile::reset(bool reset) {
+     264        6136 :   eof = reset;
+     265        6136 :   err = reset;
+     266        6136 :   if(!reset && fp) clearerr(fp);
+     267             : #ifdef __PLUMED_HAS_ZLIB
+     268        6136 :   if(!reset && gzfp) gzclearerr(gzFile(gzfp));
+     269             : #endif
+     270        6136 :   return;
+     271             : }
+     272             : 
+     273        5778 : void IFile::allowIgnoredFields() {
+     274        5778 :   ignoreFields=true;
+     275        5778 : }
+     276             : 
+     277         792 : void IFile::allowNoEOL() {
+     278         792 :   noEOL=true;
+     279         792 : }
+     280             : 
+     281             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..f706c3a841 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/IFile.h.func.html b/coverage/tools/IFile.h.func.html new file mode 100644 index 0000000000..88235d7732 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/IFile.h.gcov.html b/coverage/tools/IFile.h.gcov.html new file mode 100644 index 0000000000..7349446430 --- /dev/null +++ b/coverage/tools/IFile.h.gcov.html @@ -0,0 +1,190 @@ + + + + + + + + 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-06-10 08:19:14Functions: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       26057 :   class Field:
+      45             :     public FieldBase {
+      46             :   public:
+      47             :     bool read;
+      48        7253 :     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 unsigned field
+      81             :   IFile& scanField(const std::string&,unsigned&);
+      82             : /// Read a long unsigned field
+      83             :   IFile& scanField(const std::string&,long unsigned&);
+      84             : /// Read a string field
+      85             :   IFile& scanField(const std::string&,std::string&);
+      86             :   /**
+      87             :    Ends a field-formatted line.
+      88             : 
+      89             :   Typically used as
+      90             :   \verbatim
+      91             :     if.scanField("a",a).scanField("b",b).scanField();
+      92             :   \endverbatim
+      93             :   */
+      94             :   IFile& scanField();
+      95             : /// Get a full line as a string
+      96             :   IFile& getline(std::string&);
+      97             : /// Reset end of file
+      98             :   void reset(bool);
+      99             : /// Check if a field exist
+     100             :   bool FieldExist(const std::string& s);
+     101             : /// Read in a value
+     102             :   IFile& scanField(Value* val);
+     103             : /// Allow some of the fields in the input to be ignored
+     104             :   void allowIgnoredFields();
+     105             : /// Allow files without EOL at the end.
+     106             : /// This in practice should be only used when opening
+     107             : /// plumed input files
+     108             :   void allowNoEOL();
+     109             : };
+     110             : 
+     111             : }
+     112             : 
+     113             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..4667f9da0b --- /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:18922484.4 %
Date:2024-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.func.html b/coverage/tools/KernelFunctions.cpp.func.html new file mode 100644 index 0000000000..eb3fd41fe7 --- /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:18922484.4 %
Date:2024-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.gcov.html b/coverage/tools/KernelFunctions.cpp.gcov.html new file mode 100644 index 0000000000..79da45965c --- /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:18922484.4 %
Date:2024-06-10 08:19:14Functions: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         103 :     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           9 :   return Tools::make_unique<KernelFunctions>( cc, sig, ktype, "VON-MISSES", h );
+     453             : }
+     454             : 
+     455             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..a94e641b12 --- /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:88100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15KernelFunctions9getMatrixEv9632291
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.func.html b/coverage/tools/KernelFunctions.h.func.html new file mode 100644 index 0000000000..cfa56e9237 --- /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:88100.0 %
Date:2024-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15KernelFunctions9getMatrixEv9632291
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.gcov.html b/coverage/tools/KernelFunctions.h.gcov.html new file mode 100644 index 0000000000..fa956a7fe1 --- /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:88100.0 %
Date:2024-06-10 08:19:14Functions: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             : 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.15
+
+ + + 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 0000000000..ae85bbe25e --- /dev/null +++ b/coverage/tools/Keywords.cpp.func-sort-c.html @@ -0,0 +1,221 @@ + + + + + + + + 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:22341853.3 %
Date:2024-06-10 08:19:14Functions:273773.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Keywords11destroyDataEv0
_ZN4PLMD8Keywords15removeComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10getTooltipERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10print_htmlEv0
_ZNK4PLMD8Keywords12printKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_3LogE0
_ZNK4PLMD8Keywords14print_spellingEv0
_ZNK4PLMD8Keywords14print_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZNK4PLMD8Keywords15print_html_itemERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords5printERNS_3LogE0
_ZNK4PLMD8Keywords5printEP8_IO_FILE287
_ZNK4PLMD8Keywords9print_vimEv287
_ZN4PLMD8Keywords3addERKS0_682
_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_682
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1438
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_1953
_ZNK4PLMD8Keywords12printKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEP8_IO_FILE3412
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3912
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3912
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6275
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8070
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej9262
_ZNK4PLMD8Keywords15getDefaultValueENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_10262
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14436
_ZNK4PLMD8Keywords17getLogicalDefaultENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb36577
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_72441
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb106111
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_112849
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_184796
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_189136
_ZNK4PLMD8Keywords3getB5cxx11Ej368197
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_426605
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_727474
_ZNK4PLMD8Keywords4sizeEv783765
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE915339
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE933368
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1160571
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Keywords.cpp.func.html b/coverage/tools/Keywords.cpp.func.html new file mode 100644 index 0000000000..7368b22176 --- /dev/null +++ b/coverage/tools/Keywords.cpp.func.html @@ -0,0 +1,221 @@ + + + + + + + + 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:22341853.3 %
Date:2024-06-10 08:19:14Functions:273773.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Keywords11destroyDataEv0
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_1953
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3912
_ZN4PLMD8Keywords15removeComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_72441
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6275
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_426605
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_189136
_ZN4PLMD8Keywords3addERKS0_682
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14436
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1438
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3912
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE915339
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_184796
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_112849
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej9262
_ZNK4PLMD8Keywords10getTooltipERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10print_htmlEv0
_ZNK4PLMD8Keywords12printKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEP8_IO_FILE3412
_ZNK4PLMD8Keywords12printKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_3LogE0
_ZNK4PLMD8Keywords14print_spellingEv0
_ZNK4PLMD8Keywords14print_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZNK4PLMD8Keywords15getDefaultValueENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_10262
_ZNK4PLMD8Keywords15print_html_itemERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords17getLogicalDefaultENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb36577
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb106111
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords3getB5cxx11Ej368197
_ZNK4PLMD8Keywords4sizeEv783765
_ZNK4PLMD8Keywords5printEP8_IO_FILE287
_ZNK4PLMD8Keywords5printERNS_3LogE0
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_727474
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1160571
_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_682
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8070
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE933368
_ZNK4PLMD8Keywords9print_vimEv287
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Keywords.cpp.gcov.html b/coverage/tools/Keywords.cpp.gcov.html new file mode 100644 index 0000000000..96f8dbe8f1 --- /dev/null +++ b/coverage/tools/Keywords.cpp.gcov.html @@ -0,0 +1,778 @@ + + + + + + + + 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:22341853.3 %
Date:2024-06-10 08:19:14Functions:273773.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             : 
+      27             : namespace PLMD {
+      28             : 
+      29      915339 : Keywords::KeyType::KeyType( const std::string& type ) {
+      30      915339 :   if( type=="compulsory" ) {
+      31      242031 :     style=compulsory;
+      32      673308 :   } else if( type=="flag" ) {
+      33      186749 :     style=flag;
+      34      486559 :   } else if( type=="optional" ) {
+      35      252231 :     style=optional;
+      36      234328 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      37      121214 :     style=atoms;
+      38      113114 :   } else if( type=="hidden" ) {
+      39       54073 :     style=hidden;
+      40       59041 :   } else if( type=="vessel" ) {
+      41       59041 :     style=vessel;
+      42             :   } else {
+      43           0 :     plumed_massert(false,"invalid keyword specifier " + type);
+      44             :   }
+      45      915339 : }
+      46             : 
+      47        3912 : void Keywords::KeyType::setStyle( const std::string& type ) {
+      48        3912 :   if( type=="compulsory" ) {
+      49          80 :     style=compulsory;
+      50        3832 :   } else if( type=="flag" ) {
+      51           0 :     style=flag;
+      52        3832 :   } else if( type=="optional" ) {
+      53          25 :     style=optional;
+      54        3807 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      55         205 :     style=atoms;
+      56        3602 :   } else if( type=="hidden" ) {
+      57         129 :     style=hidden;
+      58        3473 :   } else if( type=="vessel" ) {
+      59        3473 :     style=vessel;
+      60             :   } else {
+      61           0 :     plumed_massert(false,"invalid keyword specifier " + type);
+      62             :   }
+      63        3912 : }
+      64             : 
+      65         682 : void Keywords::add( const Keywords& newkeys ) {
+      66         682 :   newkeys.copyData( keys, reserved_keys, types, allowmultiple, documentation, booldefs, numdefs, atomtags, cnames, ckey, cdocs  );
+      67         682 : }
+      68             : 
+      69         682 : 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,
+      70             :                          std::map<std::string,std::string>& docs, std::map<std::string,bool>& bools, std::map<std::string,std::string>& nums,
+      71             :                          std::map<std::string,std::string>& atags, std::vector<std::string>& cnam, std::map<std::string,std::string>& ck,
+      72             :                          std::map<std::string,std::string>& cd ) const {
+      73         682 :   for(unsigned i=0; i<keys.size(); ++i) {
+      74           0 :     std::string thiskey=keys[i];
+      75           0 :     for(unsigned j=0; j<kk.size(); ++j) plumed_massert( thiskey!=kk[j], "keyword " + thiskey + " is in twice" );
+      76           0 :     for(unsigned j=0; j<rk.size(); ++j) plumed_massert( thiskey!=rk[j], "keyword " + thiskey + " is in twice" );
+      77           0 :     kk.push_back( thiskey );
+      78           0 :     plumed_massert( types.count( thiskey ), "no type data on keyword " + thiskey + " to copy" );
+      79           0 :     tt.insert( std::pair<std::string,KeyType>( thiskey,types.find(thiskey)->second) );
+      80           0 :     if( (types.find(thiskey)->second).isAtomList() ) atags.insert( std::pair<std::string,std::string>( thiskey,atomtags.find(thiskey)->second) );
+      81           0 :     plumed_massert( allowmultiple.count( thiskey ), "no numbered data on keyword " + thiskey + " to copy" );
+      82           0 :     am.insert( std::pair<std::string,bool>(thiskey,allowmultiple.find(thiskey)->second) );
+      83           0 :     plumed_massert( documentation.count( thiskey ), "no documentation for keyword " + thiskey + " to copy" );
+      84           0 :     docs.insert( std::pair<std::string,std::string>(thiskey,documentation.find(thiskey)->second) );
+      85           0 :     if( booldefs.count( thiskey ) ) bools.insert( std::pair<std::string,bool>( thiskey,booldefs.find(thiskey)->second) );
+      86           0 :     if( numdefs.count( thiskey ) ) nums.insert( std::pair<std::string,std::string>( thiskey,numdefs.find(thiskey)->second) );
+      87             :   }
+      88       12958 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+      89       12276 :     std::string thiskey=reserved_keys[i];
+      90      108072 :     for(unsigned j=0; j<kk.size(); ++j) plumed_massert( thiskey!=kk[j], "keyword " + thiskey + " is in twice" );
+      91      170280 :     for(unsigned j=0; j<rk.size(); ++j) plumed_massert( thiskey!=rk[j], "keyword " + thiskey + " is in twice" );
+      92       12276 :     rk.push_back( thiskey );
+      93           0 :     plumed_massert( types.count( thiskey ), "no type data on keyword " + thiskey + " to copy" );
+      94       12276 :     tt.insert( std::pair<std::string,KeyType>( thiskey,types.find(thiskey)->second) );
+      95       12276 :     if( (types.find(thiskey)->second).isAtomList() ) atags.insert( std::pair<std::string,std::string>( thiskey,atomtags.find(thiskey)->second) );
+      96           0 :     plumed_massert( allowmultiple.count( thiskey ), "no numbered data on keyword " + thiskey + " to copy" );
+      97       12276 :     am.insert( std::pair<std::string,bool>(thiskey,allowmultiple.find(thiskey)->second) );
+      98           0 :     plumed_massert( documentation.count( thiskey ), "no documentation for keyword " + thiskey + " to copy" );
+      99       24552 :     docs.insert( std::pair<std::string,std::string>(thiskey,documentation.find(thiskey)->second) );
+     100           0 :     if( booldefs.count( thiskey ) ) bools.insert( std::pair<std::string,bool>( thiskey,booldefs.find(thiskey)->second) );
+     101           0 :     if( numdefs.count( thiskey ) ) nums.insert( std::pair<std::string,std::string>( thiskey,numdefs.find(thiskey)->second) );
+     102             :   }
+     103       12958 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     104       12276 :     std::string thisnam=cnames[i];
+     105      116622 :     for(unsigned j=0; j<cnam.size(); ++j) plumed_massert( thisnam!=cnam[j], "component " + thisnam + " is in twice" );
+     106       12276 :     cnam.push_back( thisnam );
+     107           0 :     plumed_massert( ckey.count( thisnam ), "no keyword data on component " + thisnam + " to copy" );
+     108       24552 :     ck.insert( std::pair<std::string,std::string>( thisnam, ckey.find(thisnam)->second) );
+     109           0 :     plumed_massert( cdocs.count( thisnam ), "no documentation on component " + thisnam + " to copy" );
+     110       24552 :     cd.insert( std::pair<std::string,std::string>( thisnam, cdocs.find(thisnam)->second) );
+     111             :   }
+     112         682 : }
+     113             : 
+     114      112849 : void Keywords::reserve( const std::string & t, const std::string & k, const std::string & d ) {
+     115      112849 :   plumed_assert( !exists(k) && !reserved(k) );
+     116      112849 :   std::string fd, lowkey=k;
+     117             :   // Convert to lower case
+     118      972044 :   std::transform(lowkey.begin(),lowkey.end(),lowkey.begin(),[](unsigned char c) { return std::tolower(c); });
+     119             : // Remove any underscore characters
+     120             :   for(unsigned i=0;; ++i) {
+     121      154817 :     std::size_t num=lowkey.find_first_of("_");
+     122      154817 :     if( num==std::string::npos ) break;
+     123       41968 :     lowkey.erase( lowkey.begin() + num, lowkey.begin() + num + 1 );
+     124       41968 :   }
+     125      112849 :   if( t=="vessel" ) {
+     126      118082 :     fd = d + " The final value can be referenced using <em>label</em>." + lowkey;
+     127      111136 :     if(d.find("flag")==std::string::npos) fd += ".  You can use multiple instances of this keyword i.e. " +
+     128      104190 :           k +"1, " + k + "2, " + k + "3...  The corresponding values are then "
+     129      104190 :           "referenced using <em>label</em>."+ lowkey +"-1,  <em>label</em>." + lowkey +
+     130      104190 :           "-2,  <em>label</em>." + lowkey + "-3...";
+     131       59041 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     132      118082 :     types.insert( std::pair<std::string,KeyType>(k,KeyType("vessel")) );
+     133       53808 :   } else if( t=="numbered" ) {
+     134        5994 :     fd = d + " You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     135        2997 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     136        5994 :     types.insert( std::pair<std::string,KeyType>(k,KeyType("optional")) );
+     137             :   } else {
+     138             :     fd = d;
+     139       50811 :     if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     140       50811 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     141      101622 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     142       52086 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     143             :   }
+     144      225698 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     145      112849 :   reserved_keys.push_back(k);
+     146      112849 : }
+     147             : 
+     148        1953 : void Keywords::reserveFlag( const std::string & k, const bool def, const std::string & d ) {
+     149        1953 :   plumed_assert( !exists(k) && !reserved(k) );
+     150             :   std::string defstr;
+     151        1953 :   if( def ) { defstr="( default=on ) "; } else { defstr="( default=off ) "; }
+     152        3906 :   types.insert( std::pair<std::string,KeyType>(k,KeyType("flag")) );
+     153       24266 :   std::string fd,lowkey=k; std::transform(lowkey.begin(),lowkey.end(),lowkey.begin(),[](unsigned char c) { return std::tolower(c); });
+     154        1953 :   fd=defstr + d;
+     155        3906 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     156        1953 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     157           0 :   booldefs.insert( std::pair<std::string,bool>(k,def) );
+     158        1953 :   reserved_keys.push_back(k);
+     159        1953 : }
+     160             : 
+     161       14436 : void Keywords::use( const std::string & k ) {
+     162       14436 :   plumed_massert( reserved(k), "the " + k + " keyword is not reserved");
+     163      179967 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     164      165531 :     if(reserved_keys[i]==k) keys.push_back( reserved_keys[i] );
+     165             :   }
+     166       14436 : }
+     167             : 
+     168        3912 : void Keywords::reset_style( const std::string & k, const std::string & style ) {
+     169        3912 :   plumed_massert( exists(k) || reserved(k), "no " + k + " keyword" );
+     170        3912 :   (types.find(k)->second).setStyle(style);
+     171        3912 :   if( (types.find(k)->second).isVessel() ) allowmultiple[k]=true;
+     172        4117 :   if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,style) );
+     173        3912 : }
+     174             : 
+     175      426605 : void Keywords::add( const std::string & t, const std::string & k, const std::string & d ) {
+     176     1279815 :   plumed_massert( !exists(k) && t!="flag" && !reserved(k) && t!="vessel", "keyword " + k + " has already been registered");
+     177             :   std::string fd;
+     178      426605 :   if( t=="numbered" ) {
+     179        2742 :     fd=d + " You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     180        1371 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     181        2742 :     types.insert( std::pair<std::string,KeyType>(k, KeyType("optional")) );
+     182             :   } else {
+     183             :     fd=d;
+     184      425234 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     185      850468 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     186      545173 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     187             :   }
+     188      442649 :   if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     189      853210 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     190      426605 :   keys.push_back(k);
+     191      426605 : }
+     192             : 
+     193      189136 : void Keywords::add( const std::string & t, const std::string & k, const std::string &  def, const std::string & d ) {
+     194      378272 :   plumed_assert( !exists(k) && !reserved(k) &&  (t=="compulsory" || t=="hidden" )); // An optional keyword can't have a default
+     195      189136 :   types.insert(  std::pair<std::string,KeyType>(k, KeyType(t)) );
+     196      378272 :   documentation.insert( std::pair<std::string,std::string>(k,"( default=" + def + " ) " + d) );
+     197      189136 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     198      378272 :   numdefs.insert( std::pair<std::string,std::string>(k,def) );
+     199      189136 :   keys.push_back(k);
+     200      189136 : }
+     201             : 
+     202      184796 : void Keywords::addFlag( const std::string & k, const bool def, const std::string & d ) {
+     203      184796 :   plumed_massert( !exists(k) && !reserved(k), "keyword " + k + " has already been registered");
+     204      184796 :   std::string defstr; plumed_massert( !def, "the second argument to addFlag must be false " + k );
+     205             :   defstr="( default=off ) ";
+     206      369592 :   types.insert( std::pair<std::string,KeyType>(k,KeyType("flag")) );
+     207      369592 :   documentation.insert( std::pair<std::string,std::string>(k,defstr + d) );
+     208      184796 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     209           0 :   booldefs.insert( std::pair<std::string,bool>(k,def) );
+     210      184796 :   keys.push_back(k);
+     211      184796 : }
+     212             : 
+     213        1438 : void Keywords::remove( const std::string & k ) {
+     214             :   bool found=false; unsigned j=0, n=0;
+     215             : 
+     216             :   while(true) {
+     217       14291 :     for(j=0; j<keys.size(); j++) if(keys[j]==k)break;
+     218       33184 :     for(n=0; n<reserved_keys.size(); n++) if(reserved_keys[n]==k)break;
+     219        2876 :     if(j<keys.size()) {
+     220        1353 :       keys.erase(keys.begin()+j);
+     221             :       found=true;
+     222        1523 :     } else if(n<reserved_keys.size()) {
+     223          85 :       reserved_keys.erase(reserved_keys.begin()+n);
+     224             :       found=true;
+     225             :     } else break;
+     226             :   }
+     227             :   // Delete documentation, type and so on from the description
+     228             :   types.erase(k); documentation.erase(k); allowmultiple.erase(k); booldefs.erase(k); numdefs.erase(k);
+     229        1438 :   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
+     230        1438 : }
+     231             : 
+     232        8070 : bool Keywords::numbered( const std::string & k ) const {
+     233       16140 :   if( style( k,"atoms") ) return true;
+     234           0 :   plumed_massert( allowmultiple.count(k), "Did not find keyword " + k );
+     235        6094 :   return allowmultiple.find(k)->second;
+     236             : }
+     237             : 
+     238      727474 : bool Keywords::style( const std::string & k, const std::string & t ) const {
+     239           0 :   plumed_massert( types.count(k), "Did not find keyword " + k );
+     240             : 
+     241      727474 :   if( (types.find(k)->second).toString()==t ) return true;
+     242             :   return false;
+     243             : }
+     244             : 
+     245      783765 : unsigned Keywords::size() const {
+     246      783765 :   return keys.size();
+     247             : }
+     248             : 
+     249        9262 : std::string Keywords::getKeyword( const unsigned i ) const {
+     250        9262 :   plumed_assert( i<size() );
+     251        9262 :   return keys[i];
+     252             : }
+     253             : 
+     254     1160571 : bool Keywords::exists( const std::string & k ) const {
+     255    12056720 :   for(unsigned i=0; i<keys.size(); ++i) {
+     256    11096368 :     if( keys[i]==k ) return true;
+     257             :   }
+     258             :   return false;
+     259             : }
+     260             : 
+     261      933368 : bool Keywords::reserved( const std::string & k ) const {
+     262     2158698 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     263     1243359 :     if( reserved_keys[i]==k ) return true;
+     264             :   }
+     265             :   return false;
+     266             : }
+     267             : 
+     268           0 : void Keywords::print_template(const std::string& actionname, bool include_optional) const {
+     269             :   unsigned nkeys=0;
+     270             :   std::printf("%s",actionname.c_str());
+     271           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     272           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     273             :   }
+     274           0 :   if( nkeys>0 ) {
+     275           0 :     std::string prevtag="start";
+     276           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     277           0 :       if( (types.find(keys[i])->second).isAtomList() ) {
+     278           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     279           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second ) break;
+     280           0 :         if( (atomtags.find(keys[i])->second).find("residues")!=std::string::npos) std::printf(" %s=<residue selection>", keys[i].c_str() );
+     281             :         else std::printf(" %s=<atom selection>", keys[i].c_str() );
+     282           0 :         prevtag=atomtags.find(keys[i])->second;
+     283             :       }
+     284             :     }
+     285             :   }
+     286             :   nkeys=0;
+     287           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     288           0 :     if ( include_optional || \
+     289           0 :          (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     290             :   }
+     291           0 :   if( nkeys>0 ) {
+     292           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     293           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) {
+     294             :         std::string def;
+     295           0 :         if( getDefaultValue( keys[i], def) ) {
+     296             :           std::printf(" %s=%s ", keys[i].c_str(), def.c_str() );
+     297             :         } else {
+     298             :           std::printf(" %s=    ", keys[i].c_str() );
+     299             :         }
+     300           0 :       } else if (include_optional) {
+     301             :         // TG no defaults for optional keywords?
+     302             :         std::printf(" [%s]", keys[i].c_str() );
+     303             :       }
+     304             :     }
+     305             :   }
+     306             :   std::printf("\n");
+     307           0 : }
+     308             : 
+     309         287 : void Keywords::print_vim() const {
+     310        4426 :   for(unsigned i=0; i<keys.size(); ++i) {
+     311        4139 :     if( (types.find(keys[i])->second).isFlag() ) {
+     312             :       std::printf( ",flag:%s", keys[i].c_str() );
+     313             :     } else {
+     314        3209 :       if( allowmultiple.find(keys[i])->second ) std::printf(",numbered:%s",keys[i].c_str() );
+     315             :       else std::printf(",option:%s",keys[i].c_str() );
+     316             :     }
+     317             :   }
+     318         287 :   std::fprintf(stdout,"\n");
+     319         287 :   print(stdout);
+     320         287 : }
+     321             : 
+     322           0 : void Keywords::print_html() const {
+     323             : 
+     324             : // This is the part that outputs the details of the components
+     325           0 :   if( cnames.size()>0 ) {
+     326             :     unsigned ndef=0;
+     327           0 :     for(unsigned i=0; i<cnames.size(); ++i) {
+     328           0 :       if(ckey.find(cnames[i])->second=="default") ndef++;
+     329             :     }
+     330             : 
+     331           0 :     if( ndef>0 ) {
+     332           0 :       std::cout<<"\\par Description of components\n\n";
+     333           0 :       std::cout<<cstring<<"\n\n";
+     334           0 :       std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     335             :       std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     336             :       unsigned nndef=0;
+     337           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     338             :         //plumed_assert( ckey.find(cnames[i])->second=="default" );
+     339           0 :         if( ckey.find(cnames[i])->second!="default" ) { nndef++; continue; }
+     340             :         std::printf("<tr>\n");
+     341             :         std::printf("<td width=15%%> <b> %s </b></td>\n",cnames[i].c_str() );
+     342             :         std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     343             :         std::printf("</tr>\n");
+     344             :       }
+     345           0 :       std::cout<<"</table>\n\n";
+     346           0 :       if( nndef>0 ) {
+     347           0 :         std::cout<<"In addition the following quantities can be calculated by employing the keywords listed below"<<std::endl;
+     348           0 :         std::cout<<"\n\n";
+     349           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     350             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     351           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     352           0 :           if( ckey.find(cnames[i])->second!="default") {
+     353             :             std::printf("<tr>\n");
+     354             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     355             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     356             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     357             :             std::printf("</tr>\n");
+     358             :           }
+     359             :         }
+     360           0 :         std::cout<<"</table>\n\n";
+     361             :       }
+     362             :     } else {
+     363             :       unsigned nregs=0;
+     364           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     365           0 :         if( exists(ckey.find(cnames[i])->second) ) nregs++;
+     366             :       }
+     367           0 :       if( nregs>0 ) {
+     368           0 :         std::cout<<"\\par Description of components\n\n";
+     369           0 :         std::cout<<cstring<<"\n\n";
+     370           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     371             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     372           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     373           0 :           if( exists(ckey.find(cnames[i])->second) ) {
+     374             :             std::printf("<tr>\n");
+     375             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     376             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     377             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     378             :             std::printf("</tr>\n");
+     379             :           }
+     380             :         }
+     381           0 :         std::cout<<"</table>\n\n";
+     382             :       }
+     383             :     }
+     384             :   }
+     385             : 
+     386             :   unsigned nkeys=0;
+     387           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     388           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     389             :   }
+     390           0 :   if( nkeys>0 ) {
+     391           0 :     if(isaction && isatoms) std::cout<<"\\par The atoms involved can be specified using\n\n";
+     392           0 :     else if(isaction) std::cout<<"\\par The data to analyze can be the output from another analysis algorithm\n\n";
+     393           0 :     else std::cout<<"\\par The input trajectory is specified using one of the following\n\n";
+     394           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     395           0 :     std::string prevtag="start"; unsigned counter=0;
+     396           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     397           0 :       if ( (types.find(keys[i])->second).isAtomList() ) {
+     398           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     399           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second && isaction ) {
+     400           0 :           std::cout<<"</table>\n\n";
+     401           0 :           if( isatoms ) std::cout<<"\\par Or alternatively by using\n\n";
+     402           0 :           else if( counter==0 ) { std::cout<<"\\par Alternatively data can be collected from the trajectory using \n\n"; counter++; }
+     403           0 :           else std::cout<<"\\par Lastly data collected in a previous analysis action can be reanalyzed by using the keyword \n\n";
+     404           0 :           std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     405             :         }
+     406           0 :         print_html_item( keys[i] );
+     407           0 :         prevtag=atomtags.find(keys[i])->second;
+     408             :       }
+     409             :     }
+     410           0 :     std::cout<<"</table>\n\n";
+     411             :   }
+     412             :   nkeys=0;
+     413           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     414           0 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     415             :   }
+     416           0 :   if( nkeys>0 ) {
+     417           0 :     if(isaction) std::cout<< "\\par Compulsory keywords\n\n";
+     418           0 :     else std::cout<<"\\par The following must be present\n\n";
+     419           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     420           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     421           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) print_html_item( keys[i] );
+     422             :     }
+     423           0 :     std::cout<<"</table>\n\n";
+     424             :   }
+     425             :   nkeys=0;
+     426           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     427           0 :     if ( (types.find(keys[i])->second).isFlag() || (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     428             :   }
+     429           0 :   if( nkeys>0 ) {
+     430           0 :     if(isaction) std::cout<<"\\par Options\n\n";
+     431           0 :     else std::cout<<"\\par The following options are available\n\n";
+     432           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     433           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     434           0 :       if ( (types.find(keys[i])->second).isFlag() ) print_html_item( keys[i] );
+     435             :     }
+     436           0 :     std::cout<<"\n";
+     437             :   }
+     438             :   nkeys=0;
+     439           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     440           0 :     if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     441             :   }
+     442           0 :   if( 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() ) print_html_item( keys[i] );
+     445             :     }
+     446             :   }
+     447           0 :   std::cout<<"</table>\n\n";
+     448           0 : }
+     449             : 
+     450           0 : void Keywords::print_spelling() const {
+     451           0 :   for(unsigned i=0; i<keys.size(); ++i) std::printf("%s\n", keys[i].c_str() );
+     452           0 :   for(unsigned i=0; i<cnames.size(); ++i) std::printf("%s\n",cnames[i].c_str() );
+     453           0 : }
+     454             : 
+     455         287 : void Keywords::print( FILE* out ) const {
+     456             :   unsigned nkeys=0;
+     457        4426 :   for(unsigned i=0; i<keys.size(); ++i) {
+     458        4139 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     459             :   }
+     460         287 :   if( nkeys>0 ) {
+     461             :     std::fprintf(out,"The input trajectory can be in any of the following formats: \n\n");
+     462        2386 :     for(unsigned i=0; i<keys.size(); ++i) {
+     463        2260 :       if ( (types.find(keys[i])->second).isAtomList() ) printKeyword( keys[i], out );
+     464             :     }
+     465             :   }
+     466             :   nkeys=0;
+     467        4426 :   for(unsigned i=0; i<keys.size(); ++i) {
+     468        4139 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     469             :   }
+     470             :   unsigned ncompulsory=nkeys;
+     471         287 :   if( nkeys>0 ) {
+     472             :     std::fprintf(out,"\nThe following arguments are compulsory: \n\n");
+     473        3616 :     for(unsigned i=0; i<keys.size(); ++i) {
+     474        3388 :       if ( (types.find(keys[i])->second).isCompulsory() ) printKeyword( keys[i], out );   //log.printKeyword( keys[i], documentation[i] );
+     475             :     }
+     476             :   }
+     477             :   nkeys=0;
+     478        4426 :   for(unsigned i=0; i<keys.size(); ++i) {
+     479        4139 :     if ( (types.find(keys[i])->second).isFlag() ) nkeys++;
+     480             :   }
+     481         287 :   if( nkeys>0 ) {
+     482         253 :     if(ncompulsory>0) std::fprintf( out,"\nIn addition you may use the following options: \n\n");
+     483             :     else std::fprintf( out,"\nThe following options are available\n\n");
+     484        4211 :     for(unsigned i=0; i<keys.size(); ++i) {
+     485        3958 :       if ( (types.find(keys[i])->second).isFlag() ) printKeyword( keys[i], out );   //log.printKeyword( keys[i], documentation[i] );
+     486             :     }
+     487             :   }
+     488             :   nkeys=0;
+     489        4426 :   for(unsigned i=0; i<keys.size(); ++i) {
+     490        7427 :     if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     491             :   }
+     492         287 :   if( nkeys>0 ) {
+     493        3855 :     for(unsigned i=0; i<keys.size(); ++i) {
+     494        6425 :       if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) printKeyword( keys[i], out );   //log.printKeyword( keys[i], documentation[i] );
+     495             :     }
+     496             :     std::fprintf(out,"\n");
+     497             :   }
+     498         287 : }
+     499             : 
+     500        3412 : void Keywords::printKeyword( const std::string& key, FILE* out ) const {
+     501        3412 :   bool killdot=( (documentation.find(key)->second).find("\\f$")!=std::string::npos ); // Check for latex
+     502        3412 :   std::vector<std::string> w=Tools::getWords( documentation.find(key)->second );
+     503             :   std::fprintf(out,"%23s - ", key.c_str() );
+     504        3412 :   unsigned nl=0; std::string blank=" ";
+     505       72717 :   for(unsigned i=0; i<w.size(); ++i) {
+     506       69598 :     nl+=w[i].length() + 1;
+     507       69598 :     if( nl>60 ) {
+     508             :       std::fprintf(out,"\n%23s   %s ", blank.c_str(), w[i].c_str() ); nl=0;
+     509             :     } else {
+     510             :       std::fprintf(out,"%s ", w[i].c_str() );
+     511             :     }
+     512       69598 :     if( killdot && w[i].find(".")!=std::string::npos ) break; // If there is latex only write up to first dot
+     513             :   }
+     514             :   std::fprintf(out,"\n");
+     515        3412 : }
+     516             : 
+     517           0 : void Keywords::print( Log& log ) const {
+     518             :   unsigned nkeys=0;
+     519           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     520           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     521             :   }
+     522           0 :   if (nkeys>0 ) {
+     523           0 :     log.printf( "The input for this keyword can be specified using one of the following \n\n");
+     524           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     525           0 :       if ( (types.find(keys[i])->second).isAtomList() ) printKeyword( keys[i], log );   //log.printKeyword( keys[i], documentation[i] );
+     526             :     }
+     527             :   }
+     528             :   nkeys=0;
+     529           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     530           0 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     531             :   }
+     532           0 :   if( nkeys>0 ) {
+     533           0 :     log.printf( "\n The compulsory keywords for this action are: \n\n");
+     534           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     535           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) printKeyword( keys[i], log );   //log.printKeyword( keys[i], documentation[i] );
+     536             :     }
+     537             :   }
+     538             :   nkeys=0;
+     539           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     540           0 :     if ( (types.find(keys[i])->second).isFlag() ) nkeys++;
+     541             :   }
+     542           0 :   if( nkeys>0 ) {
+     543           0 :     log.printf( "\n The following options are available: \n\n");
+     544           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     545           0 :       if ( (types.find(keys[i])->second).isFlag() ) printKeyword( keys[i], log );   //log.printKeyword( keys[i], documentation[i] );
+     546             :     }
+     547           0 :     log.printf("\n");
+     548             :   }
+     549             :   nkeys=0;
+     550           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     551           0 :     if ( (types.find(keys[i])->second).isOptional() ) nkeys++;
+     552             :   }
+     553           0 :   if( nkeys>0 ) {
+     554           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     555           0 :       if ( (types.find(keys[i])->second).isOptional() ) printKeyword( keys[i], log );   //log.printKeyword( keys[i], documentation[i] );
+     556             :     }
+     557           0 :     log.printf("\n");
+     558             :   }
+     559           0 : }
+     560             : 
+     561           0 : void Keywords::printKeyword( const std::string& key, Log& log ) const {
+     562           0 :   bool killdot=( (documentation.find(key)->second).find("\\f$")!=std::string::npos ); // Check for latex
+     563           0 :   std::vector<std::string> w=Tools::getWords( documentation.find(key)->second );
+     564           0 :   log.printf("%23s - ", key.c_str() );
+     565           0 :   unsigned nl=0; std::string blank=" ";
+     566           0 :   for(unsigned i=0; i<w.size(); ++i) {
+     567           0 :     nl+=w[i].length() + 1;
+     568           0 :     if( nl>60 ) {
+     569           0 :       log.printf("\n%23s   %s ", blank.c_str(), w[i].c_str() ); nl=0;
+     570             :     } else {
+     571           0 :       log.printf("%s ", w[i].c_str() );
+     572             :     }
+     573           0 :     if( killdot && w[i].find(".")!=std::string::npos ) break; // If there is latex only write up to first dot
+     574             :   }
+     575           0 :   log.printf("\n");
+     576           0 : }
+     577             : 
+     578           0 : std::string Keywords::getTooltip( const std::string& name ) const {
+     579           0 :   std::size_t dd=name.find_first_of("0123456789"); std::string kname=name.substr(0,dd);
+     580           0 :   if( !exists(kname) ) return "<b> could not find this keyword </b>";
+     581           0 :   std::string mystring, docstr = documentation.find(kname)->second;
+     582           0 :   if( types.find(kname)->second.isCompulsory() ) {
+     583             :     mystring += "<b>compulsory keyword ";
+     584           0 :     if( docstr.find("default")!=std::string::npos ) {
+     585           0 :       std::size_t bra = docstr.find_first_of(")"); mystring += docstr.substr(0,bra+1); docstr = docstr.substr(bra+1);
+     586             :     }
+     587             :     mystring += "</b>\n";
+     588             :   }
+     589           0 :   std::vector<std::string> w=Tools::getWords( docstr ); unsigned nl=0;
+     590           0 :   for(unsigned i=0; i<w.size(); ++i) {
+     591           0 :     nl+=w[i].length() + 1;
+     592           0 :     if( nl>80 ) { mystring += w[i] + "\n"; nl=0; }
+     593           0 :     else { mystring += w[i] + " "; }
+     594           0 :     if( w[i].find(".")!=std::string::npos ) break; // Only write up the the first dot
+     595             :   }
+     596             :   return mystring;
+     597           0 : }
+     598             : 
+     599           0 : void Keywords::print_html_item( const std::string& key ) const {
+     600             :   std::printf("<tr>\n");
+     601             :   std::printf("<td width=15%%> <b> %s </b></td>\n",key.c_str() );
+     602             :   std::printf("<td> %s </td>\n",(documentation.find(key)->second).c_str() );
+     603             :   std::printf("</tr>\n");
+     604           0 : }
+     605             : 
+     606      368197 : std::string Keywords::get( const unsigned k ) const {
+     607      368197 :   plumed_assert( k<size() );
+     608      368197 :   return keys[k];
+     609             : }
+     610             : 
+     611       36577 : bool Keywords::getLogicalDefault( std::string key, bool& def ) const {
+     612       36577 :   if( booldefs.find(key)!=booldefs.end() ) {
+     613       36577 :     def=booldefs.find(key)->second;
+     614       36577 :     return true;
+     615             :   } else {
+     616             :     return false;
+     617             :   }
+     618             : }
+     619             : 
+     620       10262 : bool Keywords::getDefaultValue( std::string key, std::string& def ) const {
+     621       20702 :   plumed_assert( style(key,"compulsory") || style(key,"hidden") );
+     622             : 
+     623       10262 :   if( numdefs.find(key)!=numdefs.end() ) {
+     624        5042 :     def=numdefs.find(key)->second;
+     625        5042 :     return true;
+     626             :   } else {
+     627             :     return false;
+     628             :   }
+     629             : }
+     630             : 
+     631           0 : void Keywords::destroyData() {
+     632           0 :   keys.clear(); reserved_keys.clear(); types.clear();
+     633             :   allowmultiple.clear(); documentation.clear();
+     634             :   booldefs.clear(); numdefs.clear(); atomtags.clear();
+     635             :   ckey.clear(); cdocs.clear(); ckey.clear();
+     636           0 : }
+     637             : 
+     638        6275 : void Keywords::setComponentsIntroduction( const std::string& instr ) {
+     639        6275 :   cstring = instr;
+     640        6275 : }
+     641             : 
+     642       72441 : void Keywords::addOutputComponent( const std::string& name, const std::string& key, const std::string& descr ) {
+     643       72441 :   plumed_assert( !outputComponentExists( name, false ) );
+     644       72441 :   plumed_massert( name.find("-")==std::string::npos,"dash is reseved character in component names" );
+     645             : 
+     646       72441 :   std::size_t num2=name.find_first_of("_");
+     647       72441 :   if( num2!=std::string::npos ) {
+     648         298 :     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");
+     649         298 :     plumed_massert( num2==0, "underscore is reserved character in component names that has special meaning");
+     650             :   }
+     651             : 
+     652      144882 :   ckey.insert( std::pair<std::string,std::string>(name,key) );
+     653      144882 :   cdocs.insert( std::pair<std::string,std::string>(name,descr) );
+     654       72441 :   cnames.push_back(name);
+     655       72441 : }
+     656             : 
+     657      106111 : bool Keywords::outputComponentExists( const std::string& name, const bool& custom ) const {
+     658      106111 :   if( custom && cstring.find("customize")!=std::string::npos ) return true;
+     659             : 
+     660             :   std::string sname;
+     661      102652 :   std::size_t num=name.find_first_of("-");
+     662      102652 :   std::size_t num2=name.find_last_of("_");
+     663             : 
+     664      104570 :   if( num2!=std::string::npos ) sname=name.substr(num2);
+     665      126538 :   else if( num!=std::string::npos ) sname=name.substr(0,num);
+     666             :   else sname=name;
+     667             : 
+     668      976400 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     669      903959 :     if( sname==cnames[i] ) return true;
+     670             :   }
+     671             :   return false;
+     672             : }
+     673             : 
+     674           0 : std::string Keywords::getOutputComponentDescription( const std::string& name ) const {
+     675           0 :   if( cstring.find("customized")!=std::string::npos ) return "the label of this action is set by user in the input. See documentation above.";
+     676             : 
+     677             :   bool found=false;
+     678           0 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     679           0 :     if( name==cnames[i] ) found=true;
+     680             :   }
+     681           0 :   if( !found ) plumed_merror("could not find output component named " + name );
+     682           0 :   return cdocs.find(name)->second;
+     683             : }
+     684             : 
+     685           0 : void Keywords::removeComponent( const std::string& name ) {
+     686             :   bool found=false;
+     687             : 
+     688             :   while(true) {
+     689             :     unsigned j;
+     690           0 :     for(j=0; j<cnames.size(); j++) if(cnames[j]==name)break;
+     691           0 :     if(j<cnames.size()) {
+     692           0 :       cnames.erase(cnames.begin()+j);
+     693             :       found=true;
+     694             :     } else break;
+     695           0 :   }
+     696             :   // Delete documentation, type and so on from the description
+     697             :   cdocs.erase(name); ckey.erase(name);
+     698           0 :   plumed_massert(found,"You are trying to remove " + name + " a component that isn't there");
+     699           0 : }
+     700             : 
+     701             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..25ac7c4dd4 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev80828
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev727474
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Keywords.h.func.html b/coverage/tools/Keywords.h.func.html new file mode 100644 index 0000000000..619829d016 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev80828
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev727474
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Keywords.h.gcov.html b/coverage/tools/Keywords.h.gcov.html new file mode 100644 index 0000000000..0a265770b4 --- /dev/null +++ b/coverage/tools/Keywords.h.gcov.html @@ -0,0 +1,253 @@ + + + + + + + + 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-06-10 08:19:14Functions: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        7527 :     bool isCompulsory() const { return (style==compulsory); }
+      44       12236 :     bool isFlag() const { return (style==flag); }
+      45        7777 :     bool isOptional() const { return (style==optional); }
+      46      498632 :     bool isAtomList() const { return (style==atoms); }
+      47        9987 :     bool isVessel() const { return (style==vessel); }
+      48      727474 :     std::string toString() const {
+      49      727474 :       if(style==compulsory) return "compulsory";
+      50      150298 :       else if(style==optional) return "optional";
+      51      148802 :       else if(style==atoms) return "atoms";
+      52      287157 :       else if(style==flag) return "flag";
+      53       68086 :       else if(style==hidden) return "hidden";
+      54       21433 :       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             : /// Print a particular keyword
+      92             :   void printKeyword( const std::string& j, Log& log ) const ;
+      93             : /// Print a particular keyword (copy of the above that works with files)
+      94             :   void printKeyword( const std::string& j, FILE* out ) const ;
+      95             : public:
+      96             : /// Constructor
+      97       80828 :   Keywords() : isaction(true), isatoms(true) {}
+      98             : ///
+      99        6946 :   void isDriver() { isaction=false; }
+     100             : ///
+     101         129 :   void isAnalysis() { isatoms=false; }
+     102             : /// find out whether flag key is on or off by default.
+     103             :   bool getLogicalDefault( std::string key, bool& def ) const ;
+     104             : /// Get the value of the default for the keyword named key
+     105             :   bool getDefaultValue( std::string key, std::string& def ) const ;
+     106             : /// Return the number of defined keywords
+     107             :   unsigned size() const;
+     108             : /// Check if numbered keywords are allowed for this action
+     109             :   bool numbered( const std::string & k ) const ;
+     110             : /// Return the ith keyword
+     111             :   std::string getKeyword( const unsigned i ) const ;
+     112             : /// Print the documentation to the log file (used by PLMD::Action::error)
+     113             :   void print( Log& log ) const ;
+     114             : /// Print the documentation to a file (use by PLUMED::CLTool::readCommandLineArgs)
+     115             :   void print( FILE* out ) 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             : /// Check if the keyword with name k has style t
+     139             :   bool style( const std::string & k, const std::string & t ) const ;
+     140             : /// Print an html version of the documentation
+     141             :   void print_html() const ;
+     142             : /// Print keywords in form readable by vim
+     143             :   void print_vim() const ;
+     144             : /// Print the template version for the documentation
+     145             :   void print_template( const std::string& actionname, bool include_optional) const ;
+     146             : /// Change the style of a keyword
+     147             :   void reset_style( const std::string & k, const std::string & style );
+     148             : /// Add keywords from one keyword object to another
+     149             :   void add( const Keywords& keys );
+     150             : /// Copy the keywords data
+     151             :   void copyData( std::vector<std::string>& kk, std::vector<std::string>& rk, std::map<std::string,KeyType>& tt, std::map<std::string,bool>& am,
+     152             :                  std::map<std::string,std::string>& docs, std::map<std::string,bool>& bools, std::map<std::string,std::string>& nums,
+     153             :                  std::map<std::string,std::string>& atags, std::vector<std::string>& cnam, std::map<std::string,std::string>& ck,
+     154             :                  std::map<std::string,std::string>& cd ) const ;
+     155             : /// Clear everything from the keywords object.
+     156             : /// Not actually needed if your Keywords object is going out of scope.
+     157             :   void destroyData();
+     158             : /// Set the text that introduces how the components for this action are introduced
+     159             :   void setComponentsIntroduction( const std::string& instr );
+     160             : /// Add a potential component which can be output by this particular action
+     161             :   void addOutputComponent( const std::string& name, const std::string& key, const std::string& descr );
+     162             : /// Has a component with this name been added?
+     163             :   bool outputComponentExists( const std::string& name, const bool& custom ) const ;
+     164             : /// Get the description of this component
+     165             :   std::string getOutputComponentDescription( const std::string& name ) const ;
+     166             : /// Remove a component with a particular name from the keywords
+     167             :   void removeComponent( const std::string& name );
+     168             : /// Reference to keys
+     169           0 :   std::vector<std::string> getKeys() const { return keys; }
+     170             : /// Get the description of a particular keyword
+     171             :   std::string getTooltip( const std::string& name ) const ;
+     172             : };
+     173             : 
+     174             : }
+     175             : 
+     176             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..d67bfc30c9 --- /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-06-10 08:19:14Functions: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_13TensorGenericILj3ELj3EEE12554
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE12555
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_19233
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE31782
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.func.html b/coverage/tools/LatticeReduction.cpp.func.html new file mode 100644 index 0000000000..6cffec89f6 --- /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-06-10 08:19:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16LatticeReduction10isReduced2ERKNS_13VectorGenericILj3EEES4_S4_0
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE12555
_ZN4PLMD16LatticeReduction10reduceSlowERNS_13TensorGenericILj3ELj3EEE1
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE31782
_ZN4PLMD16LatticeReduction6reduceERNS_13TensorGenericILj3ELj3EEE12554
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_19233
_ZN4PLMD16LatticeReduction7reduce2ERNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD16LatticeReduction7reduce2ERNS_13VectorGenericILj3EEES3_S3_1
_ZN4PLMD16LatticeReduction9isReducedERKNS_13TensorGenericILj3ELj3EEE2
_ZN4PLMD16LatticeReduction9isReducedERKNS_13VectorGenericILj3EEES4_11
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.gcov.html b/coverage/tools/LatticeReduction.cpp.gcov.html new file mode 100644 index 0000000000..0d2c7d56b7 --- /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-06-10 08:19:14Functions: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       31782 : void LatticeReduction::sort(Vector v[3]) {
+      32             :   const double onePlusEpsilon=(1.0+epsilon);
+      33             :   double m[3];
+      34       31782 :   m[0]=modulo2(v[0]);
+      35       31782 :   m[1]=modulo2(v[1]);
+      36       31782 :   m[2]=modulo2(v[2]);
+      37      222474 :   for(int i=0; i<3; i++) for(int j=i+1; j<3; j++) if(m[i]>m[j]) {
+      38       11780 :         std::swap(v[i],v[j]);
+      39             :         std::swap(m[i],m[j]);
+      40             :       }
+      41       31782 :   plumed_assert(m[0]<=m[1]*onePlusEpsilon);
+      42       31782 :   plumed_assert(m[1]<=m[2]*onePlusEpsilon);
+      43       31782 : }
+      44             : 
+      45       19233 : void LatticeReduction::reduce(Vector&a,Vector&b) {
+      46             :   const double onePlusEpsilon=(1.0+epsilon);
+      47       19233 :   double ma=modulo2(a);
+      48       19233 :   double mb=modulo2(b);
+      49             :   unsigned counter=0;
+      50             :   while(true) {
+      51       19799 :     if(mb>ma) {
+      52             :       std::swap(a,b);
+      53             :       std::swap(ma,mb);
+      54             :     }
+      55       19799 :     a-=b*floor(dotProduct(a,b)/mb+0.5);
+      56       19799 :     ma=modulo2(a);
+      57       19799 :     if(mb<=ma*onePlusEpsilon) break;
+      58         566 :     counter++;
+      59         566 :     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         566 :     if(counter%10000==0) std::fprintf(stderr,"WARNING: LatticeReduction::reduce stuck after %u iterations\n",counter);
+      64             :   }
+      65             : 
+      66             :   std::swap(a,b);
+      67       19233 : }
+      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       12554 : void LatticeReduction::reduce(Tensor&t) {
+     112       12554 :   reduceFast(t);
+     113       12554 : }
+     114             : 
+     115       12555 : void LatticeReduction::reduceFast(Tensor&t) {
+     116             :   const double onePlusEpsilon=(1.0+epsilon);
+     117       50220 :   Vector v[3];
+     118       12555 :   v[0]=t.getRow(0);
+     119       12555 :   v[1]=t.getRow(1);
+     120       12555 :   v[2]=t.getRow(2);
+     121             :   unsigned counter=0;
+     122             :   while(true) {
+     123       19226 :     sort(v);
+     124       19226 :     reduce(v[0],v[1]);
+     125       19226 :     double b11=modulo2(v[0]);
+     126       19226 :     double b22=modulo2(v[1]);
+     127       19226 :     double b12=dotProduct(v[0],v[1]);
+     128       19226 :     double b13=dotProduct(v[0],v[2]);
+     129       19226 :     double b23=dotProduct(v[1],v[2]);
+     130       19226 :     double z=b11*b22-b12*b12;
+     131       19226 :     double y2=-(b11*b23-b12*b13)/z;
+     132       19226 :     double y1=-(b22*b13-b12*b23)/z;
+     133       19226 :     int x1min=floor(y1);
+     134       19226 :     int x1max=x1min+1;
+     135       19226 :     int x2min=floor(y2);
+     136       19226 :     int x2max=x2min+1;
+     137             :     bool first=true;
+     138             :     double mbest,mtrial;
+     139       19226 :     Vector trial,best;
+     140       57678 :     for(int x1=x1min; x1<=x1max; x1++)
+     141      115356 :       for(int x2=x2min; x2<=x2max; x2++) {
+     142       76904 :         trial=v[2]+x2*v[1]+x1*v[0];
+     143       76904 :         mtrial=modulo2(trial);
+     144       76904 :         if(first || mtrial<mbest) {
+     145             :           mbest=mtrial;
+     146       26770 :           best=trial;
+     147             :           first=false;
+     148             :         }
+     149             :       }
+     150       19226 :     if(modulo2(best)*onePlusEpsilon>=modulo2(v[2])) break;
+     151        6671 :     counter++;
+     152        6671 :     if(counter%10000==0) std::fprintf(stderr,"WARNING: LatticeReduction::reduceFast stuck after %u iterations\n",counter);
+     153        6671 :     v[2]=best;
+     154        6671 :   }
+     155       12555 :   sort(v);
+     156       12555 :   t.setRow(0,v[0]);
+     157       12555 :   t.setRow(1,v[1]);
+     158       12555 :   t.setRow(2,v[2]);
+     159       12555 : }
+     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.15
+
+ + + 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 0000000000..cd1f350e6e --- /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-06-10 08:19:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9LinkCells9getCutoffEv8
_ZN4PLMD9LinkCells9setCutoffERKd383
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE701
_ZN4PLMD9LinkCells14buildCellListsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEERKNS_3PbcE1294
_ZNK4PLMD9LinkCells24retrieveNeighboringAtomsERKNS_13VectorGenericILj3EEERSt6vectorIjSaIjEERjS8_6576
_ZNK4PLMD9LinkCells16addRequiredCellsERKSt5arrayIjLm3EERjRSt6vectorIjSaIjEE227143
_ZNK4PLMD9LinkCells20retrieveAtomsInCellsERKjRKSt6vectorIjSaIjEERjRS5_227143
_ZNK4PLMD9LinkCells21convertIndicesToIndexERKjS2_S2_409550
_ZNK4PLMD9LinkCells8findCellERKNS_13VectorGenericILj3EEE409550
_ZNK4PLMD9LinkCells10findMyCellERKNS_13VectorGenericILj3EEE636693
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.func.html b/coverage/tools/LinkCells.cpp.func.html new file mode 100644 index 0000000000..69fe4c9a56 --- /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-06-10 08:19:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9LinkCells14buildCellListsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEERKNS_3PbcE1294
_ZN4PLMD9LinkCells9setCutoffERKd383
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE701
_ZNK4PLMD9LinkCells10findMyCellERKNS_13VectorGenericILj3EEE636693
_ZNK4PLMD9LinkCells16addRequiredCellsERKSt5arrayIjLm3EERjRSt6vectorIjSaIjEE227143
_ZNK4PLMD9LinkCells20retrieveAtomsInCellsERKjRKSt6vectorIjSaIjEERjRS5_227143
_ZNK4PLMD9LinkCells21convertIndicesToIndexERKjS2_S2_409550
_ZNK4PLMD9LinkCells24retrieveNeighboringAtomsERKNS_13VectorGenericILj3EEERSt6vectorIjSaIjEERjS8_6576
_ZNK4PLMD9LinkCells8findCellERKNS_13VectorGenericILj3EEE409550
_ZNK4PLMD9LinkCells9getCutoffEv8
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.gcov.html b/coverage/tools/LinkCells.cpp.gcov.html new file mode 100644 index 0000000000..f116357918 --- /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-06-10 08:19:14Functions: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         701 : LinkCells::LinkCells( Communicator& cc ) :
+      29         701 :   comm(cc),
+      30         701 :   cutoffwasset(false),
+      31         701 :   link_cutoff(0.0),
+      32         701 :   ncells(3),
+      33        1402 :   nstride(3)
+      34             : {
+      35         701 : }
+      36             : 
+      37         383 : void LinkCells::setCutoff( const double& lcut ) {
+      38         383 :   cutoffwasset=true; link_cutoff=lcut;
+      39         383 : }
+      40             : 
+      41           8 : double LinkCells::getCutoff() const {
+      42           8 :   plumed_assert( cutoffwasset ); return link_cutoff;
+      43             : }
+      44             : 
+      45        1294 : void LinkCells::buildCellLists( const std::vector<Vector>& pos, const std::vector<unsigned>& indices, const Pbc& pbc ) {
+      46        1294 :   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        1294 :   mypbc.setBox( pbc.getBox() );
+      52             : 
+      53             :   // Setup the lists
+      54        1294 :   if( pos.size()!=allcells.size() ) {
+      55         312 :     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        1294 :     Tensor reciprocal(transpose(mypbc.getInvBox()));
+      63        1294 :     ncells[0] = std::floor( 1.0/ reciprocal.getRow(0).modulo() / link_cutoff );
+      64        1294 :     if( ncells[0]==0 ) ncells[0]=1;
+      65        1294 :     ncells[1] = std::floor( 1.0/ reciprocal.getRow(1).modulo() / link_cutoff );
+      66        1294 :     if( ncells[1]==0 ) ncells[1]=1;
+      67        1294 :     ncells[2] = std::floor( 1.0/ reciprocal.getRow(2).modulo() / link_cutoff );
+      68        1294 :     if( ncells[2]==0 ) ncells[2]=1;
+      69             :   }
+      70             :   // Setup the strides
+      71        1294 :   nstride[0]=1; nstride[1]=ncells[0]; nstride[2]=ncells[0]*ncells[1];
+      72             : 
+      73             :   // Setup the storage for link cells
+      74        1294 :   unsigned ncellstot=ncells[0]*ncells[1]*ncells[2];
+      75        1294 :   if( lcell_tots.size()!=ncellstot ) {
+      76         302 :     lcell_tots.resize( ncellstot ); lcell_starts.resize( ncellstot );
+      77             :   }
+      78             :   // Clear nlcells
+      79      299507 :   for(unsigned i=0; i<ncellstot; ++i) lcell_tots[i]=0;
+      80             :   // Clear allcells
+      81        1294 :   allcells.assign( allcells.size(), 0 );
+      82             : 
+      83             :   // Find out what cell everyone is in
+      84        1294 :   unsigned rank=comm.Get_rank(), size=comm.Get_size();
+      85      410844 :   for(unsigned i=rank; i<pos.size(); i+=size) {
+      86      409550 :     allcells[i]=findCell( pos[i] );
+      87      409550 :     lcell_tots[allcells[i]]++;
+      88             :   }
+      89             :   // And gather all this information on every node
+      90        1294 :   comm.Sum( allcells ); comm.Sum( lcell_tots );
+      91             : 
+      92             :   // Now prepare the link cell lists
+      93             :   unsigned tot=0;
+      94      299507 :   for(unsigned i=0; i<lcell_tots.size(); ++i) { lcell_starts[i]=tot; tot+=lcell_tots[i]; lcell_tots[i]=0; }
+      95        1294 :   plumed_assert( tot==pos.size() );
+      96             : 
+      97             :   // And setup the link cells properly
+      98      456123 :   for(unsigned j=0; j<pos.size(); ++j) {
+      99      454829 :     unsigned myind = lcell_starts[ allcells[j] ] + lcell_tots[ allcells[j] ];
+     100      454829 :     lcell_lists[ myind ] = indices[j];
+     101      454829 :     lcell_tots[allcells[j]]++;
+     102             :   }
+     103        1294 : }
+     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      227143 : 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     1297461 :   for(int nx=LINKC_MIN(ncells[0]); nx<LINKC_MAX(ncells[0]); ++nx) {
+     113      432999 :     int xval = celn[0] + nx;
+     114      432999 :     xval=LINKC_PBC(xval,ncells[0])*nstride[0];
+     115     3141735 :     for(int ny=LINKC_MIN(ncells[1]); ny<LINKC_MAX(ncells[1]); ++ny) {
+     116     1048569 :       int yval = celn[1] + ny;
+     117     1048569 :       yval=LINKC_PBC(yval,ncells[1])*nstride[1];
+     118     8641472 :       for(int nz=LINKC_MIN(ncells[2]); nz<LINKC_MAX(ncells[2]); ++nz) {
+     119     2883950 :         int zval = celn[2] + nz;
+     120     2883950 :         zval=LINKC_PBC(zval,ncells[2])*nstride[2];
+     121             : 
+     122     2883950 :         unsigned mybox=xval+yval+zval; bool added=false;
+     123     2883950 :         for(unsigned k=0; k<ncells_required; ++k) {
+     124           0 :           if( mybox==cells_required[k] ) { added=true; break; }
+     125             :         }
+     126     2883950 :         if( !added ) { cells_required[ncells_required+nnew_cells]=mybox; nnew_cells++; }
+     127             :       }
+     128             :     }
+     129             :   }
+     130      227143 :   ncells_required += nnew_cells;
+     131      227143 : }
+     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      227143 : void LinkCells::retrieveAtomsInCells( const unsigned& ncells_required,
+     141             :                                       const std::vector<unsigned>& cells_required,
+     142             :                                       unsigned& natomsper, std::vector<unsigned>& atoms ) const {
+     143      227143 :   plumed_assert( natomsper==1 || natomsper==2 );  // This is really a bug. If you are trying to reuse this ask GAT for help
+     144     3111093 :   for(unsigned i=0; i<ncells_required; ++i) {
+     145     2883950 :     unsigned mybox=cells_required[i];
+     146   407311008 :     for(unsigned k=0; k<lcell_tots[mybox]; ++k) {
+     147   404427058 :       unsigned myatom = lcell_lists[lcell_starts[mybox]+k];
+     148   404427058 :       if( myatom!=atoms[0] ) { // Ideally would provide an option to not do this
+     149   404245654 :         atoms[natomsper]=myatom;
+     150   404245654 :         natomsper++;
+     151             :       }
+     152             :     }
+     153             :   }
+     154      227143 : }
+     155             : 
+     156      636693 : std::array<unsigned,3> LinkCells::findMyCell( const Vector& pos ) const {
+     157      636693 :   Vector fpos=mypbc.realToScaled( pos );
+     158             :   std::array<unsigned,3> celn;
+     159     2546772 :   for(unsigned j=0; j<3; ++j) {
+     160     1910079 :     celn[j] = std::floor( ( Tools::pbc(fpos[j]) + 0.5 ) * ncells[j] );
+     161     1910079 :     plumed_assert( celn[j]>=0 && celn[j]<ncells[j] ); // Check that atom is in box
+     162             :   }
+     163      636693 :   return celn;
+     164             : }
+     165             : 
+     166      409550 : unsigned LinkCells::convertIndicesToIndex( const unsigned& nx, const unsigned& ny, const unsigned& nz ) const {
+     167      409550 :   return nx*nstride[0] + ny*nstride[1] + nz*nstride[2];
+     168             : }
+     169             : 
+     170      409550 : unsigned LinkCells::findCell( const Vector& pos ) const {
+     171      409550 :   std::array<unsigned,3> celn( findMyCell(pos ) );
+     172      409550 :   return convertIndicesToIndex( celn[0], celn[1], celn[2] );
+     173             : }
+     174             : 
+     175             : 
+     176             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..c06ee9c046 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/LinkCells.h.func.html b/coverage/tools/LinkCells.h.func.html new file mode 100644 index 0000000000..8f296fa43b --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/LinkCells.h.gcov.html b/coverage/tools/LinkCells.h.gcov.html new file mode 100644 index 0000000000..b5860ece11 --- /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-06-10 08:19:14Functions: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        1938 :   return cutoffwasset;
+      90             : }
+      91             : 
+      92             : inline
+      93             : unsigned LinkCells::getNumberOfCells() const {
+      94      227143 :   return ncells[0]*ncells[1]*ncells[2];
+      95             : }
+      96             : 
+      97             : }
+      98             : 
+      99             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..22507a4491 --- /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-06-10 08:19:14Functions:5252100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj13EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj14EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj15EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj16EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj10EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj11EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj12EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd47910118
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd55010046
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd55010046
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd55010046
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd55014050
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd55014050
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd57310496
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd106155164
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd106155164
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_166313906
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_166313906
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd543684249
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd543684249
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd738415154
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd738415154
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1095243464
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1095243464
_ZN4PLMD12LoopUnrollerILj2EE4_addEPdPKd1664258758
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd1664258758
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd1814074115
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd1814074115
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.func.html b/coverage/tools/LoopUnroller.h.func.html new file mode 100644 index 0000000000..60ea57c441 --- /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-06-10 08:19:14Functions: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_addEPdPKd1664258758
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_166313906
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd1814074115
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd106155164
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1095243464
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd738415154
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd543684249
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd1664258758
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_166313906
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd1814074115
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd106155164
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1095243464
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd738415154
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd543684249
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd47910118
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd57310496
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd55014050
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd55014050
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd55010046
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd55010046
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd42423502
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd154201037
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd63299
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd46791016
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd55010046
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.gcov.html b/coverage/tools/LoopUnroller.h.gcov.html new file mode 100644 index 0000000000..cc805215f0 --- /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-06-10 08:19:14Functions: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  1454755234 : void LoopUnroller<n>::_zero(double*d) {
+      78   911070985 :   LoopUnroller<n-1>::_zero(d);
+      79  1454755234 :   d[n-1]=0.0;
+      80  1454755234 : }
+      81             : 
+      82             : template<>
+      83             : inline
+      84             : void LoopUnroller<1>::_zero(double*d) {
+      85   544233169 :   d[0]=0.0;
+      86             : }
+      87             : 
+      88             : template<unsigned n>
+      89  3583058528 : void LoopUnroller<n>::_add(double*d,const double*a) {
+      90  1918799770 :   LoopUnroller<n-1>::_add(d,a);
+      91  3583058528 :   d[n-1]+=a[n-1];
+      92  3583058528 : }
+      93             : 
+      94             : template<>
+      95             : inline
+      96             : void LoopUnroller<1>::_add(double*d,const double*a) {
+      97  1664258758 :   d[0]+=a[0];
+      98             : }
+      99             : 
+     100             : template<unsigned n>
+     101  2472352126 : void LoopUnroller<n>::_sub(double*d,const double*a) {
+     102  1377108662 :   LoopUnroller<n-1>::_sub(d,a);
+     103  2472352126 :   d[n-1]-=a[n-1];
+     104  2472352126 : }
+     105             : 
+     106             : template<>
+     107             : inline
+     108             : void LoopUnroller<1>::_sub(double*d,const double*a) {
+     109  1095243464 :   d[0]-=a[0];
+     110             : }
+     111             : 
+     112             : template<unsigned n>
+     113  4553354452 : void LoopUnroller<n>::_mul(double*d,const double s) {
+     114  2739280337 :   LoopUnroller<n-1>::_mul(d,s);
+     115  4553354452 :   d[n-1]*=s;
+     116  4553354452 : }
+     117             : 
+     118             : template<>
+     119             : inline
+     120             : void LoopUnroller<1>::_mul(double*d,const double s) {
+     121  1814074115 :   d[0]*=s;
+     122             : }
+     123             : 
+     124             : template<unsigned n>
+     125   212690122 : void LoopUnroller<n>::_neg(double*d,const double*a ) {
+     126   106534958 :   LoopUnroller<n-1>::_neg(d,a);
+     127   212690122 :   d[n-1]=-a[n-1];
+     128   212690122 : }
+     129             : 
+     130             : template<>
+     131             : inline
+     132             : void LoopUnroller<1>::_neg(double*d,const double*a) {
+     133   106155164 :   d[0]=-a[0];
+     134             : }
+     135             : 
+     136             : template<unsigned n>
+     137  1477949410 : double LoopUnroller<n>::_sum2(const double*d) {
+     138  1477949410 :   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   738415154 :   return d[0]*d[0];
+     145             : }
+     146             : 
+     147             : template<unsigned n>
+     148   332627812 : double LoopUnroller<n>::_dot(const double*d,const double*v) {
+     149   332627812 :   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   166313906 :   return d[0]*v[0];
+     156             : }
+     157             : 
+     158             : }
+     159             : 
+     160             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..5ba3d05e08 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/Matrix.h.func.html b/coverage/tools/Matrix.h.func.html new file mode 100644 index 0000000000..89baad673c --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/Matrix.h.gcov.html b/coverage/tools/Matrix.h.gcov.html new file mode 100644 index 0000000000..df22ce604e --- /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-06-10 08:19:14Functions: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     9769443 : 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    10723145 :   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         331 :   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   231234617 :   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      236382 :     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.15
+
+ + + 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 0000000000..7bf1757639 --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html @@ -0,0 +1,145 @@ + + + + + + + + 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-06-10 08:19:14Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j5400
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowixEj5400
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj5400
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowC2ERS3_j30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjEixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowC2ERS3_j16897856
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowixEj16897856
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj16897856
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j27680833
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj27680833
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj27680833
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowC2ERS8_j35212356
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowixEj35212356
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjEixEj35212356
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.func.html b/coverage/tools/MatrixSquareBracketsAccess.h.func.html new file mode 100644 index 0000000000..d3de5ffabf --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func.html @@ -0,0 +1,145 @@ + + + + + + + + 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-06-10 08:19:14Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j27680833
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj27680833
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j5400
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj27680833
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowC2ERS3_j16897856
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowixEj16897856
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj16897856
_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_rowixEj5400
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj5400
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html b/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html new file mode 100644 index 0000000000..75382308bd --- /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-06-10 08:19:14Functions:1818100.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        5400 : MatrixSquareBracketsAccess<T,C,I,J>::Const_row::Const_row(const MatrixSquareBracketsAccess&t,I i):
+     101        5400 :   t(t),i(i) {}
+     102             : 
+     103             : template<class T,class C,class I,class J>
+     104    82566119 : MatrixSquareBracketsAccess<T,C,I,J>::Row::Row(MatrixSquareBracketsAccess&t,I i):
+     105    82566119 :   t(t),i(i) {}
+     106             : 
+     107             : template<class T,class C,class I,class J>
+     108        5400 : 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        5400 :   return (*static_cast<const T*>(&t))(i,j);
+     113             : }
+     114             : 
+     115             : template<class T,class C,class I,class J>
+     116    82566119 : 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    82566119 :   return (*static_cast<T*>(&t))(i,j);
+     121             : }
+     122             : 
+     123             : template<class T,class C,class I,class J>
+     124    82566119 : typename MatrixSquareBracketsAccess<T,C,I,J>::Row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i) {
+     125    82566119 :   return Row(*this,i);
+     126             : }
+     127             : 
+     128             : template<class T,class C,class I,class J>
+     129        5400 : typename MatrixSquareBracketsAccess<T,C,I,J>::Const_row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i)const {
+     130        5400 :   return Const_row(*this,i);
+     131             : }
+     132             : 
+     133             : }
+     134             : 
+     135             : 
+     136             : #endif
+     137             : 
+     138             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..4ea0252664 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.func.html b/coverage/tools/Minimise1DBrent.h.func.html new file mode 100644 index 0000000000..8007f7dec7 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.gcov.html b/coverage/tools/Minimise1DBrent.h.gcov.html new file mode 100644 index 0000000000..ba39296e75 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..412d0ef8f6 --- /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-06-10 08:19:14Functions: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_9gridtools18ContourFindingBaseEE6getEngERKd8245
_ZN4PLMD5F1dimINS_6dimred24ProjectNonLandmarkPointsEE6getEngERKd15930
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.func.html b/coverage/tools/MinimiseBase.h.func.html new file mode 100644 index 0000000000..246e72dfd3 --- /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-06-10 08:19:14Functions: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_9gridtools18ContourFindingBaseEE6getEngERKd8245
_ZN4PLMD5F1dimINS_9gridtools18ContourFindingBaseEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E1242
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.gcov.html b/coverage/tools/MinimiseBase.h.gcov.html new file mode 100644 index 0000000000..510ff9a35a --- /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-06-10 08:19:14Functions: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             : 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       28205 : double F1dim<FCLASS>::getEng( const double& xt ) {
+      71      465500 :   for(unsigned j=0; j<pt.size(); ++j) pt[j] = p[j] + xt*dir[j];
+      72       28205 :   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         897 : }
+     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.15
+
+ + + 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 0000000000..726efd6f6b --- /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-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MolDataClass33numberOfAtomsPerResidueInBackboneERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE25
_ZN4PLMD12MolDataClass13specialSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_RKNS_3PDBERSt6vectorINS_10AtomNumberESaISD_EE593
_ZN4PLMD12MolDataClass21getBackboneForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKNS_3PDBERSt6vectorINS_10AtomNumberESaISF_EE2652
_ZN4PLMD12MolDataClass15isTerminalGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3417
_ZN4PLMD12MolDataClass14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_8129
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.func.html b/coverage/tools/MolDataClass.cpp.func.html new file mode 100644 index 0000000000..33063f2c2b --- /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-06-10 08:19:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MolDataClass13specialSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_RKNS_3PDBERSt6vectorINS_10AtomNumberESaISD_EE593
_ZN4PLMD12MolDataClass14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_8129
_ZN4PLMD12MolDataClass15isTerminalGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3417
_ZN4PLMD12MolDataClass21getBackboneForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKNS_3PDBERSt6vectorINS_10AtomNumberESaISF_EE2652
_ZN4PLMD12MolDataClass33numberOfAtomsPerResidueInBackboneERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE25
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.gcov.html b/coverage/tools/MolDataClass.cpp.gcov.html new file mode 100644 index 0000000000..fc8b36dc3c --- /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-06-10 08:19:14Functions: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        8129 : bool MolDataClass::allowedResidue( const std::string& type, const std::string& residuename ) {
+      37        8129 :   if( type=="protein" ) {
+      38        6022 :     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        5304 :       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        3417 : bool MolDataClass::isTerminalGroup( const std::string& type, const std::string& residuename ) {
+     203        3417 :   if( type=="protein" ) {
+     204        3417 :     if( residuename=="ACE" ) return true;
+     205        3090 :     else if( residuename=="NME" ) return true;
+     206        2763 :     else if( residuename=="NH2" ) return true;
+     207        2763 :     else return false;
+     208             :   } else {
+     209           0 :     plumed_merror(type + " is not a valid molecule type");
+     210             :   }
+     211             :   return false;
+     212             : }
+     213             : 
+     214         593 : void MolDataClass::specialSymbol( const std::string& type, const std::string& symbol, const PDB& mypdb, std::vector<AtomNumber>& numbers ) {
+     215         823 :   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         593 :     numbers.resize(0);
+     222             : 
+     223             : // special cases:
+     224         593 :     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         592 :     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         590 :     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         589 :     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         588 :     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         587 :     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         586 :     if(dash==std::string::npos) plumed_error() << "Unrecognized symbol "<<symbol;
+     289             : 
+     290         586 :     std::size_t firstunderscore=symbol.find_first_of('_',dash+1);
+     291         586 :     std::size_t firstnum=symbol.find_first_of("0123456789",dash+1);
+     292         586 :     std::string name=symbol.substr(0,dash);
+     293             :     unsigned resnum;
+     294             :     std::string resname;
+     295             :     std::string chainid;
+     296         586 :     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         580 :     } else if(firstnum==dash+1) {
+     300        1140 :       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         586 :     resname= mypdb.getResidueName(resnum,chainid);
+     308         586 :     Tools::stripLeadingAndTrailingBlanks(resname);
+     309        1172 :     if(allowedResidue("protein",resname)) {
+     310         151 :       if( name=="phi" && !isTerminalGroup("protein",resname) ) {
+     311          80 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum-1,chainid));
+     312          80 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     313          80 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     314          80 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum,chainid));
+     315         137 :       } else if( name=="psi" && !isTerminalGroup("protein",resname) ) {
+     316         132 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     317         132 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     318         132 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum,chainid));
+     319         132 :         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.15
+
+ + + 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 0000000000..9740417fd8 --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue6resizeERKmS2_41854
_ZN4PLMD10MultiValue15copyDerivativesERS0_50656
_ZNK4PLMD10MultiValue10copyValuesERS0_57565
_ZN4PLMD10MultiValueC2ERKmS2_360231
_ZN4PLMD10MultiValue9chainRuleERKjS2_S2_S2_RKdS2_RSt6vectorIdSaIdEE502652
_ZN4PLMD10MultiValue12quotientRuleERKjS2_1869892
_ZN4PLMD10MultiValue23clearTemporyDerivativesEv2098913
_ZN4PLMD10MultiValue8clearAllEv2098913
_ZN4PLMD10MultiValue5clearERKj8342417
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.func.html b/coverage/tools/MultiValue.cpp.func.html new file mode 100644 index 0000000000..58eb41a18f --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue12quotientRuleERKjS2_1869892
_ZN4PLMD10MultiValue15copyDerivativesERS0_50656
_ZN4PLMD10MultiValue23clearTemporyDerivativesEv2098913
_ZN4PLMD10MultiValue5clearERKj8342417
_ZN4PLMD10MultiValue6resizeERKmS2_41854
_ZN4PLMD10MultiValue8clearAllEv2098913
_ZN4PLMD10MultiValue9chainRuleERKjS2_S2_S2_RKdS2_RSt6vectorIdSaIdEE502652
_ZN4PLMD10MultiValueC2ERKmS2_360231
_ZNK4PLMD10MultiValue10copyValuesERS0_57565
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.gcov.html b/coverage/tools/MultiValue.cpp.gcov.html new file mode 100644 index 0000000000..71f278ac31 --- /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-06-10 08:19:14Functions: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      360231 : MultiValue::MultiValue( const size_t& nvals, const size_t& nder ):
+      27      360231 :   values(nvals),
+      28      360231 :   nderivatives(nder),
+      29      360231 :   derivatives(nvals*nder),
+      30      360231 :   tmpval(0),
+      31      360231 :   tmpder(nder),
+      32      720462 :   atLeastOneSet(false)
+      33             : {
+      34      360231 :   std::vector<unsigned> myind( nder );
+      35    10699694 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      36      360231 :   hasDerivatives.createIndexListFromVector( myind );
+      37      360231 : }
+      38             : 
+      39       41854 : void MultiValue::resize( const size_t& nvals, const size_t& nder ) {
+      40       41854 :   values.resize(nvals); nderivatives=nder; derivatives.resize( nvals*nder );
+      41       41854 :   tmpder.resize( nder ); hasDerivatives.clear(); std::vector<unsigned> myind( nder );
+      42    10856236 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      43       41854 :   hasDerivatives.createIndexListFromVector( myind );
+      44       41854 :   atLeastOneSet=false;
+      45       41854 : }
+      46             : 
+      47     2098913 : void MultiValue::clearAll() {
+      48     2098913 :   if( atLeastOneSet && !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+      49    10441330 :   for(unsigned i=0; i<values.size(); ++i) clear(i);
+      50     2098913 :   clearTemporyDerivatives(); hasDerivatives.deactivateAll(); atLeastOneSet=false;
+      51     2098913 : }
+      52             : 
+      53     8342417 : void MultiValue::clear( const unsigned& ival ) {
+      54     8342417 :   values[ival]=0;
+      55     8342417 :   unsigned base=ival*nderivatives, ndert=hasDerivatives.getNumberActive();
+      56   311768969 :   for(unsigned i=0; i<ndert; ++i) derivatives[ base+hasDerivatives[i] ]=0.;
+      57     8342417 : }
+      58             : 
+      59     2098913 : void MultiValue::clearTemporyDerivatives() {
+      60     2098913 :   unsigned ndert=hasDerivatives.getNumberActive(); tmpval=0.;
+      61    82072301 :   for(unsigned i=0; i<ndert; ++i) tmpder[ hasDerivatives[i] ]=0.;
+      62     2098913 : }
+      63             : 
+      64      502652 : 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      502652 :   if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+      67             : 
+      68             :   plumed_dbg_assert( off<stride );
+      69      502652 :   unsigned base=nderivatives*ival, ndert=hasDerivatives.getNumberActive();
+      70      502652 :   unsigned start=bufstart+stride*(nderivatives+1)*iout + stride;
+      71    29225155 :   for(unsigned i=0; i<ndert; ++i) {
+      72             :     unsigned jder=hasDerivatives[i];
+      73    28722503 :     buffer[start+jder*stride] += df*derivatives[base+jder];
+      74             :   }
+      75      502652 : }
+      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     1869892 : void MultiValue::quotientRule( const unsigned& nder, const unsigned& oder ) {
+     103             :   plumed_dbg_assert( nder<values.size() && oder<values.size() );
+     104     1869892 :   if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+     105             : 
+     106     1869892 :   unsigned ndert=hasDerivatives.getNumberActive(); double wpref;
+     107     1869892 :   unsigned obase=oder*nderivatives, nbase=nder*nderivatives;
+     108             : 
+     109     1869892 :   if( std::fabs(tmpval)>epsilon ) { wpref=1.0/tmpval; }
+     110             :   else { wpref=1.0; }
+     111             : 
+     112     1869892 :   double pref = values[nder]*wpref*wpref;
+     113   179899336 :   for(unsigned j=0; j<ndert; ++j) {
+     114             :     unsigned jder=hasDerivatives[j];
+     115   178029444 :     derivatives[obase+jder] = wpref*derivatives[nbase+jder]  - pref*tmpder[jder];
+     116             :   }
+     117     1869892 :   values[oder] = wpref*values[nder];
+     118     1869892 : }
+     119             : 
+     120             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..050d73e92a --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue11updateIndexERKj222000
_ZN4PLMD10MultiValue20addTemporyDerivativeERKjRKd35718834
_ZN4PLMD10MultiValue13setDerivativeERKjS2_RKd145611693
_ZN4PLMD10MultiValue13addDerivativeERKjS2_RKd1359057860
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MultiValue.h.func.html b/coverage/tools/MultiValue.h.func.html new file mode 100644 index 0000000000..528fbd12d7 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue11updateIndexERKj222000
_ZN4PLMD10MultiValue13addDerivativeERKjS2_RKd1359057860
_ZN4PLMD10MultiValue13setDerivativeERKjS2_RKd145611693
_ZN4PLMD10MultiValue20addTemporyDerivativeERKjRKd35718834
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/MultiValue.h.gcov.html b/coverage/tools/MultiValue.h.gcov.html new file mode 100644 index 0000000000..42437b71bb --- /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-06-10 08:19:14Functions: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   172403989 :   return values.size();
+     112             : }
+     113             : 
+     114             : inline
+     115             : unsigned MultiValue::getNumberOfDerivatives() const {
+     116    30912249 :   return nderivatives; //derivatives.ncols();
+     117             : }
+     118             : 
+     119             : inline
+     120             : double MultiValue::get( const unsigned& ival ) const {
+     121             :   plumed_dbg_assert( ival<=values.size() );
+     122   173450639 :   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     1829471 :   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    62229581 :   values[ival]+=val;
+     135             : }
+     136             : 
+     137             : inline
+     138  1359057860 : void MultiValue::addDerivative( const unsigned& ival, const unsigned& jder, const double& der) {
+     139  1359057860 :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     140  1359057860 :   hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder] += der;
+     141  1359057860 : }
+     142             : 
+     143             : inline
+     144             : void MultiValue::addTemporyValue( const double& val ) {
+     145     2752543 :   tmpval += val;
+     146             : }
+     147             : 
+     148             : inline
+     149    35718834 : void MultiValue::addTemporyDerivative( const unsigned& jder, const double& der ) {
+     150    35718834 :   plumed_dbg_assert( jder<nderivatives ); atLeastOneSet=true;
+     151    35718834 :   hasDerivatives.activate(jder); tmpder[jder] += der;
+     152    35718834 : }
+     153             : 
+     154             : 
+     155             : inline
+     156   145611693 : void MultiValue::setDerivative( const unsigned& ival, const unsigned& jder, const double& der) {
+     157   145611693 :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     158   145611693 :   hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder]=der;
+     159   145611693 : }
+     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   535797285 :   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     1621195 :   return hasDerivatives.updateComplete();
+     177             : }
+     178             : 
+     179             : inline
+     180             : void MultiValue::emptyActiveMembers() {
+     181      932792 :   hasDerivatives.emptyActiveMembers();
+     182             : }
+     183             : 
+     184             : inline
+     185             : void MultiValue::putIndexInActiveArray( const unsigned& ind ) {
+     186    32660076 :   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      876487 :   hasDerivatives.completeUpdate();
+     202       94076 : }
+     203             : 
+     204             : inline
+     205             : unsigned MultiValue::getNumberActive() const {
+     206    41498512 :   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      919363 :   return indices;
+     223             : }
+     224             : 
+     225             : inline
+     226             : std::vector<unsigned>& MultiValue::getSortIndices() {
+     227      447981 :   return sort_indices;
+     228             : }
+     229             : 
+     230             : inline
+     231             : std::vector<Vector>& MultiValue::getAtomVector() {
+     232      678710 :   return tmp_atoms;
+     233             : }
+     234             : 
+     235             : inline
+     236             : bool MultiValue::isActive( const unsigned& ind ) const {
+     237   423929148 :   return hasDerivatives.isActive( ind );
+     238             : }
+     239             : 
+     240             : }
+     241             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..150b14fa5e --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + 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:9610789.7 %
Date:2024-06-10 08:19:14Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborList12getNeighborsEj0
_ZN4PLMD12NeighborList13setLastUpdateEj0
_ZNK4PLMD12NeighborList13getLastUpdateEv0
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EERKbS8_RKNS_3PbcERNS_12CommunicatorERKdRKj39
_ZN4PLMD12NeighborList18getReducedAtomListEv240
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EES6_RKbS8_S8_RKNS_3PbcERNS_12CommunicatorERKdRKj245
_ZN4PLMD12NeighborList10initializeEv284
_ZN4PLMD12NeighborList14setRequestListEv3138
_ZN4PLMD12NeighborList6updateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE3138
_ZNK4PLMD12NeighborList9getStrideEv13616
_ZN4PLMD12NeighborList15getFullAtomListEv69974
_ZNK4PLMD12NeighborList4sizeEv23715949
_ZNK4PLMD12NeighborList22getClosePairAtomNumberEj34665936
_ZN4PLMD12NeighborList12getIndexPairEj49191551
_ZNK4PLMD12NeighborList12getClosePairEj77112268
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.func.html b/coverage/tools/NeighborList.cpp.func.html new file mode 100644 index 0000000000..07d8672ccf --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + 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:9610789.7 %
Date:2024-06-10 08:19:14Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborList10initializeEv284
_ZN4PLMD12NeighborList12getIndexPairEj49191551
_ZN4PLMD12NeighborList12getNeighborsEj0
_ZN4PLMD12NeighborList13setLastUpdateEj0
_ZN4PLMD12NeighborList14setRequestListEv3138
_ZN4PLMD12NeighborList15getFullAtomListEv69974
_ZN4PLMD12NeighborList18getReducedAtomListEv240
_ZN4PLMD12NeighborList6updateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE3138
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EERKbS8_RKNS_3PbcERNS_12CommunicatorERKdRKj39
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EES6_RKbS8_S8_RKNS_3PbcERNS_12CommunicatorERKdRKj245
_ZNK4PLMD12NeighborList12getClosePairEj77112268
_ZNK4PLMD12NeighborList13getLastUpdateEv0
_ZNK4PLMD12NeighborList22getClosePairAtomNumberEj34665936
_ZNK4PLMD12NeighborList4sizeEv23715949
_ZNK4PLMD12NeighborList9getStrideEv13616
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.gcov.html b/coverage/tools/NeighborList.cpp.gcov.html new file mode 100644 index 0000000000..d27cab5810 --- /dev/null +++ b/coverage/tools/NeighborList.cpp.gcov.html @@ -0,0 +1,302 @@ + + + + + + + + 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:9610789.7 %
Date:2024-06-10 08:19:14Functions:121580.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 "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             : namespace PLMD {
+      34             : 
+      35         245 : NeighborList::NeighborList(const std::vector<AtomNumber>& list0, const std::vector<AtomNumber>& list1,
+      36             :                            const bool& serial, const bool& do_pair, const bool& do_pbc, const Pbc& pbc, Communicator& cm,
+      37         245 :                            const double& distance, const unsigned& stride): reduced(false),
+      38         245 :   serial_(serial), do_pair_(do_pair), do_pbc_(do_pbc), pbc_(&pbc), comm(cm),
+      39         245 :   distance_(distance), stride_(stride)
+      40             : {
+      41             : // store full list of atoms needed
+      42         245 :   fullatomlist_=list0;
+      43         245 :   fullatomlist_.insert(fullatomlist_.end(),list1.begin(),list1.end());
+      44         245 :   nlist0_=list0.size();
+      45         245 :   nlist1_=list1.size();
+      46         245 :   twolists_=true;
+      47         245 :   if(!do_pair) {
+      48         220 :     nallpairs_=nlist0_*nlist1_;
+      49             :   } else {
+      50          25 :     plumed_assert(nlist0_==nlist1_) << "when using PAIR option, the two groups should have the same number of elements\n"
+      51           0 :                                     << "the groups you specified have size "<<nlist0_<<" and "<<nlist1_;
+      52          25 :     nallpairs_=nlist0_;
+      53             :   }
+      54         245 :   initialize();
+      55         245 :   lastupdate_=0;
+      56         245 : }
+      57             : 
+      58          39 : NeighborList::NeighborList(const std::vector<AtomNumber>& list0, const bool& serial, const bool& do_pbc,
+      59             :                            const Pbc& pbc, Communicator& cm, const double& distance,
+      60          39 :                            const unsigned& stride): reduced(false),
+      61          39 :   serial_(serial), do_pbc_(do_pbc), pbc_(&pbc), comm(cm),
+      62          39 :   distance_(distance), stride_(stride) {
+      63          39 :   fullatomlist_=list0;
+      64          39 :   nlist0_=list0.size();
+      65          39 :   twolists_=false;
+      66          39 :   nallpairs_=nlist0_*(nlist0_-1)/2;
+      67          39 :   initialize();
+      68          39 :   lastupdate_=0;
+      69          39 : }
+      70             : 
+      71         284 : void NeighborList::initialize() {
+      72         284 :   neighbors_.clear();
+      73    42954115 :   for(unsigned int i=0; i<nallpairs_; ++i) {
+      74    85907662 :     neighbors_.push_back(getIndexPair(i));
+      75             :   }
+      76         284 : }
+      77             : 
+      78       69974 : std::vector<AtomNumber>& NeighborList::getFullAtomList() {
+      79       69974 :   return fullatomlist_;
+      80             : }
+      81             : 
+      82    49191551 : std::pair<unsigned,unsigned> NeighborList::getIndexPair(unsigned ipair) {
+      83             :   std::pair<unsigned,unsigned> index;
+      84    49191551 :   if(twolists_ && do_pair_) {
+      85         636 :     index=std::pair<unsigned,unsigned>(ipair,ipair+nlist0_);
+      86    49190915 :   } else if (twolists_ && !do_pair_) {
+      87     8866469 :     index=std::pair<unsigned,unsigned>(ipair/nlist1_,ipair%nlist1_+nlist0_);
+      88    40324446 :   } else if (!twolists_) {
+      89    40324446 :     unsigned ii = nallpairs_-1-ipair;
+      90    40324446 :     unsigned  K = unsigned(std::floor((std::sqrt(double(8*ii+1))+1)/2));
+      91    40324446 :     unsigned jj = ii-K*(K-1)/2;
+      92    40324446 :     index=std::pair<unsigned,unsigned>(nlist0_-1-K,nlist0_-1-jj);
+      93             :   }
+      94    49191551 :   return index;
+      95             : }
+      96             : 
+      97        3138 : void NeighborList::update(const std::vector<Vector>& positions) {
+      98        3138 :   neighbors_.clear();
+      99        3138 :   const double d2=distance_*distance_;
+     100             :   // check if positions array has the correct length
+     101        3138 :   plumed_assert(positions.size()==fullatomlist_.size());
+     102             : 
+     103        3138 :   unsigned stride=comm.Get_size();
+     104        3138 :   unsigned rank=comm.Get_rank();
+     105        3138 :   unsigned nt=OpenMP::getNumThreads();
+     106        3138 :   if(serial_) {
+     107             :     stride=1;
+     108             :     rank=0;
+     109             :     nt=1;
+     110             :   }
+     111             :   std::vector<unsigned> local_flat_nl;
+     112             : 
+     113        3138 :   #pragma omp parallel num_threads(nt)
+     114             :   {
+     115             :     std::vector<unsigned> private_flat_nl;
+     116             :     #pragma omp for nowait
+     117             :     for(unsigned int i=rank; i<nallpairs_; i+=stride) {
+     118             :       std::pair<unsigned,unsigned> index=getIndexPair(i);
+     119             :       unsigned index0=index.first;
+     120             :       unsigned index1=index.second;
+     121             :       Vector distance;
+     122             :       if(do_pbc_) {
+     123             :         distance=pbc_->distance(positions[index0],positions[index1]);
+     124             :       } else {
+     125             :         distance=delta(positions[index0],positions[index1]);
+     126             :       }
+     127             :       double value=modulo2(distance);
+     128             :       if(value<=d2) {
+     129             :         private_flat_nl.push_back(index0);
+     130             :         private_flat_nl.push_back(index1);
+     131             :       }
+     132             :     }
+     133             :     #pragma omp critical
+     134             :     local_flat_nl.insert(local_flat_nl.end(), private_flat_nl.begin(), private_flat_nl.end());
+     135             :   }
+     136             : 
+     137             :   // find total dimension of neighborlist
+     138        3138 :   std::vector <int> local_nl_size(stride, 0);
+     139        3138 :   local_nl_size[rank] = local_flat_nl.size();
+     140        3138 :   if(!serial_) comm.Sum(&local_nl_size[0], stride);
+     141             :   int tot_size = std::accumulate(local_nl_size.begin(), local_nl_size.end(), 0);
+     142        3138 :   if(tot_size==0) {setRequestList(); return;}
+     143             :   // merge
+     144        3120 :   std::vector<unsigned> merge_nl(tot_size, 0);
+     145             :   // calculate vector of displacement
+     146        3120 :   std::vector<int> disp(stride);
+     147        3120 :   disp[0] = 0;
+     148             :   int rank_size = 0;
+     149        9216 :   for(unsigned i=0; i<stride-1; ++i) {
+     150        6096 :     rank_size += local_nl_size[i];
+     151        6096 :     disp[i+1] = rank_size;
+     152             :   }
+     153             :   // Allgather neighbor list
+     154        5197 :   if(comm.initialized()&&!serial_) comm.Allgatherv((!local_flat_nl.empty()?&local_flat_nl[0]:NULL), local_nl_size[rank], &merge_nl[0], &local_nl_size[0], &disp[0]);
+     155        1016 :   else merge_nl = local_flat_nl;
+     156             :   // resize neighbor stuff
+     157        3120 :   neighbors_.resize(tot_size/2);
+     158     6114036 :   for(unsigned i=0; i<tot_size/2; i++) {
+     159     6110916 :     unsigned j=2*i;
+     160     6110916 :     neighbors_[i] = std::make_pair(merge_nl[j],merge_nl[j+1]);
+     161             :   }
+     162             : 
+     163        3120 :   setRequestList();
+     164             : }
+     165             : 
+     166        3138 : void NeighborList::setRequestList() {
+     167        3138 :   requestlist_.clear();
+     168     6114054 :   for(unsigned int i=0; i<size(); ++i) {
+     169     6110916 :     requestlist_.push_back(fullatomlist_[neighbors_[i].first]);
+     170     6110916 :     requestlist_.push_back(fullatomlist_[neighbors_[i].second]);
+     171             :   }
+     172        3138 :   Tools::removeDuplicates(requestlist_);
+     173        3138 :   reduced=false;
+     174        3138 : }
+     175             : 
+     176         240 : std::vector<AtomNumber>& NeighborList::getReducedAtomList() {
+     177      168359 :   if(!reduced)for(unsigned int i=0; i<size(); ++i) {
+     178             :       unsigned newindex0=0,newindex1=0;
+     179      168119 :       AtomNumber index0=fullatomlist_[neighbors_[i].first];
+     180      168119 :       AtomNumber index1=fullatomlist_[neighbors_[i].second];
+     181             : // I exploit the fact that requestlist_ is an ordered vector
+     182      168119 :       auto p = std::find(requestlist_.begin(), requestlist_.end(), index0); plumed_dbg_assert(p!=requestlist_.end()); newindex0=p-requestlist_.begin();
+     183      168119 :       p = std::find(requestlist_.begin(), requestlist_.end(), index1); plumed_dbg_assert(p!=requestlist_.end()); newindex1=p-requestlist_.begin();
+     184             :       neighbors_[i]=std::pair<unsigned,unsigned>(newindex0,newindex1);
+     185             :     }
+     186         240 :   reduced=true;
+     187         240 :   return requestlist_;
+     188             : }
+     189             : 
+     190       13616 : unsigned NeighborList::getStride() const {
+     191       13616 :   return stride_;
+     192             : }
+     193             : 
+     194           0 : unsigned NeighborList::getLastUpdate() const {
+     195           0 :   return lastupdate_;
+     196             : }
+     197             : 
+     198           0 : void NeighborList::setLastUpdate(unsigned step) {
+     199           0 :   lastupdate_=step;
+     200           0 : }
+     201             : 
+     202    23715949 : unsigned NeighborList::size() const {
+     203    23715949 :   return neighbors_.size();
+     204             : }
+     205             : 
+     206    77112268 : std::pair<unsigned,unsigned> NeighborList::getClosePair(unsigned i) const {
+     207    77112268 :   return neighbors_[i];
+     208             : }
+     209             : 
+     210    34665936 : std::pair<AtomNumber,AtomNumber> NeighborList::getClosePairAtomNumber(unsigned i) const {
+     211             :   std::pair<AtomNumber,AtomNumber> Aneigh;
+     212    34665936 :   Aneigh=std::pair<AtomNumber,AtomNumber>(fullatomlist_[neighbors_[i].first],fullatomlist_[neighbors_[i].second]);
+     213    34665936 :   return Aneigh;
+     214             : }
+     215             : 
+     216           0 : std::vector<unsigned> NeighborList::getNeighbors(unsigned index) {
+     217             :   std::vector<unsigned> neighbors;
+     218           0 :   for(unsigned int i=0; i<size(); ++i) {
+     219           0 :     if(neighbors_[i].first==index)  neighbors.push_back(neighbors_[i].second);
+     220           0 :     if(neighbors_[i].second==index) neighbors.push_back(neighbors_[i].first);
+     221             :   }
+     222           0 :   return neighbors;
+     223             : }
+     224             : 
+     225             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..9e2ca3fd89 --- /dev/null +++ b/coverage/tools/NeighborList.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + 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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborListD2Ev284
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/NeighborList.h.func.html b/coverage/tools/NeighborList.h.func.html new file mode 100644 index 0000000000..897025d669 --- /dev/null +++ b/coverage/tools/NeighborList.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + 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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborListD2Ev284
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/NeighborList.h.gcov.html b/coverage/tools/NeighborList.h.gcov.html new file mode 100644 index 0000000000..3e4040f717 --- /dev/null +++ b/coverage/tools/NeighborList.h.gcov.html @@ -0,0 +1,171 @@ + + + + + + + + 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-06-10 08:19:14Functions: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             : #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             : {
+      39             :   bool reduced;
+      40             :   bool serial_;
+      41             :   bool do_pair_,do_pbc_,twolists_;
+      42             :   const PLMD::Pbc* pbc_;
+      43             :   Communicator& comm;
+      44             :   std::vector<PLMD::AtomNumber> fullatomlist_,requestlist_;
+      45             :   std::vector<std::pair<unsigned,unsigned> > neighbors_;
+      46             :   double distance_;
+      47             :   unsigned stride_,nlist0_,nlist1_,nallpairs_,lastupdate_;
+      48             : /// Initialize the neighbor list with all possible pairs
+      49             :   void initialize();
+      50             : /// Return the pair of indexes in the positions array
+      51             : /// of the two atoms forming the i-th pair among all possible pairs
+      52             :   std::pair<unsigned,unsigned> getIndexPair(unsigned i);
+      53             : /// Extract the list of atoms from the current list of close pairs
+      54             :   void setRequestList();
+      55             : public:
+      56             :   NeighborList(const std::vector<PLMD::AtomNumber>& list0,
+      57             :                const std::vector<PLMD::AtomNumber>& list1,
+      58             :                const bool& serial,
+      59             :                const bool& do_pair, const bool& do_pbc, const PLMD::Pbc& pbc, Communicator &cm,
+      60         388 :                const double& distance=1.0e+30, const unsigned& stride=0);
+      61             :   NeighborList(const std::vector<PLMD::AtomNumber>& list0,
+      62             :                const bool& serial,
+      63             :                const bool& do_pbc,
+      64          22 :                const PLMD::Pbc& pbc, Communicator &cm, const double& distance=1.0e+30,
+      65          22 :                const unsigned& stride=0);
+      66             : /// Return the list of all atoms. These are needed to rebuild the neighbor list.
+      67             :   std::vector<PLMD::AtomNumber>& getFullAtomList();
+      68             : /// Update the indexes in the neighbor list to match the
+      69             : /// ordering in the new positions array
+      70             : /// and return the new list of atoms that must be requested to the main code
+      71             :   std::vector<PLMD::AtomNumber>& getReducedAtomList();
+      72             : /// Update the neighbor list and prepare the new
+      73             : /// list of atoms that will be requested to the main code
+      74             :   void update(const std::vector<PLMD::Vector>& positions);
+      75             : /// Get the update stride of the neighbor list
+      76             :   unsigned getStride() const;
+      77             : /// Get the last step in which the neighbor list was updated
+      78             :   unsigned getLastUpdate() const;
+      79             : /// Set the step of the last update
+      80             :   void setLastUpdate(unsigned step);
+      81             : /// Get the size of the neighbor list
+      82             :   unsigned size() const;
+      83             : /// Get the i-th pair of the neighbor list
+      84             :   std::pair<unsigned,unsigned> getClosePair(unsigned i) const;
+      85             : /// Get the list of neighbors of the i-th atom
+      86             :   std::vector<unsigned> getNeighbors(unsigned i);
+      87         284 :   ~NeighborList() {}
+      88             : /// Get the i-th pair of AtomNumbers from the neighbor list
+      89             :   std::pair<AtomNumber,AtomNumber> getClosePairAtomNumber(unsigned i) const;
+      90             : };
+      91             : 
+      92             : }
+      93             : 
+      94             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..78baec3ea3 --- /dev/null +++ b/coverage/tools/OFile.cpp.func-sort-c.html @@ -0,0 +1,185 @@ + + + + + + + + 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:21722198.2 %
Date:2024-06-10 08:19:14Functions:2828100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEl1
_ZN4PLMD5OFile14enforceRestartEv1
_ZN4PLMD5OFile4linkERS0_11
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj31
_ZN4PLMD5OFile14backupAllFilesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm48
_ZN4PLMD5OFile15setBackupStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE121
_ZN4PLMD5OFile6rewindEv134
_ZN4PLMD5OFile13enforceBackupEv1144
_ZN4PLMD5OFile10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3199
_ZN4PLMD5OFile11clearFieldsEv3201
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3482
_ZNK4PLMD5OFile12checkRestartEv3518
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE5735
_ZN4PLMD5OFile5flushEv8436
_ZN4PLMD5OFileC1Ev14415
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27816
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE404395
_ZN4PLMD5OFileC2Ev404395
_ZN4PLMD5OFile8fmtFieldEv424681
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd537963
_ZN4PLMD5OFile10printFieldEv3886692
_ZN4PLMD5OFile7llwriteEPKcm5373431
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6031476
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14172009
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15101445
_ZN4PLMD5OFile6printfEPKcz22722870
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_36950358
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/OFile.cpp.func.html b/coverage/tools/OFile.cpp.func.html new file mode 100644 index 0000000000..087fe5ab4a --- /dev/null +++ b/coverage/tools/OFile.cpp.func.html @@ -0,0 +1,185 @@ + + + + + + + + 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:21722198.2 %
Date:2024-06-10 08:19:14Functions:2828100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5OFile10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3199
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd537963
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_36950358
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15101445
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6031476
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj31
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEl1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm48
_ZN4PLMD5OFile10printFieldEv3886692
_ZN4PLMD5OFile11clearFieldsEv3201
_ZN4PLMD5OFile13enforceBackupEv1144
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE404395
_ZN4PLMD5OFile14backupAllFilesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD5OFile14enforceRestartEv1
_ZN4PLMD5OFile15setBackupStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE121
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE5735
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27816
_ZN4PLMD5OFile4linkERS0_11
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3482
_ZN4PLMD5OFile5flushEv8436
_ZN4PLMD5OFile6printfEPKcz22722870
_ZN4PLMD5OFile6rewindEv134
_ZN4PLMD5OFile7llwriteEPKcm5373431
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14172009
_ZN4PLMD5OFile8fmtFieldEv424681
_ZN4PLMD5OFileC1Ev14415
_ZN4PLMD5OFileC2Ev404395
_ZNK4PLMD5OFile12checkRestartEv3518
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/OFile.cpp.gcov.html b/coverage/tools/OFile.cpp.gcov.html new file mode 100644 index 0000000000..db7c27f9f6 --- /dev/null +++ b/coverage/tools/OFile.cpp.gcov.html @@ -0,0 +1,496 @@ + + + + + + + + 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:21722198.2 %
Date:2024-06-10 08:19:14Functions:2828100.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 "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     5373431 : size_t OFile::llwrite(const char*ptr,size_t s) {
+      47             :   size_t r;
+      48     5373431 :   if(linked) return linked->llwrite(ptr,s);
+      49     5373379 :   if(! (comm && comm->Get_rank()>0)) {
+      50     4571294 :     if(!fp) plumed_merror("writing on uninitialized File");
+      51     4571294 :     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     4570031 :       r=std::fwrite(ptr,1,s,fp);
+      59             :     }
+      60             :   }
+      61             : //  This barrier is apparently useless since it comes
+      62             : //  just before a Bcast.
+      63             : //
+      64             : //  Anyway, it looks like it is solving an issue that appeared on
+      65             : //  TRAVIS (at least on my laptop) so I add it here.
+      66             : //  GB
+      67     5373379 :   if(comm) comm->Barrier();
+      68             : 
+      69             : 
+      70     5373379 :   if(comm) comm->Bcast(r,0);
+      71     5373379 :   return r;
+      72             : }
+      73             : 
+      74      418810 : OFile::OFile():
+      75      418810 :   linked(NULL),
+      76      418810 :   fieldChanged(false),
+      77      418810 :   backstring("bck"),
+      78      418810 :   enforceRestart_(false),
+      79      418810 :   enforceBackup_(false)
+      80             : {
+      81      418810 :   fmtField();
+      82      418810 :   buflen=1;
+      83      418810 :   actual_buffer_length=0;
+      84      418810 :   buffer=Tools::make_unique<char[]>(buflen);
+      85             : // these are set to zero to avoid valgrind errors
+      86      837620 :   for(int i=0; i<buflen; ++i) buffer[i]=0;
+      87      418810 :   buffer_string=Tools::make_unique<char[]>(1000);
+      88             : // these are set to zero to avoid valgrind errors
+      89   419228810 :   for(unsigned i=0; i<1000; ++i) buffer_string[i]=0;
+      90      418810 : }
+      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      404395 : OFile& OFile::setLinePrefix(const std::string&l) {
+     100      404395 :   linePrefix=l;
+     101      404395 :   return *this;
+     102             : }
+     103             : 
+     104    22722870 : int OFile::printf(const char*fmt,...) {
+     105             :   va_list arg;
+     106    22722870 :   va_start(arg, fmt);
+     107    22722870 :   int r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     108    22722870 :   va_end(arg);
+     109    22722870 :   if(r>=buflen-actual_buffer_length) {
+     110             :     int newlen=buflen;
+     111       45189 :     while(newlen<=r+actual_buffer_length) newlen*=2;
+     112       15223 :     auto newbuf=Tools::make_unique<char[]>(newlen);
+     113       15223 :     std::memmove(newbuf.get(),buffer.get(),buflen);
+     114     3184571 :     for(int k=buflen; k<newlen; k++) newbuf[k]=0;
+     115             :     buffer=std::move(newbuf);
+     116       15223 :     buflen=newlen;
+     117             :     va_list arg;
+     118       15223 :     va_start(arg, fmt);
+     119       15223 :     r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     120       15223 :     va_end(arg);
+     121             :   }
+     122    22722870 :   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.get();
+     126             :   char*p2;
+     127             : // newline is only searched in the just added portion:
+     128    22722870 :   char*psearch=p1+actual_buffer_length;
+     129    22722870 :   actual_buffer_length+=r;
+     130    27869023 :   while((p2=std::strchr(psearch,'\n'))) {
+     131     5146153 :     if(linePrefix.length()>0) llwrite(linePrefix.c_str(),linePrefix.length());
+     132     5146153 :     llwrite(p1,p2-p1+1);
+     133     5146153 :     actual_buffer_length-=(p2-p1)+1;
+     134     5146153 :     p1=p2+1;
+     135             :     psearch=p1;
+     136             :   };
+     137    22722870 :   if(buffer.get()!=p1) std::memmove(buffer.get(),p1,actual_buffer_length);
+     138    22722870 :   return r;
+     139             : }
+     140             : 
+     141       27816 : OFile& OFile::addConstantField(const std::string&name) {
+     142             :   Field f;
+     143             :   f.name=name;
+     144       27816 :   const_fields.push_back(f);
+     145       27816 :   return *this;
+     146             : }
+     147             : 
+     148             : 
+     149        3201 : OFile& OFile::clearFields() {
+     150        3201 :   fields.clear();
+     151        3201 :   const_fields.clear();
+     152        3201 :   previous_fields.clear();
+     153        3201 :   return *this;
+     154             : }
+     155             : 
+     156    14172009 : OFile& OFile::fmtField(const std::string&fmt) {
+     157    14172009 :   this->fieldFmt=fmt;
+     158    14172009 :   return *this;
+     159             : }
+     160             : 
+     161      424681 : OFile& OFile::fmtField() {
+     162      424681 :   this->fieldFmt="%23.16lg";
+     163      424681 :   return *this;
+     164             : }
+     165             : 
+     166    15101445 : 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    15101445 :   if(std::isnan(v)) v=std::numeric_limits<double>::quiet_NaN();
+     171             :   std::sprintf(buffer_string.get(),fieldFmt.c_str(),v);
+     172    15101445 :   printField(name,buffer_string.get());
+     173    15101445 :   return *this;
+     174             : }
+     175             : 
+     176     6031476 : OFile& OFile::printField(const std::string&name,int v) {
+     177             :   std::sprintf(buffer_string.get()," %d",v);
+     178     6031476 :   printField(name,buffer_string.get());
+     179     6031476 :   return *this;
+     180             : }
+     181             : 
+     182           1 : OFile& OFile::printField(const std::string&name,long int v) {
+     183             :   std::sprintf(buffer_string.get()," %ld",v);
+     184           1 :   printField(name,buffer_string.get());
+     185           1 :   return *this;
+     186             : }
+     187             : 
+     188          31 : OFile& OFile::printField(const std::string&name,unsigned v) {
+     189             :   std::sprintf(buffer_string.get()," %u",v);
+     190          31 :   printField(name,buffer_string.get());
+     191          31 :   return *this;
+     192             : }
+     193             : 
+     194          48 : OFile& OFile::printField(const std::string&name,long unsigned v) {
+     195             :   std::sprintf(buffer_string.get()," %lu",v);
+     196          48 :   printField(name,buffer_string.get());
+     197          48 :   return *this;
+     198             : }
+     199             : 
+     200    36950358 : OFile& OFile::printField(const std::string&name,const std::string & v) {
+     201             :   unsigned i;
+     202   189697493 :   for(i=0; i<const_fields.size(); i++) if(const_fields[i].name==name) break;
+     203    36950358 :   if(i>=const_fields.size()) {
+     204             :     Field field;
+     205             :     field.name=name;
+     206             :     field.value=v;
+     207    16174094 :     fields.push_back(field);
+     208             :   } else {
+     209    20776264 :     if(const_fields[i].value!=v) fieldChanged=true;
+     210             :     const_fields[i].value=v;
+     211             :   }
+     212    36950358 :   return *this;
+     213             : }
+     214             : 
+     215        5735 : OFile& OFile::setupPrintValue( Value *val ) {
+     216        5735 :   if( val->isPeriodic() ) {
+     217         475 :     addConstantField("min_" + val->getName() );
+     218         950 :     addConstantField("max_" + val->getName() );
+     219             :   }
+     220        5735 :   return *this;
+     221             : }
+     222             : 
+     223      537963 : OFile& OFile::printField( Value* val, const double& v ) {
+     224      537963 :   printField( val->getName(), v );
+     225      537963 :   if( val->isPeriodic() ) {
+     226       12918 :     std::string min, max; val->getDomain( min, max );
+     227       12918 :     printField( "min_" + val->getName(), min );
+     228       25836 :     printField("max_" + val->getName(), max );
+     229             :   }
+     230      537963 :   return *this;
+     231             : }
+     232             : 
+     233     3886692 : OFile& OFile::printField() {
+     234             :   bool reprint=false;
+     235     3886692 :   if(fieldChanged || fields.size()!=previous_fields.size()) {
+     236             :     reprint=true;
+     237    19996953 :   } else for(unsigned i=0; i<fields.size(); i++) {
+     238    16116186 :       if( previous_fields[i].name!=fields[i].name ||
+     239    16116184 :           (fields[i].constant && fields[i].value!=previous_fields[i].value) ) {
+     240             :         reprint=true;
+     241             :         break;
+     242             :       }
+     243             :     }
+     244     3886692 :   if(reprint) {
+     245        5925 :     printf("#! FIELDS");
+     246       63837 :     for(unsigned i=0; i<fields.size(); i++) printf(" %s",fields[i].name.c_str());
+     247        5925 :     printf("\n");
+     248       33677 :     for(unsigned i=0; i<const_fields.size(); i++) {
+     249       27752 :       printf("#! SET %s %s",const_fields[i].name.c_str(),const_fields[i].value.c_str());
+     250       27752 :       printf("\n");
+     251             :     }
+     252             :   }
+     253    20060786 :   for(unsigned i=0; i<fields.size(); i++) printf("%s",fields[i].value.c_str());
+     254     3886692 :   printf("\n");
+     255     3886692 :   previous_fields=fields;
+     256             :   fields.clear();
+     257     3886692 :   fieldChanged=false;
+     258     3886692 :   return *this;
+     259             : }
+     260             : 
+     261         121 : void OFile::setBackupString( const std::string& str ) {
+     262         121 :   backstring=str;
+     263         121 : }
+     264             : 
+     265          36 : void OFile::backupAllFiles( const std::string& str ) {
+     266          36 :   if(str=="/dev/null") return;
+     267          36 :   plumed_assert( backstring!="bck" && !checkRestart());
+     268          36 :   size_t found=str.find_last_of("/\\");
+     269          36 :   std::string filename = appendSuffix(str,getSuffix());
+     270          36 :   std::string directory=filename.substr(0,found+1);
+     271          36 :   std::string file=filename.substr(found+1);
+     272          36 :   if( FileExist(filename) ) backupFile("bck", filename);
+     273          36 :   for(int i=0;; i++) {
+     274          36 :     std::string num; Tools::convert(i,num);
+     275          72 :     std::string filestr = directory + backstring + "." + num + "." + file;
+     276          36 :     if( !FileExist(filestr) ) break;
+     277           0 :     backupFile( "bck", filestr);
+     278           0 :   }
+     279             : }
+     280             : 
+     281        3199 : void OFile::backupFile( const std::string& bstring, const std::string& fname ) {
+     282        3199 :   if(fname=="/dev/null") return;
+     283        3045 :   int maxbackup=100;
+     284        3045 :   if(std::getenv("PLUMED_MAXBACKUP")) Tools::convert(std::getenv("PLUMED_MAXBACKUP"),maxbackup);
+     285        3045 :   if(maxbackup>0 && (!comm || comm->Get_rank()==0)) {
+     286        2585 :     FILE* ff=std::fopen(const_cast<char*>(fname.c_str()),"r");
+     287        2585 :     if(ff) {
+     288          65 :       std::fclose(ff);
+     289             :       std::string backup;
+     290          65 :       size_t found=fname.find_last_of("/\\");
+     291          65 :       std::string directory=fname.substr(0,found+1);
+     292          65 :       std::string file=fname.substr(found+1);
+     293          65 :       for(int i=0;; i++) {
+     294             :         std::string num;
+     295          65 :         Tools::convert(i,num);
+     296          65 :         if(i>maxbackup) plumed_merror("cannot backup file "+file+" maximum number of backup is "+num+"\n");
+     297         130 :         backup=directory+bstring +"."+num+"."+file;
+     298          65 :         FILE* fff=std::fopen(backup.c_str(),"r");
+     299          65 :         if(!fff) break;
+     300           0 :         else std::fclose(fff);
+     301           0 :       }
+     302          65 :       int check=rename(fname.c_str(),backup.c_str());
+     303          65 :       plumed_massert(check==0,"renaming "+fname+" into "+backup+" failed for reason: "+std::strerror(errno));
+     304             :     }
+     305             :   }
+     306             : }
+     307             : 
+     308        3482 : OFile& OFile::open(const std::string&path) {
+     309        3482 :   plumed_assert(!cloned);
+     310        3482 :   eof=false;
+     311        3482 :   err=false;
+     312        3482 :   fp=NULL;
+     313        3482 :   gzfp=NULL;
+     314        3482 :   this->path=path;
+     315        6964 :   this->path=appendSuffix(path,getSuffix());
+     316        3482 :   if(checkRestart()) {
+     317         283 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"a");
+     318         283 :     mode="a";
+     319         566 :     if(Tools::extension(this->path)=="gz") {
+     320             : #ifdef __PLUMED_HAS_ZLIB
+     321          12 :       gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"a9");
+     322             : #else
+     323             :       plumed_merror("file " + getPath() + ": trying to use a gz file without zlib being linked");
+     324             : #endif
+     325             :     }
+     326             :   } else {
+     327        3199 :     backupFile( backstring, this->path );
+     328        3199 :     if(comm)comm->Barrier();
+     329        3199 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"w");
+     330        3199 :     mode="w";
+     331        6398 :     if(Tools::extension(this->path)=="gz") {
+     332             : #ifdef __PLUMED_HAS_ZLIB
+     333          13 :       gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"w9");
+     334             : #else
+     335             :       plumed_merror("file " + getPath() + ": trying to use a gz file without zlib being linked");
+     336             : #endif
+     337             :     }
+     338             :   }
+     339        3482 :   if(plumed) plumed->insertFile(*this);
+     340        3482 :   return *this;
+     341             : }
+     342             : 
+     343         134 : OFile& OFile::rewind() {
+     344             : // we use here "hard" rewind, which means close/reopen
+     345             : // the reason is that normal rewind does not work when in append mode
+     346             : // moreover, we can take a backup of the file
+     347         134 :   plumed_assert(fp);
+     348         134 :   clearFields();
+     349         134 :   if(gzfp) {
+     350             : #ifdef __PLUMED_HAS_ZLIB
+     351          15 :     gzclose((gzFile)gzfp);
+     352             : #endif
+     353         119 :   } else fclose(fp);
+     354             : 
+     355         134 :   if(!comm || comm->Get_rank()==0) {
+     356         103 :     std::string fname=this->path;
+     357         103 :     size_t found=fname.find_last_of("/\\");
+     358         103 :     std::string directory=fname.substr(0,found+1);
+     359         103 :     std::string file=fname.substr(found+1);
+     360         206 :     std::string backup=directory+backstring +".last."+file;
+     361         103 :     int check=rename(fname.c_str(),backup.c_str());
+     362         103 :     plumed_massert(check==0,"renaming "+fname+" into "+backup+" failed for reason: "+std::strerror(errno));
+     363             :   }
+     364             : 
+     365         134 :   if(comm) comm->Barrier();
+     366             : 
+     367         134 :   if(gzfp) {
+     368             : #ifdef __PLUMED_HAS_ZLIB
+     369          15 :     gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"w9");
+     370             : #endif
+     371         119 :   } else fp=std::fopen(const_cast<char*>(path.c_str()),"w");
+     372         134 :   return *this;
+     373             : }
+     374             : 
+     375        8436 : FileBase& OFile::flush() {
+     376        8436 :   if(heavyFlush) {
+     377        3901 :     if(gzfp) {
+     378             : #ifdef __PLUMED_HAS_ZLIB
+     379           9 :       gzclose(gzFile(gzfp));
+     380           9 :       gzfp=(void*)gzopen(const_cast<char*>(path.c_str()),"a");
+     381             : #endif
+     382             :     } else {
+     383        3892 :       fclose(fp);
+     384        3892 :       fp=std::fopen(const_cast<char*>(path.c_str()),"a");
+     385             :     }
+     386             :   } else {
+     387        4535 :     FileBase::flush();
+     388             :     // if(gzfp) gzflush(gzFile(gzfp),Z_FINISH);
+     389             :     // for some reason flushing with Z_FINISH has problems on linux
+     390             :     // I thus use this (incomplete) flush
+     391             : #ifdef __PLUMED_HAS_ZLIB
+     392        4535 :     if(gzfp) gzflush(gzFile(gzfp),Z_FULL_FLUSH);
+     393             : #endif
+     394             :   }
+     395        8436 :   return *this;
+     396             : }
+     397             : 
+     398        3518 : bool OFile::checkRestart()const {
+     399        3518 :   if(enforceRestart_) return true;
+     400        3517 :   else if(enforceBackup_) return false;
+     401        2373 :   else if(action) return action->getRestart();
+     402         218 :   else if(plumed) return plumed->getRestart();
+     403             :   else return false;
+     404             : }
+     405             : 
+     406           1 : OFile& OFile::enforceRestart() {
+     407           1 :   enforceRestart_=true;
+     408           1 :   enforceBackup_=false;
+     409           1 :   return *this;
+     410             : }
+     411             : 
+     412        1144 : OFile& OFile::enforceBackup() {
+     413        1144 :   enforceBackup_=true;
+     414        1144 :   enforceRestart_=false;
+     415        1144 :   return *this;
+     416             : }
+     417             : 
+     418             : 
+     419             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..559ab04c45 --- /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-06-10 08:19:14Functions: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
_ZN4PLMDlsINS_14ActionRegisterEEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIxEERNS_5OFileES2_RKT_1
_ZN4PLMDlsIA58_cEERNS_5OFileES3_RKT_2
_ZN4PLMDlsIA34_cEERNS_5OFileES3_RKT_3
_ZN4PLMDlsIA48_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
_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
_ZN4PLMDlsIA55_cEERNS_5OFileES3_RKT_30
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA9_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA25_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIA32_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA43_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA116_cEERNS_5OFileES3_RKT_38
_ZN4PLMDlsIA21_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIA49_cEERNS_5OFileES3_RKT_55
_ZN4PLMDlsIA31_cEERNS_5OFileES3_RKT_65
_ZN4PLMDlsIA23_cEERNS_5OFileES3_RKT_79
_ZN4PLMDlsIiEERNS_5OFileES2_RKT_87
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_105
_ZN4PLMDlsIA73_cEERNS_5OFileES3_RKT_113
_ZN4PLMDlsIA85_cEERNS_5OFileES3_RKT_114
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_117
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIA6_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_166
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_169
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_202
_ZN4PLMDlsIPKcEERNS_5OFileES4_RKT_220
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_437
_ZN4PLMDlsIcEERNS_5OFileES2_RKT_510
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_543
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_871
_ZN4PLMDlsIA74_cEERNS_5OFileES3_RKT_915
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_916
_ZN4PLMDlsIA10_cEERNS_5OFileES3_RKT_918
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_924
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_929
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_941
_ZN4PLMDlsINS_6lepton16ParsedExpressionEEERNS_5OFileES4_RKT_982
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1017
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1071
_ZN4PLMDlsIA51_cEERNS_5OFileES3_RKT_1092
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1137
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_1214
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1272
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_1333
_ZN4PLMDlsImEERNS_5OFileES2_RKT_1452
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_1566
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_1841
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2132
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_7145
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_7272
_ZN4PLMDlsIfEERNS_5OFileES2_RKT_45192
_ZN4PLMDlsIA4_cEERNS_5OFileES3_RKT_45204
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45216
_ZN4PLMDlsIlEERNS_5OFileES2_RKT_45553
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46257
_ZN4PLMDlsIA5_cEERNS_5OFileES3_RKT_46657
_ZN4PLMDlsIA8_cEERNS_5OFileES3_RKT_47384
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52400
_ZN4PLMDlsIdEERNS_5OFileES2_RKT_91744
_ZN4PLMDlsIPcEERNS_5OFileES3_RKT_100109
_ZN4PLMDlsIjEERNS_5OFileES2_RKT_129613
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_211749
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_213724
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/OFile.h.func.html b/coverage/tools/OFile.h.func.html new file mode 100644 index 0000000000..a55e4c337d --- /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-06-10 08:19:14Functions: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_918
_ZN4PLMDlsIA110_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA116_cEERNS_5OFileES3_RKT_38
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_871
_ZN4PLMDlsIA120_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA127_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA129_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1137
_ZN4PLMDlsIA134_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1071
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_1214
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52400
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_1566
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_105
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46257
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_1841
_ZN4PLMDlsIA21_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA23_cEERNS_5OFileES3_RKT_79
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1017
_ZN4PLMDlsIA25_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIA26_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_166
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_941
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_117
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_213724
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_169
_ZN4PLMDlsIA31_cEERNS_5OFileES3_RKT_65
_ZN4PLMDlsIA32_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_543
_ZN4PLMDlsIA34_cEERNS_5OFileES3_RKT_3
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45216
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_202
_ZN4PLMDlsIA37_cEERNS_5OFileES3_RKT_17
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_437
_ZN4PLMDlsIA39_cEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1272
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_1333
_ZN4PLMDlsIA42_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA43_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_929
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_7272
_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_30
_ZN4PLMDlsIA56_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA57_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA58_cEERNS_5OFileES3_RKT_2
_ZN4PLMDlsIA59_cEERNS_5OFileES3_RKT_10
_ZN4PLMDlsIA5_cEERNS_5OFileES3_RKT_46657
_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_915
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_7145
_ZN4PLMDlsIA77_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA78_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA79_cEERNS_5OFileES3_RKT_21
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2132
_ZN4PLMDlsIA81_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA82_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA85_cEERNS_5OFileES3_RKT_114
_ZN4PLMDlsIA88_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA8_cEERNS_5OFileES3_RKT_47384
_ZN4PLMDlsIA90_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA92_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA96_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA99_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA9_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIFRSt8ios_baseS2_EEERNS_5OFileES5_RKT_19
_ZN4PLMDlsINS_14ActionRegisterEEERNS_5OFileES3_RKT_1
_ZN4PLMDlsINS_6lepton16ParsedExpressionEEERNS_5OFileES4_RKT_982
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_916
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_924
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_211749
_ZN4PLMDlsIPKcEERNS_5OFileES4_RKT_220
_ZN4PLMDlsIPcEERNS_5OFileES3_RKT_100109
_ZN4PLMDlsISt13_SetprecisionEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIcEERNS_5OFileES2_RKT_510
_ZN4PLMDlsIdEERNS_5OFileES2_RKT_91744
_ZN4PLMDlsIfEERNS_5OFileES2_RKT_45192
_ZN4PLMDlsIiEERNS_5OFileES2_RKT_87
_ZN4PLMDlsIjEERNS_5OFileES2_RKT_129613
_ZN4PLMDlsIlEERNS_5OFileES2_RKT_45553
_ZN4PLMDlsImEERNS_5OFileES2_RKT_1452
_ZN4PLMDlsIxEERNS_5OFileES2_RKT_1
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/OFile.h.gcov.html b/coverage/tools/OFile.h.gcov.html new file mode 100644 index 0000000000..3d89fc3b0a --- /dev/null +++ b/coverage/tools/OFile.h.gcov.html @@ -0,0 +1,361 @@ + + + + + + + + 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-06-10 08:19:14Functions: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::unique_ptr<char[]> buffer_string;
+     158             : /// Internal buffer (generic use)
+     159             :   std::unique_ptr<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    64909204 :   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&,unsigned);
+     234             :   OFile& printField(const std::string&,long unsigned);
+     235             : /// Set the value of a string field
+     236             :   OFile& printField(const std::string&,const std::string&);
+     237             : ///
+     238             :   OFile& addConstantField(const std::string&);
+     239             : /// Used to setup printing of values
+     240             :   OFile& setupPrintValue( Value *val );
+     241             : /// Print a value
+     242             :   OFile& printField( Value* val, const double& v );
+     243             :   /** Close a line.
+     244             :   Typically used as
+     245             :   \verbatim
+     246             :     of.printField("a",a).printField("b",b).printField();
+     247             :   \endverbatim
+     248             :   */
+     249             :   OFile& printField();
+     250             :   /**
+     251             :   Resets the list of fields.
+     252             :   As it is only possible to add new constant fields (addConstantField()),
+     253             :   this method can be used to clean the field list.
+     254             :   */
+     255             :   OFile& clearFields();
+     256             : /// Formatted output with explicit format - a la printf
+     257             :   int printf(const char*fmt,...);
+     258             : /// Formatted output with << operator
+     259             :   template <class T>
+     260             :   friend OFile& operator<<(OFile&,const T &);
+     261             : /// Rewind a file
+     262             :   OFile&rewind();
+     263             : /// Flush a file
+     264             :   FileBase&flush() override;
+     265             : /// Enforce restart, also if the attached plumed object is not restarting.
+     266             : /// Useful for tests
+     267             :   OFile&enforceRestart();
+     268             : /// Enforce backup, even if the attached plumed object is restarting.
+     269             :   OFile&enforceBackup();
+     270             : };
+     271             : 
+     272             : /// Write using << syntax
+     273             : template <class T>
+     274     1161839 : OFile& operator<<(OFile&of,const T &t) {
+     275     1161839 :   of.oss<<t;
+     276     1161839 :   of.printf("%s",of.oss.str().c_str());
+     277     1161839 :   of.oss.str("");
+     278     1161839 :   return of;
+     279             : }
+     280             : 
+     281             : 
+     282             : }
+     283             : 
+     284             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..4760926968 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + 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:141782.4 %
Date:2024-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP13setNumThreadsEj0
_ZN4PLMD6OpenMP16getCachelineSizeEv88038
_ZN4PLMD6OpenMP13getNumThreadsEv1866045
_ZN4PLMDL13getOpenMPVarsEv1954083
_ZN4PLMD6OpenMP12getThreadNumEv6263516
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.func.html b/coverage/tools/OpenMP.cpp.func.html new file mode 100644 index 0000000000..86ac26237f --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + 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:141782.4 %
Date:2024-06-10 08:19:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP12getThreadNumEv6263516
_ZN4PLMD6OpenMP13getNumThreadsEv1866045
_ZN4PLMD6OpenMP13setNumThreadsEj0
_ZN4PLMD6OpenMP16getCachelineSizeEv88038
_ZN4PLMDL13getOpenMPVarsEv1954083
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.gcov.html b/coverage/tools/OpenMP.cpp.gcov.html new file mode 100644 index 0000000000..8f7e31e9d3 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.gcov.html @@ -0,0 +1,155 @@ + + + + + + + + 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:141782.4 %
Date:2024-06-10 08:19:14Functions: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             : 
+      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             : 
+      33             : struct OpenMPVars {
+      34             :   unsigned cacheline_size=512;
+      35             :   bool cache_set=false;
+      36             :   unsigned num_threads=1;
+      37             :   bool nt_env_set=false;
+      38             : };
+      39             : 
+      40     1954083 : static OpenMPVars & getOpenMPVars() {
+      41             :   static OpenMPVars vars;
+      42     1954083 :   return vars;
+      43             : }
+      44             : 
+      45           0 : void OpenMP::setNumThreads(const unsigned nt) {
+      46           0 :   getOpenMPVars().num_threads=nt;
+      47           0 : }
+      48             : 
+      49       88038 : unsigned OpenMP::getCachelineSize() {
+      50       88038 :   if(!getOpenMPVars().cache_set) {
+      51         786 :     if(std::getenv("PLUMED_CACHELINE_SIZE")) Tools::convert(std::getenv("PLUMED_CACHELINE_SIZE"),getOpenMPVars().cacheline_size);
+      52         786 :     getOpenMPVars().cache_set = true;
+      53             :   }
+      54       88038 :   return getOpenMPVars().cacheline_size;
+      55             : }
+      56             : 
+      57     1866045 : unsigned OpenMP::getNumThreads() {
+      58     1866045 :   if(!getOpenMPVars().nt_env_set) {
+      59         786 :     if(std::getenv("PLUMED_NUM_THREADS")) Tools::convert(std::getenv("PLUMED_NUM_THREADS"),getOpenMPVars().num_threads);
+      60         786 :     getOpenMPVars().nt_env_set = true;
+      61             :   }
+      62     1866045 :   return getOpenMPVars().num_threads;
+      63             : }
+      64             : 
+      65     6263516 : unsigned OpenMP::getThreadNum() {
+      66             : #if defined(_OPENMP)
+      67     6263516 :   return omp_get_thread_num();
+      68             : #else
+      69             :   return 0;
+      70             : #endif
+      71             : }
+      72             : 
+      73             : 
+      74             : 
+      75             : }
+      76             : 
+      77             : 
+      78             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ccc54db9d6 --- /dev/null +++ b/coverage/tools/OpenMP.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + 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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsIfEEjPKT_j0
_ZN4PLMD6OpenMP17getGoodNumThreadsINS_13VectorGenericILj3EEEEEjRKSt6vectorIT_SaIS5_EE450
_ZN4PLMD6OpenMP17getGoodNumThreadsINS_13VectorGenericILj3EEEEEjPKT_j43140
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j43984
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/OpenMP.h.func.html b/coverage/tools/OpenMP.h.func.html new file mode 100644 index 0000000000..7296ee3cbe --- /dev/null +++ b/coverage/tools/OpenMP.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + 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-06-10 08:19:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsINS_13VectorGenericILj3EEEEEjPKT_j43140
_ZN4PLMD6OpenMP17getGoodNumThreadsINS_13VectorGenericILj3EEEEEjRKSt6vectorIT_SaIS5_EE450
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j43984
_ZN4PLMD6OpenMP17getGoodNumThreadsIfEEjPKT_j0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/OpenMP.h.gcov.html b/coverage/tools/OpenMP.h.gcov.html new file mode 100644 index 0000000000..83df49f78c --- /dev/null +++ b/coverage/tools/OpenMP.h.gcov.html @@ -0,0 +1,155 @@ + + + + + + + + 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-06-10 08:19:14Functions: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             : #ifndef __PLUMED_tools_OpenMP_h
+      23             : #define __PLUMED_tools_OpenMP_h
+      24             : 
+      25             : #include <vector>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : class OpenMP {
+      30             : 
+      31             : public:
+      32             : 
+      33             : /// Set number of threads that can be used by openMP
+      34             :   static void setNumThreads(const unsigned nt);
+      35             : 
+      36             : /// Get number of threads that can be used by openMP
+      37             :   static unsigned getNumThreads();
+      38             : 
+      39             : /// Returns a unique thread identification number within the current team
+      40             :   static unsigned getThreadNum();
+      41             : 
+      42             : /// get cacheline size
+      43             :   static unsigned getCachelineSize();
+      44             : 
+      45             : /// Get a reasonable number of threads so as to access to an array of size s located at x
+      46             :   template<typename T>
+      47             :   static unsigned getGoodNumThreads(const T*x,unsigned s);
+      48             : 
+      49             : /// Get a reasonable number of threads so as to access to vector v;
+      50             :   template<typename T>
+      51             :   static unsigned getGoodNumThreads(const std::vector<T> & v);
+      52             : 
+      53             : };
+      54             : 
+      55             : template<typename T>
+      56       87124 : unsigned OpenMP::getGoodNumThreads(const T*x,unsigned n) {
+      57             :   unsigned long long p=(unsigned long long) x;
+      58             :   (void) p; // this is not to have warnings. notice that the pointer location is not used actually.
+      59             : // a factor two is necessary since there is no guarantee that x is aligned
+      60             : // to cache line boundary
+      61       87124 :   unsigned m=n*sizeof(T)/(2*getCachelineSize());
+      62       87124 :   unsigned numThreads=getNumThreads();
+      63       87124 :   if(m>=numThreads) m=numThreads;
+      64             :   else m=1;
+      65       87124 :   return m;
+      66             : }
+      67             : 
+      68             : 
+      69             : template<typename T>
+      70         450 : unsigned OpenMP::getGoodNumThreads(const std::vector<T> & v) {
+      71         450 :   if(v.size()==0) return 1;
+      72         438 :   else return getGoodNumThreads(&v[0],v.size());
+      73             : }
+      74             : 
+      75             : 
+      76             : }
+      77             : 
+      78             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..71b9dd53fc --- /dev/null +++ b/coverage/tools/PDB.cpp.func-sort-c.html @@ -0,0 +1,245 @@ + + + + + + + + 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:23929281.8 %
Date:2024-06-10 08:19:14Functions:354381.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE4
_ZNK4PLMD3PDB7hasFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD3PDB8getMtypeB5cxx11Ev10
_ZNK4PLMD3PDB9getBoxVecEv12
_ZNK4PLMD3PDB16getAtomBlockEndsEv14
_ZN4PLMD3PDB11addBlockEndERKj17
_ZN4PLMD3PDB14setAtomNumbersERKSt6vectorINS_10AtomNumberESaIS2_EE27
_ZN4PLMD3PDB16setArgumentNamesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE34
_ZNK4PLMD3PDB12getAtomRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberESA_RS6_158
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE231
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd299
_ZNK4PLMD3PDB21getNumberOfAtomBlocksEv468
_ZN4PLMD3PDB5printERKdPNS_14GenericMolInfoERNS_5OFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE497
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE854
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1339
_ZN4PLMD3PDB19readFromFilepointerEP8_IO_FILEbd2045
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2216
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj4638
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj5958
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11591
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj13260
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32150
_ZNK4PLMD3PDB12getOccupancyEv37820
_ZNK4PLMD3PDB7getBetaEv37820
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE46594
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE101936
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE166013
_ZN4PLMD3PDB16setAtomPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE493287
_ZNK4PLMD3PDB14getAtomNumbersEv721528
_ZN4PLMD3PDB16setArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKd1502798
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd1504260
_ZNK4PLMD3PDB16getArgumentNamesB5cxx11Ev2539432
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6770000
_ZNK4PLMD3PDB12getPositionsEv23533788
_ZNK4PLMD3PDB4sizeEv205300635
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/PDB.cpp.func.html b/coverage/tools/PDB.cpp.func.html new file mode 100644 index 0000000000..6c90f6ef91 --- /dev/null +++ b/coverage/tools/PDB.cpp.func.html @@ -0,0 +1,245 @@ + + + + + + + + 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:23929281.8 %
Date:2024-06-10 08:19:14Functions:354381.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_FILEbd2045
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd299
_ZN4PLMD3PDB5printERKdPNS_14GenericMolInfoERNS_5OFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE497
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1339
_ZN4PLMDlsERNS_3LogERKNS_3PDBE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj4638
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6770000
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE854
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE4
_ZNK4PLMD3PDB12checkForAtomERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB12getAtomRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberESA_RS6_158
_ZNK4PLMD3PDB12getOccupancyEv37820
_ZNK4PLMD3PDB12getPositionsEv23533788
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE231
_ZNK4PLMD3PDB14getAtomNumbersEv721528
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE101936
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj5958
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE46594
_ZNK4PLMD3PDB15checkForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getAtomsInChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11591
_ZNK4PLMD3PDB16getArgumentNamesB5cxx11Ev2539432
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd1504260
_ZNK4PLMD3PDB16getAtomBlockEndsEv14
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE166013
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE32150
_ZNK4PLMD3PDB21getNumberOfAtomBlocksEv468
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj13260
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2216
_ZNK4PLMD3PDB4sizeEv205300635
_ZNK4PLMD3PDB7getBetaEv37820
_ZNK4PLMD3PDB7hasFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD3PDB8getMtypeB5cxx11Ev10
_ZNK4PLMD3PDB9getBoxAngEv0
_ZNK4PLMD3PDB9getBoxAxsEv0
_ZNK4PLMD3PDB9getBoxVecEv12
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/PDB.cpp.gcov.html b/coverage/tools/PDB.cpp.gcov.html new file mode 100644 index 0000000000..282e701875 --- /dev/null +++ b/coverage/tools/PDB.cpp.gcov.html @@ -0,0 +1,698 @@ + + + + + + + + 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:23929281.8 %
Date:2024-06-10 08:19:14Functions:354381.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             : #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         468 : unsigned PDB::getNumberOfAtomBlocks()const {
+     189         468 :   return block_ends.size();
+     190             : }
+     191             : 
+     192          14 : const std::vector<unsigned> & PDB::getAtomBlockEnds()const {
+     193          14 :   return block_ends;
+     194             : }
+     195             : 
+     196    23533788 : const std::vector<Vector> & PDB::getPositions()const {
+     197    23533788 :   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       37820 : const std::vector<double> & PDB::getOccupancy()const {
+     206       37820 :   return occupancy;
+     207             : }
+     208             : 
+     209       37820 : const std::vector<double> & PDB::getBeta()const {
+     210       37820 :   return beta;
+     211             : }
+     212             : 
+     213        1339 : void PDB::addRemark( std::vector<std::string>& v1 ) {
+     214        1339 :   Tools::parse(v1,"TYPE",mtype);
+     215        1339 :   Tools::parseVector(v1,"ARG",argnames);
+     216        3759 :   for(unsigned i=0; i<v1.size(); ++i) {
+     217        2420 :     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         556 :       flags.push_back(v1[i]);
+     225             :     }
+     226             :   }
+     227        1339 : }
+     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      721528 : const std::vector<AtomNumber> & PDB::getAtomNumbers()const {
+     238      721528 :   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     6770000 : std::string PDB::getAtomName(AtomNumber a)const {
+     254             :   const auto p=number2index.find(a);
+     255     6770000 :   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     6770000 :   } else return atomsymb[p->second];
+     259             : }
+     260             : 
+     261      166013 : unsigned PDB::getResidueNumber(AtomNumber a)const {
+     262             :   const auto p=number2index.find(a);
+     263      166013 :   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      166013 :   } else return residue[p->second];
+     267             : }
+     268             : 
+     269      101936 : std::string PDB::getResidueName(AtomNumber a) const {
+     270             :   const auto p=number2index.find(a);
+     271      101936 :   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      101936 :   } else return residuenames[p->second];
+     275             : }
+     276             : 
+     277   205300635 : unsigned PDB::size()const {
+     278   205300635 :   return positions.size();
+     279             : }
+     280             : 
+     281        2045 : bool PDB::readFromFilepointer(FILE *fp,bool naturalUnits,double scale) {
+     282             :   //cerr<<file<<endl;
+     283             :   bool file_is_alive=false;
+     284        2045 :   if(naturalUnits) scale=1.0;
+     285             :   std::string line;
+     286             :   fpos_t pos; bool between_ters=true;
+     287      237748 :   while(Tools::getline(fp,line)) {
+     288             :     //cerr<<line<<"\n";
+     289      237543 :     fgetpos (fp,&pos);
+     290     1342583 :     while(line.length()<80) line.push_back(' ');
+     291      237543 :     std::string record=line.substr(0,6);
+     292      237543 :     std::string serial=line.substr(6,5);
+     293      237543 :     std::string atomname=line.substr(12,4);
+     294      237543 :     std::string residuename=line.substr(17,3);
+     295      237543 :     std::string chainID=line.substr(21,1);
+     296      237543 :     std::string resnum=line.substr(22,4);
+     297      237543 :     std::string x=line.substr(30,8);
+     298      237543 :     std::string y=line.substr(38,8);
+     299      237543 :     std::string z=line.substr(46,8);
+     300      237543 :     std::string occ=line.substr(54,6);
+     301      237543 :     std::string bet=line.substr(60,6);
+     302      237543 :     std::string BoxX=line.substr(6,9);
+     303      237543 :     std::string BoxY=line.substr(15,9);
+     304      237543 :     std::string BoxZ=line.substr(24,9);
+     305      237543 :     std::string BoxA=line.substr(33,7);
+     306      237543 :     std::string BoxB=line.substr(40,7);
+     307      237543 :     std::string BoxG=line.substr(47,7);
+     308      237543 :     Tools::trim(record);
+     309      237543 :     if(record=="TER") { between_ters=false; block_ends.push_back( positions.size() ); }
+     310      237543 :     if(record=="END") { file_is_alive=true;  break;}
+     311      235840 :     if(record=="ENDMDL") { file_is_alive=true;  break;}
+     312      235703 :     if(record=="REMARK") {
+     313        2678 :       std::vector<std::string> v1;  v1=Tools::getWords(line.substr(6));
+     314        1339 :       addRemark( v1 );
+     315        1339 :     }
+     316      235703 :     if(record=="CRYST1") {
+     317          69 :       Tools::convert(BoxX,BoxXYZ[0]);
+     318          69 :       Tools::convert(BoxY,BoxXYZ[1]);
+     319          69 :       Tools::convert(BoxZ,BoxXYZ[2]);
+     320          69 :       Tools::convert(BoxA,BoxABG[0]);
+     321          69 :       Tools::convert(BoxB,BoxABG[1]);
+     322          69 :       Tools::convert(BoxG,BoxABG[2]);
+     323          69 :       BoxXYZ*=scale;
+     324          69 :       double cosA=std::cos(BoxABG[0]*pi/180.);
+     325          69 :       double cosB=std::cos(BoxABG[1]*pi/180.);
+     326          69 :       double cosG=std::cos(BoxABG[2]*pi/180.);
+     327          69 :       double sinG=std::sin(BoxABG[2]*pi/180.);
+     328         276 :       for (unsigned i=0; i<3; i++) {Box[i][0]=0.; Box[i][1]=0.; Box[i][2]=0.;}
+     329          69 :       Box[0][0]=BoxXYZ[0];
+     330          69 :       Box[1][0]=BoxXYZ[1]*cosG;
+     331          69 :       Box[1][1]=BoxXYZ[1]*sinG;
+     332          69 :       Box[2][0]=BoxXYZ[2]*cosB;
+     333          69 :       Box[2][1]=(BoxXYZ[2]*BoxXYZ[1]*cosA-Box[2][0]*Box[1][0])/Box[1][1];
+     334          69 :       Box[2][2]=std::sqrt(BoxXYZ[2]*BoxXYZ[2]-Box[2][0]*Box[2][0]-Box[2][1]*Box[2][1]);
+     335             :     }
+     336      237742 :     if(record=="ATOM" || record=="HETATM") {
+     337             :       between_ters=true;
+     338             :       AtomNumber a;
+     339      233664 :       unsigned resno=0; // GB: when resnum string is not present, we set res number to zero
+     340             :       double o,b;
+     341      233664 :       Vector p;
+     342             :       {
+     343             :         int result;
+     344      233664 :         auto trimmed=serial;
+     345      233664 :         Tools::trim(trimmed);
+     346      233726 :         while(trimmed.length()<5) trimmed = std::string(" ") + trimmed;
+     347      233664 :         const char* errmsg = h36::hy36decode(5, trimmed.c_str(),trimmed.length(), &result);
+     348      233664 :         if(errmsg) {
+     349           0 :           std::string msg(errmsg);
+     350           0 :           plumed_merror(msg);
+     351             :         }
+     352      233664 :         a.setSerial(result);
+     353             :       }
+     354             : 
+     355             :       // allow skipping residue number
+     356             :       {
+     357      233664 :         auto trimmed=resnum;
+     358      233664 :         Tools::trim(trimmed);
+     359      233664 :         if(trimmed.length()>0) {
+     360             :           int result;
+     361      227024 :           while(trimmed.length()<4) trimmed = std::string(" ") + trimmed;
+     362      227024 :           const char* errmsg = h36::hy36decode(4, trimmed.c_str(),trimmed.length(), &result);
+     363      227024 :           if(errmsg) {
+     364           0 :             std::string msg(errmsg);
+     365           0 :             plumed_merror(msg);
+     366             :           }
+     367      227024 :           resno=result;
+     368             :         }
+     369             :       }
+     370             : 
+     371      233664 :       Tools::convert(occ,o);
+     372      233664 :       Tools::convert(bet,b);
+     373      233664 :       Tools::convert(x,p[0]);
+     374      233664 :       Tools::convert(y,p[1]);
+     375      233664 :       Tools::convert(z,p[2]);
+     376             :       // scale into nm
+     377      233664 :       p*=scale;
+     378      233664 :       numbers.push_back(a);
+     379      233664 :       number2index[a]=positions.size();
+     380      233664 :       std::size_t startpos=atomname.find_first_not_of(" \t");
+     381      233664 :       std::size_t endpos=atomname.find_last_not_of(" \t");
+     382      233664 :       atomsymb.push_back( atomname.substr(startpos, endpos-startpos+1) );
+     383      233664 :       residue.push_back(resno);
+     384      233664 :       chain.push_back(chainID);
+     385      233664 :       occupancy.push_back(o);
+     386      233664 :       beta.push_back(b);
+     387      233664 :       positions.push_back(p);
+     388      233664 :       residuenames.push_back(residuename);
+     389             :     }
+     390             :   }
+     391        2045 :   if( between_ters ) block_ends.push_back( positions.size() );
+     392        2045 :   return file_is_alive;
+     393             : }
+     394             : 
+     395         299 : bool PDB::read(const std::string&file,bool naturalUnits,double scale) {
+     396         299 :   FILE* fp=fopen(file.c_str(),"r");
+     397         299 :   if(!fp) return false;
+     398         297 :   readFromFilepointer(fp,naturalUnits,scale);
+     399         297 :   fclose(fp);
+     400         297 :   return true;
+     401             : }
+     402             : 
+     403         231 : void PDB::getChainNames( std::vector<std::string>& chains ) const {
+     404         231 :   chains.resize(0);
+     405         231 :   chains.push_back( chain[0] );
+     406      464610 :   for(unsigned i=1; i<size(); ++i) {
+     407      464379 :     if( chains[chains.size()-1]!=chain[i] ) chains.push_back( chain[i] );
+     408             :   }
+     409         231 : }
+     410             : 
+     411       11591 : void PDB::getResidueRange( const std::string& chainname, unsigned& res_start, unsigned& res_end, std::string& errmsg ) const {
+     412             :   bool inres=false, foundchain=false;
+     413    30269701 :   for(unsigned i=0; i<size(); ++i) {
+     414    30258110 :     if( chain[i]==chainname ) {
+     415    26604174 :       if(!inres) {
+     416       11591 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     417       11591 :         res_start=residue[i];
+     418             :       }
+     419             :       inres=true; foundchain=true;
+     420     3653936 :     } else if( inres && chain[i]!=chainname ) {
+     421             :       inres=false;
+     422       11090 :       res_end=residue[i-1];
+     423             :     }
+     424             :   }
+     425       11591 :   if(inres) res_end=residue[size()-1];
+     426       11591 : }
+     427             : 
+     428         158 : void PDB::getAtomRange( const std::string& chainname, AtomNumber& a_start, AtomNumber& a_end, std::string& errmsg ) const {
+     429             :   bool inres=false, foundchain=false;
+     430      432520 :   for(unsigned i=0; i<size(); ++i) {
+     431      432362 :     if( chain[i]==chainname ) {
+     432       89742 :       if(!inres) {
+     433         158 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     434         158 :         a_start=numbers[i];
+     435             :       }
+     436             :       inres=true; foundchain=true;
+     437      342620 :     } else if( inres && chain[i]!=chainname ) {
+     438             :       inres=false;
+     439          74 :       a_end=numbers[i-1];
+     440             :     }
+     441             :   }
+     442         158 :   if(inres) a_end=numbers[size()-1];
+     443         158 : }
+     444             : 
+     445        5958 : std::string PDB::getResidueName( const unsigned& resnum ) const {
+     446     7317600 :   for(unsigned i=0; i<size(); ++i) {
+     447     7317600 :     if( residue[i]==resnum ) return residuenames[i];
+     448             :   }
+     449           0 :   std::string num; Tools::convert( resnum, num );
+     450           0 :   plumed_merror("residue " + num + " not found" );
+     451             : }
+     452             : 
+     453       46594 : std::string PDB::getResidueName(const unsigned& resnum,const std::string& chainid ) const {
+     454    59112773 :   for(unsigned i=0; i<size(); ++i) {
+     455    59159547 :     if( residue[i]==resnum && ( chainid=="*" || chain[i]==chainid) ) return residuenames[i];
+     456             :   }
+     457           0 :   std::string num; Tools::convert( resnum, num );
+     458           0 :   plumed_merror("residue " + num + " not found in chain " + chainid );
+     459             : }
+     460             : 
+     461             : 
+     462       13260 : AtomNumber PDB::getNamedAtomFromResidue( const std::string& aname, const unsigned& resnum ) const {
+     463    16347180 :   for(unsigned i=0; i<size(); ++i) {
+     464    16347180 :     if( residue[i]==resnum && atomsymb[i]==aname ) return numbers[i];
+     465             :   }
+     466           0 :   std::string num; Tools::convert( resnum, num );
+     467           0 :   plumed_merror("residue " + num + " does not contain an atom named " + aname );
+     468             : }
+     469             : 
+     470        2216 : AtomNumber PDB::getNamedAtomFromResidueAndChain( const std::string& aname, const unsigned& resnum, const std::string& chainid ) const {
+     471     1070584 :   for(unsigned i=0; i<size(); ++i) {
+     472     1072800 :     if( residue[i]==resnum && atomsymb[i]==aname && ( chainid=="*" || chain[i]==chainid) ) return numbers[i];
+     473             :   }
+     474           0 :   std::string num; Tools::convert( resnum, num );
+     475           0 :   plumed_merror("residue " + num + " from chain " + chainid + " does not contain an atom named " + aname );
+     476             : }
+     477             : 
+     478       32150 : std::vector<AtomNumber> PDB::getAtomsInResidue(const unsigned& resnum,const std::string& chainid)const {
+     479             :   std::vector<AtomNumber> tmp;
+     480    84003186 :   for(unsigned i=0; i<size(); ++i) {
+     481    84456920 :     if( residue[i]==resnum && ( chainid=="*" || chain[i]==chainid) ) tmp.push_back(numbers[i]);
+     482             :   }
+     483       32150 :   if(tmp.size()==0) {
+     484           0 :     std::string num; Tools::convert( resnum, num );
+     485           0 :     plumed_merror("Cannot find residue " + num + " from chain " + chainid  );
+     486             :   }
+     487       32150 :   return tmp;
+     488             : }
+     489             : 
+     490           0 : std::vector<AtomNumber> PDB::getAtomsInChain(const std::string& chainid)const {
+     491             :   std::vector<AtomNumber> tmp;
+     492           0 :   for(unsigned i=0; i<size(); ++i) {
+     493           0 :     if( chainid=="*" || chain[i]==chainid ) tmp.push_back(numbers[i]);
+     494             :   }
+     495           0 :   if(tmp.size()==0) {
+     496           0 :     plumed_merror("Cannot find atoms from chain " + chainid  );
+     497             :   }
+     498           0 :   return tmp;
+     499             : }
+     500             : 
+     501        4638 : std::string PDB::getChainID(const unsigned& resnumber) const {
+     502     5689172 :   for(unsigned i=0; i<size(); ++i) {
+     503     5689172 :     if(resnumber==residue[i]) return chain[i];
+     504             :   }
+     505           0 :   plumed_merror("Not enough residues in pdb input file");
+     506             : }
+     507             : 
+     508           0 : std::string PDB::getChainID(AtomNumber a) const {
+     509             :   const auto p=number2index.find(a);
+     510           0 :   if(p==number2index.end()) {
+     511           0 :     std::string num; Tools::convert( a.serial(), num );
+     512           0 :     plumed_merror("Chain for atom " + num + " not found" );
+     513             :   }
+     514           0 :   return chain[p->second];
+     515             : }
+     516             : 
+     517           0 : bool PDB::checkForResidue( const std::string& name ) const {
+     518           0 :   for(unsigned i=0; i<size(); ++i) {
+     519           0 :     if( residuenames[i]==name ) return true;
+     520             :   }
+     521             :   return false;
+     522             : }
+     523             : 
+     524           0 : bool PDB::checkForAtom( const std::string& name ) const {
+     525           0 :   for(unsigned i=0; i<size(); ++i) {
+     526           0 :     if( atomsymb[i]==name ) return true;
+     527             :   }
+     528             :   return false;
+     529             : }
+     530             : 
+     531           4 : bool PDB::checkForAtom( AtomNumber a ) const {
+     532             :   const auto p=number2index.find(a);
+     533           4 :   return (p!=number2index.end());
+     534             : }
+     535             : 
+     536           0 : Log& operator<<(Log& ostr, const PDB&  pdb) {
+     537             :   char buffer[1000];
+     538           0 :   for(unsigned i=0; i<pdb.positions.size(); i++) {
+     539           0 :     std::sprintf(buffer,"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]);
+     540           0 :     ostr<<buffer;
+     541             :   }
+     542           0 :   return ostr;
+     543             : }
+     544             : 
+     545         854 : Vector PDB::getPosition(AtomNumber a)const {
+     546             :   const auto p=number2index.find(a);
+     547         854 :   if(p==number2index.end()) plumed_merror("atom not available");
+     548         854 :   else return positions[p->second];
+     549             : }
+     550             : 
+     551     2539432 : std::vector<std::string> PDB::getArgumentNames()const {
+     552     2539432 :   return argnames;
+     553             : }
+     554             : 
+     555          10 : std::string PDB::getMtype() const {
+     556          10 :   return mtype;
+     557             : }
+     558             : 
+     559         497 : void PDB::print( const double& lunits, GenericMolInfo* mymoldat, OFile& ofile, const std::string& fmt ) {
+     560         497 :   if( argnames.size()>0 ) {
+     561         476 :     ofile.printf("REMARK ARG=%s", argnames[0].c_str() );
+     562        1744 :     for(unsigned i=1; i<argnames.size(); ++i) ofile.printf(",%s",argnames[i].c_str() );
+     563         476 :     ofile.printf("\n"); ofile.printf("REMARK ");
+     564             :   }
+     565             :   std::string descr2;
+     566         497 :   if(fmt.find("-")!=std::string::npos) {
+     567           0 :     descr2="%s=" + fmt + " ";
+     568             :   } else {
+     569             :     // This ensures numbers are left justified (i.e. next to the equals sign
+     570         497 :     std::size_t psign=fmt.find("%");
+     571         497 :     plumed_assert( psign!=std::string::npos );
+     572         994 :     descr2="%s=%-" + fmt.substr(psign+1) + " ";
+     573             :   }
+     574        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 );
+     575         497 :   if( argnames.size()>0 ) ofile.printf("\n");
+     576         497 :   if( !mymoldat ) {
+     577        2263 :     for(unsigned i=0; i<positions.size(); ++i) {
+     578             :       std::array<char,6> at;
+     579             :       {
+     580        1769 :         const char* msg = h36::hy36encode(5,numbers[i].serial(),&at[0]);
+     581        1769 :         plumed_assert(msg==nullptr) << msg;
+     582        1769 :         at[5]=0;
+     583             :       }
+     584             :       std::array<char,5> res;
+     585             :       {
+     586        1769 :         const char* msg = h36::hy36encode(4,i,&res[0]);
+     587        1769 :         plumed_assert(msg==nullptr) << msg;
+     588        1769 :         res[4]=0;
+     589             :       }
+     590        1769 :       ofile.printf("ATOM  %s  X   RES  %s    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     591             :                    &at[0], &res[0],
+     592        1769 :                    lunits*positions[i][0], lunits*positions[i][1], lunits*positions[i][2],
+     593             :                    occupancy[i], beta[i] );
+     594             :     }
+     595             :   } else {
+     596          69 :     for(unsigned i=0; i<positions.size(); ++i) {
+     597             :       std::array<char,6> at;
+     598             :       {
+     599          66 :         const char* msg = h36::hy36encode(5,numbers[i].serial(),&at[0]);
+     600          66 :         plumed_assert(msg==nullptr) << msg;
+     601          66 :         at[5]=0;
+     602             :       }
+     603             :       std::array<char,5> res;
+     604             :       {
+     605          66 :         const char* msg = h36::hy36encode(4,mymoldat->getResidueNumber(numbers[i]),&res[0]);
+     606          66 :         plumed_assert(msg==nullptr) << msg;
+     607          66 :         res[4]=0;
+     608             :       }
+     609          66 :       ofile.printf("ATOM  %s %-4s %3s  %s    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     610         132 :                    &at[0], mymoldat->getAtomName(numbers[i]).c_str(),
+     611          66 :                    mymoldat->getResidueName(numbers[i]).c_str(), &res[0],
+     612          66 :                    lunits*positions[i][0], lunits*positions[i][1], lunits*positions[i][2],
+     613             :                    occupancy[i], beta[i] );
+     614             :     }
+     615             :   }
+     616         497 :   ofile.printf("END\n");
+     617         497 : }
+     618             : 
+     619             : 
+     620             : }
+     621             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e43474c011 --- /dev/null +++ b/coverage/tools/Pbc.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + 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:10210795.3 %
Date:2024-06-10 08:19:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3Pbc8distanceEbRKNS_13VectorGenericILj3EEES4_0
_ZNK4PLMD3Pbc13isOrthorombicEv440
_ZNK4PLMD3Pbc9getInvBoxEv2173
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_St6vectorINS_13VectorGenericILj3EEESaIS3_EE12552
_ZNK4PLMD3Pbc6getBoxEv34215
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE63109
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj220567
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE223368
_ZN4PLMD3PbcC2Ev421473
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE919918
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi206799275
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Pbc.cpp.func.html b/coverage/tools/Pbc.cpp.func.html new file mode 100644 index 0000000000..1d178cdbe8 --- /dev/null +++ b/coverage/tools/Pbc.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + 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:10210795.3 %
Date:2024-06-10 08:19:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE63109
_ZN4PLMD3PbcC2Ev421473
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_St6vectorINS_13VectorGenericILj3EEESaIS3_EE12552
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE919918
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE223368
_ZNK4PLMD3Pbc13isOrthorombicEv440
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj220567
_ZNK4PLMD3Pbc6getBoxEv34215
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi206799275
_ZNK4PLMD3Pbc8distanceEbRKNS_13VectorGenericILj3EEES4_0
_ZNK4PLMD3Pbc9getInvBoxEv2173
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Pbc.cpp.gcov.html b/coverage/tools/Pbc.cpp.gcov.html new file mode 100644 index 0000000000..0f2c9d7a3f --- /dev/null +++ b/coverage/tools/Pbc.cpp.gcov.html @@ -0,0 +1,324 @@ + + + + + + + + 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:10210795.3 %
Date:2024-06-10 08:19:14Functions:111291.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 "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      421473 : Pbc::Pbc():
+      33     6322095 :   type(unset)
+      34             : {
+      35      421473 :   box.zero();
+      36      421473 :   invBox.zero();
+      37      421473 : }
+      38             : 
+      39       12552 : void Pbc::buildShifts(std::vector<Vector> shifts[2][2][2])const {
+      40             :   const double small=1e-28;
+      41             : 
+      42             : // clear all shifts
+      43      188280 :   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      502080 :   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      338904 :         int ishift[3]= {l,m,n};
+      51      338904 :         Vector dshift(l,m,n);
+      52             : 
+      53             : // count how many components are != 0
+      54             :         unsigned count=0;
+      55     1355616 :         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      413636 :         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      225936 :         Vector cosdir=matmul(reduced,transpose(reduced),dshift);
+      66      225936 :         double dp=dotProduct(dshift,cosdir);
+      67      225936 :         double ref=modulo2(dshift)*modulo2(cosdir);
+      68      225936 :         if(std::fabs(ref-dp*dp)<small) continue;
+      69             : 
+      70             : // here we start pruning depending on the sign of the scaled coordinate
+      71     2268060 :         for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) {
+      72             : 
+      73     1209632 :               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     4838528 :               for(int s=0; s<3; s++) if(ishift[s]*block[s]>0) skip=true;
+      78     1371470 :               if(skip) continue;
+      79             :               skip=true;
+      80     1644880 :               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     1233660 :                 if(((1-ishift[s]*ishift[s])*block[s])*cosdir[s]<-small) skip=false;
+      84             :               }
+      85      411220 :               if(skip)continue;
+      86             : 
+      87             : // if we arrive to this point, shift is eligible and is added to the list
+      88      498764 :               shifts[i][j][k].push_back(matmul(transpose(reduced),dshift));
+      89             :             }
+      90             :       }
+      91       12552 : }
+      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       63109 : void Pbc::setBox(const Tensor&b) {
+     116       63109 :   box=b;
+     117             : // detect type:
+     118             :   const double epsilon=1e-28;
+     119             : 
+     120       63109 :   type=unset;
+     121       63109 :   double det=box.determinant();
+     122       63109 :   if(det*det<epsilon) return;
+     123             : 
+     124             :   bool cxy=false;
+     125             :   bool cxz=false;
+     126             :   bool cyz=false;
+     127       57024 :   if(box(0,1)*box(0,1)<epsilon && box(1,0)*box(1,0)<epsilon) cxy=true;
+     128       57024 :   if(box(0,2)*box(0,2)<epsilon && box(2,0)*box(2,0)<epsilon) cxz=true;
+     129       57024 :   if(box(1,2)*box(1,2)<epsilon && box(2,1)*box(2,1)<epsilon) cyz=true;
+     130             : 
+     131       57024 :   invBox=box.inverse();
+     132             : 
+     133       57024 :   if(cxy && cxz && cyz) type=orthorombic;
+     134       12552 :   else type=generic;
+     135             : 
+     136       57024 :   if(type==orthorombic) {
+     137       44472 :     reduced=box;
+     138       44472 :     invReduced=inverse(reduced);
+     139      177888 :     for(unsigned i=0; i<3; i++) {
+     140      133416 :       diag[i]=box[i][i];
+     141      133416 :       hdiag[i]=0.5*box[i][i];
+     142      133416 :       mdiag[i]=-0.5*box[i][i];
+     143             :     }
+     144             :   } else {
+     145       12552 :     reduced=box;
+     146       12552 :     LatticeReduction::reduce(reduced);
+     147       12552 :     invReduced=inverse(reduced);
+     148       12552 :     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      220567 : void Pbc::apply(std::vector<Vector>& dlist, unsigned max_index) const {
+     159      220567 :   if (max_index==0) max_index=dlist.size();
+     160      220567 :   if(type==unset) {
+     161             :     // do nothing
+     162      214143 :   } else if(type==orthorombic) {
+     163             : #ifdef __PLUMED_PBC_WHILE
+     164             :     for(unsigned k=0; k<max_index; ++k) {
+     165             :       while(dlist[k][0]>hdiag[0])   dlist[k][0]-=diag[0];
+     166             :       while(dlist[k][0]<=mdiag[0])  dlist[k][0]+=diag[0];
+     167             :       while(dlist[k][1]>hdiag[1])   dlist[k][1]-=diag[1];
+     168             :       while(dlist[k][1]<=mdiag[1])  dlist[k][1]+=diag[1];
+     169             :       while(dlist[k][2]>hdiag[2])   dlist[k][2]-=diag[2];
+     170             :       while(dlist[k][2]<=mdiag[2])  dlist[k][2]+=diag[2];
+     171             :     }
+     172             : #else
+     173  1603494693 :     for(unsigned k=0; k<max_index; ++k) for(int i=0; i<3; i++) dlist[k][i]=Tools::pbc(dlist[k][i]*invBox(i,i))*box(i,i);
+     174             : #endif
+     175        1810 :   } else if(type==generic) {
+     176       67768 :     for(unsigned k=0; k<max_index; ++k) dlist[k]=distance(Vector(0.0,0.0,0.0),dlist[k]);
+     177           0 :   } else plumed_merror("unknown pbc type");
+     178      220567 : }
+     179             : 
+     180   206799275 : Vector Pbc::distance(const Vector&v1,const Vector&v2,int*nshifts)const {
+     181   206799275 :   Vector d=delta(v1,v2);
+     182   206799275 :   if(type==unset) {
+     183             :     // do nothing
+     184   182935082 :   } else if(type==orthorombic) {
+     185             : #ifdef __PLUMED_PBC_WHILE
+     186             :     for(unsigned i=0; i<3; i++) {
+     187             :       while(d[i]>hdiag[i]) d[i]-=diag[i];
+     188             :       while(d[i]<=mdiag[i]) d[i]+=diag[i];
+     189             :     }
+     190             : #else
+     191   538436180 :     for(int i=0; i<3; i++) d[i]=Tools::pbc(d[i]*invBox(i,i))*box(i,i);
+     192             : #endif
+     193    48326037 :   } else if(type==generic) {
+     194    48326037 :     Vector s=matmul(d,invReduced);
+     195             : // check if images have to be computed:
+     196             : //    if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)){
+     197             : // NOTICE: the check in the previous line, albeit correct, is breaking many regtest
+     198             : //         since it does not apply Tools::pbc in many cases. Moreover, it does not
+     199             : //         introduce a significant gain. I thus leave it out for the moment.
+     200             :     if(true) {
+     201             : // bring to -0.5,+0.5 region in scaled coordinates:
+     202   193304148 :       for(int i=0; i<3; i++) s[i]=Tools::pbc(s[i]);
+     203    48326037 :       d=matmul(s,reduced);
+     204             : // check if shifts have to be attempted:
+     205    48326037 :       if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)) {
+     206             : // list of shifts is specific for that "octant" (depends on signs of s[i]):
+     207    78765012 :         const std::vector<Vector> & myshifts(shifts[(s[0]>0?1:0)][(s[1]>0?1:0)][(s[2]>0?1:0)]);
+     208    39867229 :         Vector best(d);
+     209    39867229 :         double lbest(modulo2(best));
+     210             : // loop over possible shifts:
+     211    39867229 :         if(nshifts) *nshifts+=myshifts.size();
+     212   179420109 :         for(unsigned i=0; i<myshifts.size(); i++) {
+     213   139552880 :           Vector trial=d+myshifts[i];
+     214   139552880 :           double ltrial=modulo2(trial);
+     215   139552880 :           if(ltrial<lbest) {
+     216             :             lbest=ltrial;
+     217     3759325 :             best=trial;
+     218             :           }
+     219             :         }
+     220    39867229 :         d=best;
+     221             :       }
+     222             :     }
+     223           0 :   } else plumed_merror("unknown pbc type");
+     224   206799275 :   return d;
+     225             : }
+     226             : 
+     227      919918 : Vector Pbc::realToScaled(const Vector&d)const {
+     228      919918 :   return matmul(invBox.transpose(),d);
+     229             : }
+     230             : 
+     231      223368 : Vector Pbc::scaledToReal(const Vector&d)const {
+     232      223368 :   return matmul(box.transpose(),d);
+     233             : }
+     234             : 
+     235         440 : bool Pbc::isOrthorombic()const {
+     236         440 :   return type==orthorombic;
+     237             : }
+     238             : 
+     239       34215 : const Tensor& Pbc::getBox()const {
+     240       34215 :   return box;
+     241             : }
+     242             : 
+     243        2173 : const Tensor& Pbc::getInvBox()const {
+     244        2173 :   return invBox;
+     245             : }
+     246             : 
+     247             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..5009cc18f5 --- /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:22100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Pbc.h.func.html b/coverage/tools/Pbc.h.func.html new file mode 100644 index 0000000000..225ae6400a --- /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:22100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Pbc.h.gcov.html b/coverage/tools/Pbc.h.gcov.html new file mode 100644 index 0000000000..fa031d3afa --- /dev/null +++ b/coverage/tools/Pbc.h.gcov.html @@ -0,0 +1,189 @@ + + + + + + + + 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:22100.0 %
Date:2024-06-10 08:19:14Functions: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 <vector>
+      28             : #include <cstddef>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : /*
+      33             : Tool to deal with periodic boundary conditions.
+      34             : 
+      35             : This class is useful to apply periodic boundary conditions on interatomic
+      36             : distances. It stores privately information about reduced lattice vectors
+      37             : */
+      38             : class Pbc {
+      39             : /// Type of box
+      40             :   enum {unset,orthorombic,generic} type;
+      41             : /// Box
+      42             :   Tensor box;
+      43             : /// Inverse box
+      44             :   Tensor invBox;
+      45             : /// Reduced box.
+      46             : /// This is a set of lattice vectors generating the same lattice
+      47             : /// but "minimally skewed". Useful to optimize image search.
+      48             :   Tensor reduced;
+      49             : /// Inverse of the reduced box
+      50             :   Tensor invReduced;
+      51             : /// List of shifts that should be attempted.
+      52             : /// Depending on the sign of the scaled coordinates representing
+      53             : /// a distance vector, a different set of shifts must be tried.
+      54             :   std::vector<Vector> shifts[2][2][2];
+      55             : /// Alternative representation for orthorombic cells.
+      56             : /// Not really used, but could be used to optimize search in
+      57             : /// orthorombic cells.
+      58             :   Vector diag,hdiag,mdiag;
+      59             : /// Build list of shifts.
+      60             : /// This is expensive, and must be called only when box is
+      61             : /// reset. It allows building a minimal set of shifts
+      62             : /// depending on the sign of the scaled coordinates representing
+      63             : /// a distance vector.
+      64             :   void buildShifts(std::vector<Vector> shifts[2][2][2])const;
+      65             : public:
+      66             : /// Constructor
+      67             :   Pbc();
+      68             : /// Compute modulo of (v2-v1), using or not pbc depending on bool pbc.
+      69             :   double distance( const bool pbc, const Vector& v1, const Vector& v2 ) const;
+      70             : /// Computes v2-v1, using minimal image convention
+      71             :   Vector distance(const Vector& v1,const Vector& v2)const;
+      72             : /// version of distance which also returns the number
+      73             : /// of attempted shifts
+      74             :   Vector distance(const Vector&,const Vector&,int*nshifts)const;
+      75             : /// Apply PBC to a set of positions or distance vectors
+      76             :   void apply(std::vector<Vector>&dlist, unsigned max_index=0) const;
+      77             : /// Set the lattice vectors.
+      78             : /// b[i][j] is the j-th component of the i-th vector
+      79             :   void setBox(const Tensor&b);
+      80             : /// Returns the box
+      81             :   const Tensor& getBox()const;
+      82             : /// Returns the inverse matrix of box.
+      83             : /// Thus: pbc.getInvBox() == inverse(pbc.getBox()).
+      84             :   const Tensor& getInvBox()const;
+      85             : /// Transform a vector in real space to a vector in scaled coordinates.
+      86             : /// Thus:pbc.realToScaled(v) == matmul(transpose(inverse(pbc.getBox(),v)));
+      87             :   Vector realToScaled(const Vector&)const;
+      88             : /// Transform a vector in scaled coordinates to a vector in real space.
+      89             : /// Thus:pbc.scaledToRead(v) == matmul(transpose(pbc.getBox()),v);
+      90             :   Vector scaledToReal(const Vector&)const;
+      91             : /// Returns true if the box vectors are orthogonal
+      92             :   bool isOrthorombic()const;
+      93             : /// Full search (for testing).
+      94             : /// Perform a full search on vector
+      95             :   void fullSearch(Vector&)const;
+      96             : /// Returns true if box is set and non zero
+      97             :   bool isSet()const;
+      98             : };
+      99             : 
+     100             : inline
+     101             : Vector Pbc::distance(const Vector& v1,const Vector& v2)const {
+     102   199961555 :   return distance(v1,v2,NULL);
+     103             : }
+     104             : 
+     105             : inline
+     106             : bool Pbc::isSet()const {
+     107       14248 :   return type!=unset;
+     108             : }
+     109             : 
+     110             : }
+     111             : 
+     112             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..6d1fea4775 --- /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:174141.5 %
Date:2024-06-10 08:19:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12PlumedHandleC2EOS0_0
_ZN4PLMD12PlumedHandleD0Ev0
_ZN4PLMD12PlumedHandleaSEOS0_0
_ZN4PLMD12PlumedHandle6dlopenEPKc1
_ZN4PLMD12PlumedHandleC2EPKc1
_ZN4PLMD12PlumedHandleC2Ev11
_ZN4PLMD12PlumedHandleD2Ev12
_ZN4PLMD12PlumedHandle3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1476
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.func.html b/coverage/tools/PlumedHandle.cpp.func.html new file mode 100644 index 0000000000..5b103f7387 --- /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:174141.5 %
Date:2024-06-10 08:19:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12PlumedHandle3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1476
_ZN4PLMD12PlumedHandle6dlopenEPKc1
_ZN4PLMD12PlumedHandleC2EOS0_0
_ZN4PLMD12PlumedHandleC2EPKc1
_ZN4PLMD12PlumedHandleC2Ev11
_ZN4PLMD12PlumedHandleD0Ev0
_ZN4PLMD12PlumedHandleD2Ev12
_ZN4PLMD12PlumedHandleaSEOS0_0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.gcov.html b/coverage/tools/PlumedHandle.cpp.gcov.html new file mode 100644 index 0000000000..bd2647b611 --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + + 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:174141.5 %
Date:2024-06-10 08:19:14Functions: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             : #include "../wrapper/Plumed.h"
+      39             : 
+      40             : namespace PLMD
+      41             : {
+      42             : 
+      43             : 
+      44          11 : PlumedHandle::PlumedHandle():
+      45          11 :   local(Tools::make_unique<PlumedMain>())
+      46             : {
+      47          11 : }
+      48             : 
+      49           1 : PlumedHandle::PlumedHandle(const char* kernel)
+      50             : #ifdef __PLUMED_HAS_DLOPEN
+      51             :   :
+      52           1 :   loaded(plumed_c2v(plumed_create_dlopen(kernel)))
+      53             : {
+      54             :   if(!plumed_valid(plumed_v2c(loaded))) {
+      55             :     // this is necessary to make sure loaded is properly destroyed
+      56           0 :     plumed_finalize(plumed_v2c(loaded));
+      57           0 :     plumed_error() << "You are trying to dynamically load a kernel, but the path " << kernel <<" could not be opened";
+      58             :   }
+      59           1 : }
+      60             : #else
+      61             : {
+      62             :   plumed_error() << "You are trying to dynamically load a kernel, but PLUMED was compiled without dlopen";
+      63             : }
+      64             : #endif
+      65             : 
+      66          12 : PlumedHandle::~PlumedHandle() {
+      67          12 :   if(loaded) plumed_finalize(plumed_v2c(loaded));
+      68          12 : }
+      69             : 
+      70           1 : PlumedHandle PlumedHandle::dlopen(const char* path) {
+      71           1 :   return PlumedHandle(path);
+      72             : }
+      73             : 
+      74        1476 : void PlumedHandle::cmd(const std::string & key,const TypesafePtr & ptr) {
+      75        1476 :   if(local) {
+      76        2508 :     local->cmd(key.c_str(),ptr);
+      77         222 :   } else if(loaded) {
+      78             :     plumed_safeptr safe;
+      79             :     safe.ptr=ptr.getRaw();
+      80             :     safe.nelem=ptr.getNelem();
+      81             :     safe.shape=const_cast<std::size_t*>(ptr.getShape());
+      82             :     safe.flags=ptr.getFlags();
+      83             :     safe.opt=nullptr;
+      84             :     // try/catch needed to remap exceptions in anonymous namespace to standard plumed exceptions
+      85             :     // this is necessary otherwise a user would not be able to catch them
+      86             :     try {
+      87         222 :       Plumed(loaded).cmd(key.c_str(),safe);
+      88           0 :     } catch(PLMD::Plumed::ExceptionError& e) {
+      89           0 :       throw ExceptionError(e.what());
+      90           0 :     } catch(PLMD::Plumed::ExceptionDebug& e) {
+      91           0 :       throw ExceptionDebug(e.what());
+      92           0 :     } catch(PLMD::Plumed::ExceptionTypeError& e) {
+      93           0 :       throw ExceptionError(e.what());
+      94           0 :     } catch(PLMD::Plumed::LeptonException& e) {
+      95           0 :       throw lepton::Exception(e.what());
+      96           0 :     } catch(PLMD::Plumed::Exception& e) {
+      97           0 :       throw Exception(e.what());
+      98           0 :     }
+      99           0 :   } else plumed_error() << "should never arrive here (either one or the other should work)";
+     100        1476 : }
+     101             : 
+     102           0 : PlumedHandle::PlumedHandle(PlumedHandle && other) noexcept:
+     103             :   local(std::move(other.local)),
+     104           0 :   loaded(other.loaded)
+     105             : {
+     106           0 :   other.loaded=nullptr;
+     107           0 : }
+     108             : 
+     109           0 : PlumedHandle & PlumedHandle::operator=(PlumedHandle && other) noexcept {
+     110           0 :   if(this!=&other) {
+     111           0 :     if(loaded) plumed_finalize(plumed_v2c(loaded));
+     112             :     local=std::move(other.local);
+     113           0 :     loaded=other.loaded;
+     114           0 :     other.loaded=nullptr;
+     115             :   }
+     116           0 :   return *this;
+     117             : }
+     118             : 
+     119             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..6ab525767d --- /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-06-10 08:19:14Functions: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_b160
_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
_ZN4PLMD4RMSDC2Ev46803
_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.15
+
+ + + diff --git a/coverage/tools/RMSD.cpp.func.html b/coverage/tools/RMSD.cpp.func.html new file mode 100644 index 0000000000..62c85ca17a --- /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-06-10 08:19:14Functions: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
_ZN4PLMD4RMSDC2Ev46803
_ZNK4PLMD12RMSDCoreData17getDRotationDRr01Ev1092
_ZNK4PLMD4RMSD15simpleAlignmentERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_RS9_SC_b160
_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.15
+
+ + + diff --git a/coverage/tools/RMSD.cpp.gcov.html b/coverage/tools/RMSD.cpp.gcov.html new file mode 100644 index 0000000000..3015104482 --- /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-06-10 08:19:14Functions: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       46803 : 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         160 : 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         160 :   unsigned n=reference.size();
+     389             : 
+     390         160 :   Vector apositions;
+     391         160 :   Vector areference;
+     392         160 :   Vector dpositions;
+     393         160 :   Vector dreference;
+     394             : 
+     395        2509 :   for(unsigned i=0; i<n; i++) {
+     396        2349 :     double aw=align[i];
+     397        2349 :     double dw=displace[i];
+     398        2349 :     apositions+=positions[i]*aw;
+     399        2349 :     areference+=reference[i]*aw;
+     400        2349 :     dpositions+=positions[i]*dw;
+     401        2349 :     dreference+=reference[i]*dw;
+     402             :   }
+     403             : 
+     404         160 :   Vector shift=((apositions-areference)-(dpositions-dreference));
+     405        2509 :   for(unsigned i=0; i<n; i++) {
+     406        2349 :     displacement[i]=(positions[i]-apositions)-(reference[i]-areference);
+     407        2349 :     dist+=displace[i]*displacement[i].modulo2();
+     408        2349 :     derivatives[i]=2*(displace[i]*displacement[i]+align[i]*shift);
+     409             :   }
+     410             : 
+     411         160 :   if(!squared) {
+     412             :     // sqrt
+     413         106 :     dist=std::sqrt(dist);
+     414             :     ///// sqrt on derivatives
+     415        2149 :     for(unsigned i=0; i<n; i++) {derivatives[i]*=(0.5/dist);}
+     416             :   }
+     417         160 :   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.15
+
+ + + 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 0000000000..91e76fdf55 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/RMSD.h.func.html b/coverage/tools/RMSD.h.func.html new file mode 100644 index 0000000000..1c16a922b6 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/RMSD.h.gcov.html b/coverage/tools/RMSD.h.gcov.html new file mode 100644 index 0000000000..d36bec3e35 --- /dev/null +++ b/coverage/tools/RMSD.h.gcov.html @@ -0,0 +1,451 @@ + + + + + + + + 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-06-10 08:19:14Functions: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           0 :   void setPositionsCenter(Vector v) {plumed_massert(!cpositions_is_calculated,"You are setting the center two times!"); cpositions=v; cpositions_is_calculated=true;};
+     325       52152 :   void setReferenceCenter(Vector v) {plumed_massert(!creference_is_calculated,"You are setting the center two times!"); creference=v; creference_is_calculated=true;};
+     326             :   // the center is already removed
+     327       52152 :   void setPositionsCenterIsRemoved(bool t) {cpositions_is_removed=t;};
+     328       52152 :   void setReferenceCenterIsRemoved(bool t) {creference_is_removed=t;};
+     329             :   bool getPositionsCenterIsRemoved() {return cpositions_is_removed;};
+     330             :   bool getReferenceCenterIsRemoved() {return creference_is_removed;};
+     331             :   //  does the core calc : first thing to call after the constructor:
+     332             :   // only_rotation=true does not retrieve the derivatives, just retrieve the optimal rotation (the same calc cannot be exploit further)
+     333             :   void doCoreCalc(bool safe,bool alEqDis, bool only_rotation=false);
+     334             :   // do calculation with close structure data structures
+     335             :   void doCoreCalcWithCloseStructure(bool safe,bool alEqDis, const Tensor & rotationPosClose, const Tensor & rotationRefClose, std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01);
+     336             :   // retrieve the distance if required after doCoreCalc
+     337             :   double getDistance(bool squared);
+     338             :   // retrieve the derivative of the distance respect to the position
+     339             :   std::vector<Vector> getDDistanceDPositions();
+     340             :   // retrieve the derivative of the distance respect to the reference
+     341             :   std::vector<Vector> getDDistanceDReference();
+     342             :   // specific version for SOMA calculation (i.e. does not need derivative respect to rotation matrix)
+     343             :   std::vector<Vector> getDDistanceDReferenceSOMA();
+     344             :   // get aligned reference onto position
+     345             :   std::vector<Vector> getAlignedReferenceToPositions();
+     346             :   // get aligned position onto reference
+     347             :   std::vector<Vector> getAlignedPositionsToReference();
+     348             :   // get centered positions
+     349             :   std::vector<Vector> getCenteredPositions();
+     350             :   // get centered reference
+     351             :   std::vector<Vector> getCenteredReference();
+     352             :   // get center of positions
+     353             :   Vector getPositionsCenter();
+     354             :   // get center of reference
+     355             :   Vector getReferenceCenter();
+     356             :   // get rotation matrix (reference ->positions)
+     357             :   Tensor getRotationMatrixReferenceToPositions();
+     358             :   // get rotation matrix (positions -> reference)
+     359             :   Tensor getRotationMatrixPositionsToReference();
+     360             :   // get the derivative of the rotation matrix respect to positions
+     361             :   // note that the this transformation overlap the  reference onto position
+     362             :   // if inverseTransform=true then aligns the positions onto reference
+     363             :   Matrix<std::vector<Vector> > getDRotationDPositions( bool inverseTransform=false );
+     364             :   // get the derivative of the rotation matrix respect to reference
+     365             :   // note that the this transformation overlap the  reference onto position
+     366             :   // if inverseTransform=true then aligns the positions onto reference
+     367             :   Matrix<std::vector<Vector> >  getDRotationDReference(bool inverseTransform=false );
+     368             :   const std::array<std::array<Tensor,3>,3> & getDRotationDRr01() const;
+     369             : };
+     370             : 
+     371             : }
+     372             : 
+     373             : #endif
+     374             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..121995d3b2 --- /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-06-10 08:19:14Functions: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_traitsIcESaIcEEE406024
_ZN4PLMD6Random7setSeedEi406835
_ZN4PLMD6Random8GaussianEv1242377
_ZN4PLMD6Random7RandU01Ev1582263
_ZN4PLMD6Random3U01Ev5575012
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Random.cpp.func.html b/coverage/tools/Random.cpp.func.html new file mode 100644 index 0000000000..9bcacea116 --- /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-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Random10fromStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD6Random13ReadStateFullERSi0
_ZN4PLMD6Random3U01Ev5575012
_ZN4PLMD6Random4U01dEv2
_ZN4PLMD6Random7RandU01Ev1582263
_ZN4PLMD6Random7ShuffleERSt6vectorIjSaIjEE2
_ZN4PLMD6Random7setSeedEi406835
_ZN4PLMD6Random8GaussianEv1242377
_ZN4PLMD6RandomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE406024
_ZNK4PLMD6Random14WriteStateFullERSo1
_ZNK4PLMD6Random8toStringERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Random.cpp.gcov.html b/coverage/tools/Random.cpp.gcov.html new file mode 100644 index 0000000000..3156c28709 --- /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-06-10 08:19:14Functions: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      406024 : Random::Random(const std::string & name):
+      39      406024 :   switchGaussian(false),
+      40      406024 :   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      406024 :   name(&name!=&noname?name:"noname")
+      47             : {
+      48      406024 :   iy=0;
+      49    13398792 :   for(unsigned i=0; i<NTAB; i++) iv[i]=0;
+      50      406024 :   setSeed(0);
+      51      406024 : }
+      52             : 
+      53      406835 : void Random::setSeed(int idum_) {
+      54      406835 :   if(idum_>0) idum_=-idum_;
+      55      406835 :   idum=idum_;
+      56      406835 :   incPrec=false;
+      57      406835 : }
+      58             : 
+      59     1582263 : double Random::RandU01 ()
+      60             : {
+      61     1582263 :   if (incPrec)
+      62           1 :     return U01d();
+      63             :   else
+      64     1582262 :     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     5575012 : double Random::U01() {
+      77             :   int j,k;
+      78             :   double temp;
+      79     5575012 :   if (idum <= 0 || !iy) {
+      80        1285 :     if (-idum < 1) idum=1;
+      81         626 :     else idum = -idum;
+      82       52685 :     for (j=NTAB+7; j>=0; j--) {
+      83       51400 :       k=idum/IQ;
+      84       51400 :       idum=IA*(idum-k*IQ)-IR*k;
+      85       51400 :       if (idum < 0) idum += IM;
+      86       51400 :       if (j < NTAB) iv[j] = idum;
+      87             :     }
+      88        1285 :     iy=iv[0];
+      89             :   }
+      90     5575012 :   k=idum/IQ;
+      91     5575012 :   idum=IA*(idum-k*IQ)-IR*k;
+      92     5575012 :   if (idum < 0) idum += IM;
+      93     5575012 :   j=iy/NDIV;
+      94     5575012 :   iy=iv[j];
+      95     5575012 :   iv[j] = idum;
+      96     5575012 :   if ((temp=AM*iy) > RNMX) return RNMX;
+      97     5575012 :   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      790625 :     v1=2.0*RandU01()-1.0;
+     150      790625 :     v2=2.0*RandU01()-1.0;
+     151      790625 :     rsq=v1*v1+v2*v2;
+     152      790625 :     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.15
+
+ + + 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 0000000000..005997ab92 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Random.h.func.html b/coverage/tools/Random.h.func.html new file mode 100644 index 0000000000..53b80bfd55 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Random.h.gcov.html b/coverage/tools/Random.h.gcov.html new file mode 100644 index 0000000000..fcb74ba186 --- /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-06-10 08:19:14Functions: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      405974 : 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.15
+
+ + + 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 0000000000..81974edbe1 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.func.html b/coverage/tools/RootFindingBase.h.func.html new file mode 100644 index 0000000000..53297fd002 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.gcov.html b/coverage/tools/RootFindingBase.h.gcov.html new file mode 100644 index 0000000000..f9dadac4bb --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..f2379a8bb5 --- /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:2020100.0 %
Date:2024-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsERSoRKNS_9StopwatchE926
_ZNK4PLMD9Stopwatch3logERSo926
_ZN4PLMD9StopwatchD2Ev404988
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.func.html b/coverage/tools/Stopwatch.cpp.func.html new file mode 100644 index 0000000000..e489034b21 --- /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:2020100.0 %
Date:2024-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9StopwatchD2Ev404988
_ZN4PLMDlsERSoRKNS_9StopwatchE926
_ZNK4PLMD9Stopwatch3logERSo926
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.gcov.html b/coverage/tools/Stopwatch.cpp.gcov.html new file mode 100644 index 0000000000..98345e596e --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.gcov.html @@ -0,0 +1,154 @@ + + + + + + + + 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:2020100.0 %
Date:2024-06-10 08:19:14Functions: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         926 : std::ostream& operator<<(std::ostream&os,const Stopwatch&sw) {
+      36         926 :   return sw.log(os);
+      37             : }
+      38             : 
+      39      404988 : Stopwatch::~Stopwatch() {
+      40      404988 :   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        6935 :     for(auto & w : watches) {
+      45        6012 :       if(w.second.state==Watch::State::paused) w.second.start().stop();
+      46             :     }
+      47         923 :     *mylog << *this;
+      48             :   }
+      49      404988 : }
+      50             : 
+      51         926 : std::ostream& Stopwatch::log(std::ostream&os)const {
+      52             :   char buffer[1000];
+      53         926 :   buffer[0]=0;
+      54       37966 :   for(unsigned i=0; i<40; i++) os<<" ";
+      55         926 :   os<<"      Cycles        Total      Average      Minimum      Maximum\n";
+      56             : 
+      57             :   std::vector<std::string> names;
+      58        6944 :   for(const auto & it : watches) names.push_back(it.first);
+      59         926 :   std::sort(names.begin(),names.end());
+      60             : 
+      61             :   const double frac=1.0/1000000000.0;
+      62             : 
+      63        6944 :   for(const auto & name : names) {
+      64             :     const Watch&t(watches.find(name)->second);
+      65             :     os<<name;
+      66      148755 :     for(unsigned i=name.length(); i<40; i++) os<<" ";
+      67        6018 :     std::sprintf(buffer,"%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);
+      68        6018 :     os<<buffer;
+      69             :   }
+      70         926 :   return os;
+      71         926 : }
+      72             : 
+      73             : }
+      74             : 
+      75             : 
+      76             : 
+      77             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..a72a807eda --- /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:515592.7 %
Date:2024-06-10 08:19:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Stopwatch5pauseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE570
_ZN4PLMD9Stopwatch4stopERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE573
_ZN4PLMD9Stopwatch5startERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1146
_ZN4PLMD9Stopwatch7HandleraSEOS1_3493
_ZN4PLMD9Stopwatch10startPauseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1040740
_ZN4PLMDL20StopwatchEmptyStringEv1043018
_ZN4PLMD9Stopwatch9startStopERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1481678
_ZN4PLMD9Stopwatch5Watch4stopEv1483165
_ZN4PLMD9Stopwatch5Watch5pauseEv2524352
_ZN4PLMD9Stopwatch7HandlerD2Ev6051210
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Stopwatch.h.func.html b/coverage/tools/Stopwatch.h.func.html new file mode 100644 index 0000000000..9b67ef5ee4 --- /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:515592.7 %
Date:2024-06-10 08:19:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Stopwatch10startPauseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1040740
_ZN4PLMD9Stopwatch4stopERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE573
_ZN4PLMD9Stopwatch5Watch4stopEv1483165
_ZN4PLMD9Stopwatch5Watch5pauseEv2524352
_ZN4PLMD9Stopwatch5pauseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE570
_ZN4PLMD9Stopwatch5startERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1146
_ZN4PLMD9Stopwatch7HandlerD2Ev6051210
_ZN4PLMD9Stopwatch7HandleraSEOS1_3493
_ZN4PLMD9Stopwatch9startStopERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1481678
_ZN4PLMDL20StopwatchEmptyStringEv1043018
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Stopwatch.h.gcov.html b/coverage/tools/Stopwatch.h.gcov.html new file mode 100644 index 0000000000..85f44d9d78 --- /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:515592.7 %
Date:2024-06-10 08:19:14Functions: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 <string>
+      27             : #include <unordered_map>
+      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     1043018 : inline static const std::string & StopwatchEmptyString() noexcept {
+     172     1043018 :   const static std::string s;
+     173     1043018 :   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       10042 :   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             :   std::unordered_map<std::string,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      404404 :   explicit Stopwatch(Log&log): mylog(&log) {}
+     265             : // Destructor.
+     266             :   ~Stopwatch();
+     267             : /// Start timer named "name"
+     268             :   Stopwatch& start(const std::string&name=StopwatchEmptyString());
+     269             : /// Stop timer named "name"
+     270             :   Stopwatch& stop(const std::string&name=StopwatchEmptyString());
+     271             : /// Pause timer named "name"
+     272             :   Stopwatch& pause(const std::string&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&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&name=StopwatchEmptyString());
+     285             : };
+     286             : 
+     287             : inline
+     288             : Stopwatch::Handler::Handler(Watch* watch,bool stop) :
+     289     2522418 :   watch(watch),
+     290     2522418 :   stop(stop)
+     291             : {
+     292             :   watch->start();
+     293             : }
+     294             : 
+     295             : inline
+     296     6051210 : Stopwatch::Handler::~Handler() {
+     297     6051210 :   if(watch) {
+     298     2522418 :     if(stop) watch->stop();
+     299     1040740 :     else watch->pause();
+     300             :   }
+     301     6051210 : }
+     302             : 
+     303             : inline
+     304        1146 : Stopwatch& Stopwatch::start(const std::string & name) {
+     305             :   watches[name].start();
+     306        1146 :   return *this;
+     307             : }
+     308             : 
+     309             : inline
+     310         573 : Stopwatch& Stopwatch::stop(const std::string & name) {
+     311         573 :   watches[name].stop();
+     312         573 :   return *this;
+     313             : }
+     314             : 
+     315             : inline
+     316         570 : Stopwatch& Stopwatch::pause(const std::string & name) {
+     317         570 :   watches[name].pause();
+     318         570 :   return *this;
+     319             : }
+     320             : 
+     321             : inline
+     322     1481678 : Stopwatch::Handler Stopwatch::startStop(const std::string&name) {
+     323     1481678 :   return watches[name].startStop();
+     324             : }
+     325             : 
+     326             : inline
+     327     1040740 : Stopwatch::Handler Stopwatch::startPause(const std::string&name) {
+     328     1040740 :   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        3493 : Stopwatch::Handler & Stopwatch::Handler::operator=(Handler && handler) noexcept {
+     341        3493 :   if(this!=&handler) {
+     342        3493 :     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        3493 :     watch=handler.watch;
+     353        3493 :     stop=handler.stop;
+     354        3493 :     handler.watch=nullptr;
+     355             :   }
+     356        3493 :   return *this;
+     357             : }
+     358             : 
+     359             : inline
+     360             : Stopwatch::Watch & Stopwatch::Watch::start() {
+     361     2524478 :   state=State::started;
+     362     2524478 :   running++;
+     363     2524478 :   lastStart=std::chrono::high_resolution_clock::now();
+     364             :   return *this;
+     365             : }
+     366             : 
+     367             : inline
+     368     1483165 : Stopwatch::Watch & Stopwatch::Watch::stop() {
+     369     1483165 :   pause();
+     370     1483165 :   state=State::stopped;
+     371     1483165 :   cycles++;
+     372     1483165 :   total+=lap;
+     373     1483165 :   if(lap>max)max=lap;
+     374     1483165 :   if(min>lap || cycles==1)min=lap;
+     375     1483165 :   lap=0;
+     376     1483165 :   return *this;
+     377             : }
+     378             : 
+     379             : inline
+     380     2524352 : Stopwatch::Watch & Stopwatch::Watch::pause() {
+     381     2524352 :   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     2524352 :   plumed_assert(running>0) << "Non matching start/pause or start/stop commands in a Stopwatch";
+     386     2524352 :   running--;
+     387             : // notice: with exception safety the following might be converted to a plain error.
+     388             : // I leave it like this for now:
+     389     2524352 :   if(running!=0) return *this;
+     390     2524301 :   auto t=std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()-lastStart);
+     391     2524301 :   lap+=t.count();
+     392     2524301 :   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.15
+
+ + + 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 0000000000..8c8ae4d729 --- /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:648575.3 %
Date:2024-06-10 08:19:14Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10Subprocess7HandlerC2EOS1_0
_ZN4PLMD10Subprocess7HandleraSEOS1_0
_ZN4PLMD10Subprocess4contEv16
_ZN4PLMD10Subprocess5flushEv16
_ZN4PLMD10Subprocess7HandlerC2EPS0_16
_ZN4PLMD10Subprocess7HandlerD2Ev16
_ZN4PLMD10Subprocess7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE16
_ZN4PLMD13SubprocessPid4contEv16
_ZN4PLMD10Subprocess4stopEv18
_ZN4PLMD13SubprocessPid4stopEv18
_ZN4PLMDL26SubprocessPidGetenvSignalsEv34
_ZN4PLMD10Subprocess9availableEv83
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10002
_ZN4PLMD10SubprocessD2Ev10002
_ZN4PLMD13SubprocessPidC2Ei10002
_ZN4PLMD13SubprocessPidD2Ev10002
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.func.html b/coverage/tools/Subprocess.cpp.func.html new file mode 100644 index 0000000000..dbc3214b3b --- /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:648575.3 %
Date:2024-06-10 08:19:14Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10Subprocess4contEv16
_ZN4PLMD10Subprocess4stopEv18
_ZN4PLMD10Subprocess5flushEv16
_ZN4PLMD10Subprocess7HandlerC2EOS1_0
_ZN4PLMD10Subprocess7HandlerC2EPS0_16
_ZN4PLMD10Subprocess7HandlerD2Ev16
_ZN4PLMD10Subprocess7HandleraSEOS1_0
_ZN4PLMD10Subprocess7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE16
_ZN4PLMD10Subprocess9availableEv83
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10002
_ZN4PLMD10SubprocessD2Ev10002
_ZN4PLMD13SubprocessPid4contEv16
_ZN4PLMD13SubprocessPid4stopEv18
_ZN4PLMD13SubprocessPidC2Ei10002
_ZN4PLMD13SubprocessPidD2Ev10002
_ZN4PLMDL26SubprocessPidGetenvSignalsEv34
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.gcov.html b/coverage/tools/Subprocess.cpp.gcov.html new file mode 100644 index 0000000000..5b7cd91b23 --- /dev/null +++ b/coverage/tools/Subprocess.cpp.gcov.html @@ -0,0 +1,266 @@ + + + + + + + + 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:648575.3 %
Date:2024-06-10 08:19:14Functions: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             : #include <sys/wait.h>
+      29             : #endif
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /// Retrieve PLUMED_ENABLE_SIGNALS.
+      34             : /// Inline static so that it can store a static variable (for quicker access)
+      35             : /// without adding a unique global symbol to a library including this header file.
+      36          34 : inline static bool SubprocessPidGetenvSignals() noexcept {
+      37          34 :   static const bool res=std::getenv("PLUMED_ENABLE_SIGNALS");
+      38          34 :   return res;
+      39             : }
+      40             : 
+      41             : /// Small utility class, used to avoid inclusion of unistd.h> in a header file.
+      42             : class SubprocessPid {
+      43             : #ifdef __PLUMED_HAS_SUBPROCESS
+      44             : public:
+      45             :   pid_t pid;
+      46       10002 :   explicit SubprocessPid(pid_t pid):
+      47       10002 :     pid(pid)
+      48             :   {
+      49       10002 :     plumed_assert(pid!=0 && pid!=-1);
+      50       10002 :   }
+      51          18 :   void stop() noexcept {
+      52             :     // Signals give problems with MPI on Travis.
+      53             :     // I disable them for now.
+      54          18 :     if(SubprocessPidGetenvSignals()) if(pid!=0 && pid!=-1) kill(pid,SIGSTOP);
+      55          18 :   }
+      56          16 :   void cont() noexcept {
+      57             :     // Signals give problems with MPI on Travis.
+      58             :     // I disable them for now.
+      59          16 :     if(SubprocessPidGetenvSignals()) if(pid!=0 && pid!=-1) kill(pid,SIGCONT);
+      60          16 :   }
+      61       10002 :   ~SubprocessPid() {
+      62             :     // this is apparently working also with MPI on Travis.
+      63       10002 :     if(pid!=0 && pid!=-1) {
+      64             :       int status;
+      65       10002 :       kill(pid,SIGINT);
+      66       10002 :       waitpid(pid, &status, 0); // Wait for the child process to terminate
+      67             :     }
+      68       10002 :   }
+      69             : #endif
+      70             : };
+      71             : 
+      72       10002 : Subprocess::Subprocess(const std::string & cmd) {
+      73             : #ifdef __PLUMED_HAS_SUBPROCESS
+      74       10002 :   char* arr [] = {
+      75             :     // const_cast are necessary here due to the declaration of execv
+      76             :     const_cast<char*>("/bin/sh"),
+      77             :     const_cast<char*>("-c"),
+      78             :     const_cast<char*>(cmd.c_str()),
+      79             :     nullptr
+      80       10002 :   };
+      81             :   int cp[2];
+      82             :   int pc[2];
+      83       10002 :   if(pipe(pc)<0) plumed_error()<<"error creating parent to child pipe";
+      84       10002 :   if(pipe(cp)<0) plumed_error()<<"error creating child to parent pipe";
+      85       10002 :   pid_t pid=fork();
+      86       10002 :   switch(pid) {
+      87           0 :   case -1:
+      88           0 :     plumed_error()<<"error forking";
+      89             :     break;
+      90             : // CHILD:
+      91           0 :   case 0:
+      92             :   {
+      93           0 :     if(close(1)<0) plumed_error()<<"error closing file";
+      94           0 :     if(dup(cp[1])<0) plumed_error()<<"error duplicating file";
+      95           0 :     if(close(0)<0) plumed_error()<<"error closing file";
+      96           0 :     if(dup(pc[0])<0) plumed_error()<<"error duplicating file";
+      97           0 :     if(close(pc[1])<0) plumed_error()<<"error closing file";
+      98           0 :     if(close(cp[0])<0) plumed_error()<<"error closing file";
+      99           0 :     execv(arr[0],arr);
+     100           0 :     plumed_error()<<"error in script file";
+     101             :   }
+     102             : // PARENT::
+     103       10002 :   default:
+     104       20004 :     this->pid=Tools::make_unique<SubprocessPid>(pid);
+     105       10002 :     if(close(pc[0])<0) plumed_error()<<"error closing file";
+     106       10002 :     if(close(cp[1])<0) plumed_error()<<"error closing file";
+     107       10002 :     fpc=pc[1];
+     108       10002 :     fcp=cp[0];
+     109       10002 :     fppc=fdopen(fpc,"w");
+     110       10002 :     parent_to_child.link(fppc);
+     111       10002 :     fpcp=fdopen(fcp,"r");
+     112       10002 :     child_to_parent.link(fpcp);
+     113             :   }
+     114             : #else
+     115             :   plumed_error()<<"Subprocess not supported";
+     116             : #endif
+     117       10002 : }
+     118             : 
+     119       10002 : Subprocess::~Subprocess() {
+     120             : #ifdef __PLUMED_HAS_SUBPROCESS
+     121             : // close files:
+     122       10002 :   fclose(fppc);
+     123       10002 :   fclose(fpcp);
+     124             : // fclose also closes the underlying descriptors,
+     125             : // so this is not needed:
+     126       10002 :   close(fpc);
+     127       10002 :   close(fcp);
+     128             : // after closing the communication, the subprocess is killed
+     129             : // in pid's destructor
+     130             : #endif
+     131       10002 : }
+     132             : 
+     133          83 : bool Subprocess::available() noexcept {
+     134             : #ifdef __PLUMED_HAS_SUBPROCESS
+     135          83 :   return true;
+     136             : #else
+     137             :   return false;
+     138             : #endif
+     139             : }
+     140             : 
+     141          18 : void Subprocess::stop() noexcept {
+     142             : #ifdef __PLUMED_HAS_SUBPROCESS
+     143          18 :   pid->stop();
+     144             : #endif
+     145          18 : }
+     146             : 
+     147          16 : void Subprocess::cont() noexcept {
+     148             : #ifdef __PLUMED_HAS_SUBPROCESS
+     149          16 :   pid->cont();
+     150             : #endif
+     151          16 : }
+     152             : 
+     153          16 : void Subprocess::flush() {
+     154          16 :   parent_to_child.flush();
+     155          16 : }
+     156             : 
+     157          16 : Subprocess & Subprocess::getline(std::string & line) {
+     158          16 :   child_to_parent.getline(line);
+     159          16 :   if(!child_to_parent) plumed_error() <<"error reading subprocess";
+     160          16 :   return (*this);
+     161             : }
+     162             : 
+     163          16 : Subprocess::Handler::Handler(Subprocess *sp) noexcept:
+     164          16 :   sp(sp)
+     165             : {
+     166          16 :   sp->cont();
+     167          16 : }
+     168             : 
+     169          16 : Subprocess::Handler::~Handler() {
+     170          16 :   if(sp) sp->stop();
+     171          16 : }
+     172             : 
+     173           0 : Subprocess::Handler::Handler(Handler && handler) noexcept :
+     174           0 :   sp(handler.sp)
+     175             : {
+     176           0 :   handler.sp=nullptr;
+     177           0 : }
+     178             : 
+     179           0 : Subprocess::Handler & Subprocess::Handler::operator=(Handler && handler) noexcept {
+     180           0 :   if(this!=&handler) {
+     181           0 :     if(sp) sp->stop();
+     182           0 :     sp=handler.sp;
+     183           0 :     handler.sp=nullptr;
+     184             :   }
+     185           0 :   return *this;
+     186             : }
+     187             : 
+     188             : 
+     189             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..13acc1c135 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA2_cEERNS_10SubprocessES3_RKT_16
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_10SubprocessES8_RKT_16
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Subprocess.h.func.html b/coverage/tools/Subprocess.h.func.html new file mode 100644 index 0000000000..3d06575d11 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA2_cEERNS_10SubprocessES3_RKT_16
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_10SubprocessES8_RKT_16
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Subprocess.h.gcov.html b/coverage/tools/Subprocess.h.gcov.html new file mode 100644 index 0000000000..892a00f8ee --- /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-06-10 08:19:14Functions: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          16 :     return Handler(this);
+     130             :   }
+     131             : };
+     132             : 
+     133             : template <class T>
+     134          32 : Subprocess& operator<<(Subprocess& ep,const T &t) {
+     135          32 :   ep.parent_to_child<<t;
+     136          32 :   return ep;
+     137             : }
+     138             : 
+     139             : }
+     140             : 
+     141             : #endif
+     142             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..173a0ca268 --- /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:25626397.3 %
Date:2024-06-10 08:19:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD17SwitchingFunction6get_d0Ev6
_ZNK4PLMD17SwitchingFunction6get_r0Ev30
_ZN4PLMD17SwitchingFunction3setEiidd61
_ZN4PLMD17SwitchingFunction16registerKeywordsERNS_8KeywordsE90
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1018
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1068
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd19721455
_ZNK4PLMD17SwitchingFunction9get_dmax2Ev23893569
_ZNK4PLMD17SwitchingFunction11do_rationalEdRdii41285999
_ZNK4PLMD17SwitchingFunction9calculateEdRd88945887
_ZNK4PLMD17SwitchingFunction8get_dmaxEv117918073
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.func.html b/coverage/tools/SwitchingFunction.cpp.func.html new file mode 100644 index 0000000000..589d932b1f --- /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:25626397.3 %
Date:2024-06-10 08:19:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17SwitchingFunction16registerKeywordsERNS_8KeywordsE90
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1018
_ZN4PLMD17SwitchingFunction3setEiidd61
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1068
_ZNK4PLMD17SwitchingFunction11do_rationalEdRdii41285999
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd19721455
_ZNK4PLMD17SwitchingFunction6get_d0Ev6
_ZNK4PLMD17SwitchingFunction6get_r0Ev30
_ZNK4PLMD17SwitchingFunction8get_dmaxEv117918073
_ZNK4PLMD17SwitchingFunction9calculateEdRd88945887
_ZNK4PLMD17SwitchingFunction9get_dmax2Ev23893569
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.gcov.html b/coverage/tools/SwitchingFunction.cpp.gcov.html new file mode 100644 index 0000000000..f333571756 --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.gcov.html @@ -0,0 +1,630 @@ + + + + + + + + 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:25626397.3 %
Date:2024-06-10 08:19:14Functions: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          90 : void SwitchingFunction::registerKeywords( Keywords& keys ) {
+     177         180 :   keys.add("compulsory","R_0","the value of R_0 in the switching function");
+     178         180 :   keys.add("compulsory","D_0","0.0","the value of D_0 in the switching function");
+     179         180 :   keys.add("optional","D_MAX","the value at which the switching function can be assumed equal to zero");
+     180         180 :   keys.add("compulsory","NN","6","the value of n in the switching function (only needed for TYPE=RATIONAL)");
+     181         180 :   keys.add("compulsory","MM","0","the value of m in the switching function (only needed for TYPE=RATIONAL); 0 implies 2*NN");
+     182         180 :   keys.add("compulsory","A","the value of a in the switching function (only needed for TYPE=SMAP)");
+     183         180 :   keys.add("compulsory","B","the value of b in the switching function (only needed for TYPE=SMAP)");
+     184          90 : }
+     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        1246 :   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         438 :     if(present && !Tools::parse(data,"NN",nn)) errormsg="could not parse NN";
+     233         290 :     present=Tools::findKeyword(data,"MM");
+     234         438 :     if(present && !Tools::parse(data,"MM",mm)) errormsg="could not parse MM";
+     235         290 :     if(mm==0) mm=2*nn;
+     236         356 :     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]=&const_cast<lepton::CompiledExpression*>(&expression[t])->getVariableReference("x");
+     282           8 :       } else if(vars.size()==1 && found_x2) {
+     283           8 :         lepton_ref[t]=&const_cast<lepton::CompiledExpression*>(&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]=&const_cast<lepton::CompiledExpression*>(&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          95 :     double s0=calculate(0.0,dummy);
+     317          95 :     double sd=calculate(dmax,dummy);
+     318          95 :     stretch=1.0/(s0-sd);
+     319          95 :     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    41285999 : double SwitchingFunction::do_rational(double rdist,double&dfunc,int nn,int mm)const {
+     366             :   double result;
+     367    41285999 :   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    25190661 :     double rNdist=Tools::fastpow(rdist,nn-1);
+     370    25190661 :     double iden=1.0/(1+rNdist*rdist);
+     371    25190661 :     dfunc = -nn*rNdist*iden*iden;
+     372             :     result = iden;
+     373             :   } else {
+     374    16095338 :     if(rdist>(1.-5.0e10*epsilon) && rdist<(1+5.0e10*epsilon)) {
+     375          10 :       const double secDev = ((nn * (mm * mm - 3.0* mm * (-1 + nn ) + nn *(-3 + 2* nn )))/(6.0* mm ));
+     376          10 :       const double x =(rdist-1.0);
+     377          10 :       dfunc=0.5*nn*double(nn-mm)/mm;
+     378          10 :       result = double(nn)/mm+ x * ( dfunc + 0.5 * x * secDev);
+     379          10 :       dfunc  = dfunc + x * secDev;
+     380          10 :     } else {
+     381    16095328 :       double rNdist=Tools::fastpow(rdist,nn-1);
+     382    16095328 :       double rMdist=Tools::fastpow(rdist,mm-1);
+     383    16095328 :       double num = 1.-rNdist*rdist;
+     384    16095328 :       double iden = 1./(1.-rMdist*rdist);
+     385    16095328 :       double func = num*iden;
+     386             :       result = func;
+     387    16095328 :       dfunc = ((-nn*rNdist*iden)+(func*(iden*mm)*rMdist));
+     388             :     }
+     389             :   }
+     390    41285999 :   return result;
+     391             : }
+     392             : 
+     393    19721455 : double SwitchingFunction::calculateSqr(double distance2,double&dfunc)const {
+     394    19721455 :   if(fastrational) {
+     395     7657979 :     if(distance2>dmax_2) {
+     396      144482 :       dfunc=0.0;
+     397      144482 :       return 0.0;
+     398             :     }
+     399     7513497 :     const double rdist_2 = distance2*invr0_2;
+     400     7513497 :     double result=do_rational(rdist_2,dfunc,nn/2,mm/2);
+     401             : // chain rule:
+     402     7513497 :     dfunc*=2*invr0_2;
+     403             : // stretch:
+     404     7513497 :     result=result*stretch+shift;
+     405     7513497 :     dfunc*=stretch;
+     406     7513497 :     return result;
+     407    12063476 :   } else if(leptonx2) {
+     408     1248110 :     if(distance2>dmax_2) {
+     409           8 :       dfunc=0.0;
+     410           8 :       return 0.0;
+     411             :     }
+     412     1248102 :     const unsigned t=OpenMP::getThreadNum();
+     413     1248102 :     const double rdist_2 = distance2*invr0_2;
+     414     1248102 :     plumed_assert(t<expression.size());
+     415     1248102 :     if(lepton_ref[t]) *lepton_ref[t]=rdist_2;
+     416     1248102 :     if(lepton_ref_deriv[t]) *lepton_ref_deriv[t]=rdist_2;
+     417     1248102 :     double result=expression[t].evaluate();
+     418     1248102 :     dfunc=expression_deriv[t].evaluate();
+     419             : // chain rule:
+     420     1248102 :     dfunc*=2*invr0_2;
+     421             : // stretch:
+     422     1248102 :     result=result*stretch+shift;
+     423     1248102 :     dfunc*=stretch;
+     424     1248102 :     return result;
+     425             :   } else {
+     426    10815366 :     double distance=std::sqrt(distance2);
+     427    10815366 :     return calculate(distance,dfunc);
+     428             :   }
+     429             : }
+     430             : 
+     431    88945887 : double SwitchingFunction::calculate(double distance,double&dfunc)const {
+     432    88945887 :   plumed_massert(init,"you are trying to use an unset SwitchingFunction");
+     433    88945887 :   if(distance>dmax) {
+     434      450541 :     dfunc=0.0;
+     435      450541 :     return 0.0;
+     436             :   }
+     437             : // in this case, the lepton object stores only the calculateSqr function
+     438             : // so we have to implement calculate in terms of calculateSqr
+     439    88495346 :   if(leptonx2) {
+     440           2 :     return calculateSqr(distance*distance,dfunc);
+     441             :   }
+     442    88495344 :   const double rdist = (distance-d0)*invr0;
+     443             :   double result;
+     444             : 
+     445    88495344 :   if(rdist<=0.) {
+     446             :     result=1.;
+     447    24431541 :     dfunc=0.0;
+     448             :   } else {
+     449    64063803 :     if(type==smap) {
+     450    21789971 :       double sx=c*Tools::fastpow( rdist, a );
+     451    21789971 :       result=std::pow( 1.0 + sx, d );
+     452    21789971 :       dfunc=-b*sx/rdist*result/(1.0+sx);
+     453             :     } else if(type==rational) {
+     454    33772502 :       result=do_rational(rdist,dfunc,nn,mm);
+     455             :     } else if(type==exponential) {
+     456     2486478 :       result=std::exp(-rdist);
+     457     2486478 :       dfunc=-result;
+     458             :     } else if(type==nativeq) {
+     459      146570 :       double rdist2 = beta*(distance - lambda * ref);
+     460      146570 :       double exprdist=std::exp(rdist2);
+     461      146570 :       double exprmdist=1.0/exprdist;
+     462      146570 :       result=1./(1.+exprdist);
+     463      146570 :       dfunc=-beta/(exprmdist+1.0)/(1.+exprdist)/invr0;
+     464             :     } else if(type==gaussian) {
+     465      195683 :       result=std::exp(-0.5*rdist*rdist);
+     466      195683 :       dfunc=-rdist*result;
+     467             :     } else if(type==cubic) {
+     468      127132 :       double tmp1=rdist-1, tmp2=(1+2*rdist);
+     469      127132 :       result=tmp1*tmp1*tmp2;
+     470      127132 :       dfunc=2*tmp1*tmp2 + 2*tmp1*tmp1;
+     471             :     } else if(type==tanh) {
+     472        8000 :       double tmp1=std::tanh(rdist);
+     473        8000 :       result = 1.0 - tmp1;
+     474        8000 :       dfunc=-(1-tmp1*tmp1);
+     475             :     } else if(type==cosinus) {
+     476             :       if(rdist<=0.0) {
+     477             : // rdist = (r-r1)/(r2-r1) ; rdist<=0.0 if r <=r1
+     478             :         result=1.;
+     479             :         dfunc=0.0;
+     480      522053 :       } else if(rdist<=1.0) {
+     481             : // rdist = (r-r1)/(r2-r1) ; 0.0<=rdist<=1.0 if r1 <= r <=r2; (r2-r1)/(r2-r1)=1
+     482      226962 :         double tmpcos = std::cos ( rdist * PI );
+     483      226962 :         double tmpsin = std::sin ( rdist * PI );
+     484      226962 :         result = 0.5 * (tmpcos + 1.0);
+     485      226962 :         dfunc=-0.5 * PI * tmpsin * invr0;
+     486             :       } else {
+     487             :         result=0.;
+     488      295091 :         dfunc=0.0;
+     489             :       }
+     490             :     } else if(type==leptontype) {
+     491     5015414 :       const unsigned t=OpenMP::getThreadNum();
+     492     5015414 :       plumed_assert(t<expression.size());
+     493     5015414 :       if(lepton_ref[t]) *lepton_ref[t]=rdist;
+     494     5015414 :       if(lepton_ref_deriv[t]) *lepton_ref_deriv[t]=rdist;
+     495     5015414 :       result=expression[t].evaluate();
+     496     5015414 :       dfunc=expression_deriv[t].evaluate();
+     497           0 :     } else plumed_merror("Unknown switching function type");
+     498             : // this is for the chain rule (derivative of rdist):
+     499    64063803 :     dfunc*=invr0;
+     500             : // for any future switching functions, be aware that multiplying invr0 is only correct for functions of rdist = (r-d0)/r0.
+     501             : 
+     502             : // this is because calculate() sets dfunc to the derivative divided times the distance.
+     503             : // (I think this is misleading and I would like to modify it - GB)
+     504    64063803 :     dfunc/=distance;
+     505             :   }
+     506             : 
+     507    88495344 :   result=result*stretch+shift;
+     508    88495344 :   dfunc*=stretch;
+     509             : 
+     510    88495344 :   return result;
+     511             : }
+     512             : 
+     513          61 : void SwitchingFunction::set(int nn,int mm,double r0,double d0) {
+     514          61 :   init=true;
+     515          61 :   type=rational;
+     516          61 :   if(mm==0) mm=2*nn;
+     517          61 :   this->nn=nn;
+     518          61 :   this->mm=mm;
+     519          61 :   this->invr0=1.0/r0;
+     520          61 :   this->invr0_2=this->invr0*this->invr0;
+     521          61 :   this->d0=d0;
+     522          61 :   this->dmax=d0+r0*std::pow(0.00001,1./(nn-mm));
+     523          61 :   this->dmax_2=this->dmax*this->dmax;
+     524          61 :   this->leptonx2=false;
+     525          61 :   this->fastrational=(nn%2==0 && mm%2==0 && d0==0.0);
+     526             : 
+     527             :   double dummy;
+     528          61 :   double s0=calculate(0.0,dummy);
+     529          61 :   double sd=calculate(dmax,dummy);
+     530          61 :   stretch=1.0/(s0-sd);
+     531          61 :   shift=-sd*stretch;
+     532          61 : }
+     533             : 
+     534          30 : double SwitchingFunction::get_r0() const {
+     535          30 :   return 1./invr0;
+     536             : }
+     537             : 
+     538           6 : double SwitchingFunction::get_d0() const {
+     539           6 :   return d0;
+     540             : }
+     541             : 
+     542   117918073 : double SwitchingFunction::get_dmax() const {
+     543   117918073 :   return dmax;
+     544             : }
+     545             : 
+     546    23893569 : double SwitchingFunction::get_dmax2() const {
+     547    23893569 :   return dmax_2;
+     548             : }
+     549             : 
+     550             : }
+     551             : 
+     552             : 
+     553             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..1295fff9ab --- /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-06-10 08:19:14Functions: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_556397
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tensor.cpp.func.html b/coverage/tools/Tensor.cpp.func.html new file mode 100644 index 0000000000..e04916b84e --- /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-06-10 08:19:14Functions: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_556397
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tensor.cpp.gcov.html b/coverage/tools/Tensor.cpp.gcov.html new file mode 100644 index 0000000000..edee1698f7 --- /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-06-10 08:19:14Functions: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      556397 : 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      556397 :   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      556397 : }
+      36             : 
+      37             : 
+      38             : }
+      39             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..4a66f2b983 --- /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:14615196.7 %
Date:2024-06-10 08:19:14Functions:566882.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZNK4PLMD13TensorGenericILj4ELj4EEclEjj0
_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
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv63299
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv114515
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv180509
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE225936
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE487586
_ZN4PLMD10diagMatSymILj4ELj1EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE548920
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev548920
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev608260
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1261601
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv1275156
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1572291
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1730019
_ZN4PLMD10extProductILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS_13VectorGenericIXT_EEERKNS3_IXT0_EEE1747490
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv2767515
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3177897
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4168056
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_4338783
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE4613236
_ZNK4PLMD13TensorGenericILj4ELj3EEclEjj4618728
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_4916439
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_9325987
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13395655
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj16996312
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE32857369
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_42423502
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev44220744
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_46791016
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE105723948
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_130585225
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_148196355
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d154196012
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd154201037
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj225320897
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj5362930273
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tensor.h.func.html b/coverage/tools/Tensor.h.func.html new file mode 100644 index 0000000000..719fbe6ffc --- /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:14615196.7 %
Date:2024-06-10 08:19:14Functions:566882.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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_EEE1747490
_ZN4PLMD12VcrossTensorERKNS_13TensorGenericILj3ELj3EEERKNS_13VectorGenericILj3EEE48138
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev548920
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4168056
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv1275156
_ZN4PLMD13TensorGenericILj3ELj3EE6setColEjRKNS_13VectorGenericILj3EEE29160
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1572291
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13395655
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_148196355
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev44220744
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_9325987
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJffffffffEEEdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj225320897
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_46791016
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd154201037
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_42423502
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev608260
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj16996312
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE105723948
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE32857369
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE4613236
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE225936
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD8deriNormERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE48138
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_4338783
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_4916439
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE487586
_ZN4PLMDdvILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d254
_ZN4PLMDlsILj3ELj3EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDlsILj4ELj4EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1261601
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d154196012
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_130585225
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1730019
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv180509
_ZNK4PLMD13TensorGenericILj3ELj3EE6getColEj24300
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3177897
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv114515
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv2767515
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj5362930273
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv63299
_ZNK4PLMD13TensorGenericILj3ELj3EEpsEv21229
_ZNK4PLMD13TensorGenericILj4ELj3EEclEjj4618728
_ZNK4PLMD13TensorGenericILj4ELj4EEclEjj0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tensor.h.gcov.html b/coverage/tools/Tensor.h.gcov.html new file mode 100644 index 0000000000..15b76e1748 --- /dev/null +++ b/coverage/tools/Tensor.h.gcov.html @@ -0,0 +1,651 @@ + + + + + + + + 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:14615196.7 %
Date:2024-06-10 08:19:14Functions:566882.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             : #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    83933883 : void TensorGeneric<n,m>::auxiliaryConstructor(double first,Args... arg)
+     216             : {
+     217    83933883 :   d[n*m-(sizeof...(Args))-1]=first;
+     218    74607896 :   auxiliaryConstructor(arg...);
+     219    83933883 : }
+     220             : 
+     221             : template <unsigned n,unsigned m>
+     222             : template<typename... Args>
+     223     9325987 : 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     9325987 :   auxiliaryConstructor(first,arg...);
+     227     9325987 : }
+     228             : 
+     229             : template<unsigned n,unsigned m>
+     230    55631318 : TensorGeneric<n,m>::TensorGeneric() {
+     231    55631318 :   LoopUnroller<n*m>::_zero(d.data());
+     232    55631318 : }
+     233             : 
+     234             : template<unsigned n,unsigned m>
+     235   148196355 : TensorGeneric<n,m>::TensorGeneric(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     236  1926552615 :   for(unsigned i=0; i<n; i++)for(unsigned j=0; j<m; j++)d[i*m+j]=v1[i]*v2[j];
+     237   148196355 : }
+     238             : 
+     239             : template<unsigned n,unsigned m>
+     240     1275156 : void TensorGeneric<n,m>::zero() {
+     241     1275156 :   LoopUnroller<n*m>::_zero(d.data());
+     242     1275156 : }
+     243             : 
+     244             : template<unsigned n,unsigned m>
+     245   250360449 : 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   250360449 :   return d[m*i+j];
+     251             : }
+     252             : 
+     253             : template<unsigned n,unsigned m>
+     254  5367549001 : 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  5367549001 :   return d[m*i+j];
+     260             : }
+     261             : 
+     262             : template<unsigned n,unsigned m>
+     263    42423502 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator +=(const TensorGeneric<n,m>& b) {
+     264    42423502 :   LoopUnroller<n*m>::_add(d.data(),b.d.data());
+     265    42423502 :   return *this;
+     266             : }
+     267             : 
+     268             : template<unsigned n,unsigned m>
+     269    46791016 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator -=(const TensorGeneric<n,m>& b) {
+     270    46791016 :   LoopUnroller<n*m>::_sub(d.data(),b.d.data());
+     271    46791016 :   return *this;
+     272             : }
+     273             : 
+     274             : template<unsigned n,unsigned m>
+     275   154201037 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator *=(double s) {
+     276   154201037 :   LoopUnroller<n*m>::_mul(d.data(),s);
+     277   154201037 :   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       63299 : TensorGeneric<n,m> TensorGeneric<n,m>::operator-()const {
+     293       63299 :   TensorGeneric<n,m> r;
+     294       63299 :   LoopUnroller<n*m>::_neg(r.d.data(),d.data());
+     295       63299 :   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     2864019 : TensorGeneric<n,m>& TensorGeneric<n,m>::setRow(unsigned i,const VectorGeneric<m> & r) {
+     306    11456076 :   for(unsigned j=0; j<m; ++j) (*this)(i,j)=r(j);
+     307     2864019 :   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     3177897 : VectorGeneric<m> TensorGeneric<n,m>::getRow(unsigned i)const {
+     319     3177897 :   VectorGeneric<m> v;
+     320    12711588 :   for(unsigned j=0; j<m; ++j) v(j)=(*this)(i,j);
+     321     3177897 :   return v;
+     322             : }
+     323             : 
+     324             : template<unsigned n,unsigned m>
+     325     1730019 : TensorGeneric<n,m> operator+(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     326     1730019 :   TensorGeneric<n,m> t(t1);
+     327     1730019 :   t+=t2;
+     328     1730019 :   return t;
+     329             : }
+     330             : 
+     331             : template<unsigned n,unsigned m>
+     332     1261601 : TensorGeneric<n,m> operator-(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     333     1261601 :   TensorGeneric<n,m> t(t1);
+     334     1261601 :   t-=t2;
+     335     1261601 :   return t;
+     336             : }
+     337             : 
+     338             : template<unsigned n,unsigned m>
+     339   154196012 : TensorGeneric<n,m> operator*(const TensorGeneric<n,m>&t1,double s) {
+     340   154196012 :   TensorGeneric<n,m> t(t1);
+     341   154196012 :   t*=s;
+     342   154196012 :   return t;
+     343             : }
+     344             : 
+     345             : template<unsigned n,unsigned m>
+     346   130585225 : TensorGeneric<n,m> operator*(double s,const TensorGeneric<n,m>&t1) {
+     347   130585225 :   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      180509 : double TensorGeneric<3,3>::determinant()const {
+     358             :   return
+     359      180509 :     d[0]*d[4]*d[8]
+     360      180509 :     + d[1]*d[5]*d[6]
+     361      180509 :     + d[2]*d[3]*d[7]
+     362      180509 :     - d[0]*d[5]*d[7]
+     363      180509 :     - d[1]*d[3]*d[8]
+     364      180509 :     - d[2]*d[4]*d[6];
+     365             : }
+     366             : 
+     367             : template<unsigned n,unsigned m>
+     368             : inline
+     369    13395655 : TensorGeneric<n,n> TensorGeneric<n,m>::identity() {
+     370    13395655 :   TensorGeneric<n,n> t;
+     371    53582620 :   for(unsigned i=0; i<n; i++) t(i,i)=1.0;
+     372    13395655 :   return t;
+     373             : }
+     374             : 
+     375             : template<unsigned n,unsigned m>
+     376     2767515 : TensorGeneric<m,n> TensorGeneric<n,m>::transpose()const {
+     377     2767515 :   TensorGeneric<m,n> t;
+     378    35977695 :   for(unsigned i=0; i<m; i++)for(unsigned j=0; j<n; j++) t(i,j)=(*this)(j,i);
+     379     2767515 :   return t;
+     380             : }
+     381             : 
+     382             : template<>
+     383             : inline
+     384      114515 : TensorGeneric<3,3> TensorGeneric<3,3>::inverse()const {
+     385      114515 :   TensorGeneric t;
+     386      114515 :   double invdet=1.0/determinant();
+     387     1488695 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++)
+     388     1030635 :       t(j,i)=invdet*(   (*this)((i+1)%3,(j+1)%3)*(*this)((i+2)%3,(j+2)%3)
+     389     1030635 :                         -(*this)((i+1)%3,(j+2)%3)*(*this)((i+2)%3,(j+1)%3));
+     390      114515 :   return t;
+     391             : }
+     392             : 
+     393             : template<unsigned n,unsigned m,unsigned l>
+     394     4613236 : TensorGeneric<n,l> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b) {
+     395     4613236 :   TensorGeneric<n,l> t;
+     396   184529440 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<l; j++) for(unsigned k=0; k<m; k++) {
+     397   124557372 :         t(i,j)+=a(i,k)*b(k,j);
+     398             :       }
+     399     4613236 :   return t;
+     400             : }
+     401             : 
+     402             : template<unsigned n,unsigned m>
+     403    32857369 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const VectorGeneric<m>&b) {
+     404    32857369 :   VectorGeneric<n> t;
+     405   427145797 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(i,j)*b(j);
+     406    32857369 :   return t;
+     407             : }
+     408             : 
+     409             : template<unsigned n,unsigned m>
+     410   106108842 : VectorGeneric<n> matmul(const VectorGeneric<m>&a,const TensorGeneric<m,n>&b) {
+     411   106108842 :   VectorGeneric<n> t;
+     412  1380569628 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(j)*b(j,i);
+     413   106108842 :   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      225936 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b,const VectorGeneric<l>&c) {
+     428      225936 :   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       57491 :   return t.inverse();
+     449             : }
+     450             : 
+     451             : template<unsigned n,unsigned m>
+     452      487586 : TensorGeneric<n,m> transpose(const TensorGeneric<m,n>&t) {
+     453      487586 :   return t.transpose();
+     454             : }
+     455             : 
+     456             : template<unsigned n,unsigned m>
+     457     1747490 : TensorGeneric<n,m> extProduct(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     458     1747490 :   return TensorGeneric<n,m>(v1,v2);
+     459             : }
+     460             : 
+     461             : inline
+     462     4338783 : 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     4338783 :            -v2[2],   0.0, v2[0],
+     467     4338783 :            v2[1],-v2[0],   0.0);
+     468             : }
+     469             : 
+     470             : inline
+     471     4916439 : 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     4916439 :            v1[2],0.0,-v1[0],
+     476     4916439 :            -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             :   // documentation says that "matrix is destroyed" !!!
+     539      556394 :   auto mat_copy=mat;
+     540             :   // documentation says this is size n (even if m<n)
+     541             :   std::array<double,n> evals_tmp;
+     542      556394 :   int nn=n;              // dimension of matrix
+     543      556394 :   double vl=0.0, vu=1.0; // ranges - not used
+     544      556394 :   int one=1,mm=m;        // minimum and maximum index
+     545      556394 :   double abstol=0.0;     // tolerance
+     546      556394 :   int mout=0;            // number of eigenvalues found (same as mm)
+     547      556394 :   int info=0;            // result
+     548      556394 :   int liwork=iwork.size();
+     549      556394 :   int lwork=work.size();
+     550      556394 :   TensorGenericAux::local_dsyevr("V", (n==m?"A":"I"), "U", &nn, const_cast<double*>(&mat_copy[0][0]), &nn, &vl, &vu, &one, &mm,
+     551      556394 :                                  &abstol, &mout, &evals_tmp[0], &evec[0][0], &nn,
+     552             :                                  isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     553      556394 :   if(info!=0) plumed_error()<<"Error diagonalizing matrix\n"
+     554             :                               <<"Matrix:\n"<<mat<<"\n"
+     555             :                               <<"Info: "<<info<<"\n";
+     556      556394 :   plumed_assert(mout==m);
+     557     1134810 :   for(unsigned i=0; i<m; i++) evals[i]=evals_tmp[i];
+     558             :   // This changes eigenvectors so that the first non-null element
+     559             :   // of each of them is positive
+     560             :   // We can do it because the phase is arbitrary, and helps making
+     561             :   // the result reproducible
+     562     1134810 :   for(unsigned i=0; i<m; ++i) {
+     563             :     unsigned j=0;
+     564      578516 :     for(j=0; j<n; j++) if(evec(i,j)*evec(i,j)>1e-14) break;
+     565      946879 :     if(j<n) if(evec(i,j)<0.0) for(j=0; j<n; j++) evec(i,j)*=-1;
+     566             :   }
+     567      556394 : }
+     568             : 
+     569             : static_assert(sizeof(Tensor)==9*sizeof(double), "code cannot work if this is not satisfied");
+     570             : 
+     571             : }
+     572             : 
+     573             : #endif
+     574             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..95ccdbda25 --- /dev/null +++ b/coverage/tools/Tools.cpp.func-sort-c.html @@ -0,0 +1,237 @@ + + + + + + + + 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:21423690.7 %
Date:2024-06-10 08:19:14Functions:384192.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Tools12convertToAnyIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools13convertToRealIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERf0
_ZN4PLMD5Tools7bessel0ERKd14
_ZN4PLMD5Tools12convertToAnyIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_88
_ZN4PLMD5Tools12convertToIntIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_88
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl88
_ZN4PLMD5Tools12convertToAnyImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_111
_ZN4PLMD5Tools12convertToIntImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_111
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm111
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_128
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_128
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe128
_ZN4PLMD5Tools16DirectoryChangerC2EPKc518
_ZN4PLMD5Tools16DirectoryChangerD2Ev518
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4320
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_4876
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj4876
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5652
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11151
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE11307
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE14107
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb14560
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_78063
_ZN4PLMD5Tools11findKeywordERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_82463
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i90613
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE245185
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_250061
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_323265
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc632368
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE836078
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_876783
_ZN4PLMD5Tools12trimCommentsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1354472
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2222566
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2222566
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2225160
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2700044
_ZN4PLMD5Tools8getWordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKcPiSA_RKb3790573
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14034478
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14034478
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14034478
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tools.cpp.func.html b/coverage/tools/Tools.cpp.func.html new file mode 100644 index 0000000000..b7a2bce3c4 --- /dev/null +++ b/coverage/tools/Tools.cpp.func.html @@ -0,0 +1,237 @@ + + + + + + + + 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:21423690.7 %
Date:2024-06-10 08:19:14Functions:384192.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Tools11findKeywordERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_82463
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14034478
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_128
_ZN4PLMD5Tools12convertToAnyIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2225160
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_250061
_ZN4PLMD5Tools12convertToAnyIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_88
_ZN4PLMD5Tools12convertToAnyImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_111
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2222566
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_4876
_ZN4PLMD5Tools12convertToIntIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_88
_ZN4PLMD5Tools12convertToIntImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_111
_ZN4PLMD5Tools12trimCommentsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1354472
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14034478
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_128
_ZN4PLMD5Tools13convertToRealIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb14560
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE14107
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE245185
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_78063
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14034478
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe128
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERf0
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2222566
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj4876
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl88
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm111
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE11307
_ZN4PLMD5Tools16DirectoryChangerC2EPKc518
_ZN4PLMD5Tools16DirectoryChangerD2Ev518
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_323265
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4320
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5652
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE836078
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i90613
_ZN4PLMD5Tools7bessel0ERKd14
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2700044
_ZN4PLMD5Tools8getWordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKcPiSA_RKb3790573
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11151
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_876783
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc632368
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tools.cpp.gcov.html b/coverage/tools/Tools.cpp.gcov.html new file mode 100644 index 0000000000..8e0fd16680 --- /dev/null +++ b/coverage/tools/Tools.cpp.gcov.html @@ -0,0 +1,519 @@ + + + + + + + + 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:21423690.7 %
Date:2024-06-10 08:19:14Functions:384192.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 "Tools.h"
+      23             : #include "AtomNumber.h"
+      24             : #include "Exception.h"
+      25             : #include "IFile.h"
+      26             : #include "lepton/Lepton.h"
+      27             : #include <cstring>
+      28             : #include <dirent.h>
+      29             : #include <iostream>
+      30             : #include <map>
+      31             : #if defined(__PLUMED_HAS_CHDIR) || defined(__PLUMED_HAS_GETCWD)
+      32             : #include <unistd.h>
+      33             : #endif
+      34             : 
+      35             : #include <iomanip>
+      36             : 
+      37             : namespace PLMD {
+      38             : 
+      39             : template<class T>
+      40    16510026 : bool Tools::convertToAny(const std::string & str,T & t) {
+      41    30794892 :   std::istringstream istr(str.c_str());
+      42    16510026 :   bool ok=static_cast<bool>(istr>>t);
+      43    16510026 :   if(!ok) return false;
+      44             :   std::string remaining;
+      45    14406669 :   istr>>remaining;
+      46    14406669 :   return remaining.length()==0;
+      47    16510026 : }
+      48             : 
+      49     2222566 : bool Tools::convertNoexcept(const std::string & str,int & t) {
+      50     2222566 :   return convertToInt(str,t);
+      51             : }
+      52             : 
+      53          88 : bool Tools::convertNoexcept(const std::string & str,long int & t) {
+      54          88 :   return convertToInt(str,t);
+      55             : }
+      56             : 
+      57        4876 : bool Tools::convertNoexcept(const std::string & str,unsigned & t) {
+      58        4876 :   return convertToInt(str,t);
+      59             : }
+      60             : 
+      61         111 : bool Tools::convertNoexcept(const std::string & str,long unsigned & t) {
+      62         111 :   return convertToInt(str,t);
+      63             : }
+      64             : 
+      65      245185 : bool Tools::convertNoexcept(const std::string & str,AtomNumber &a) {
+      66             :   // Note: AtomNumber's are NOT converted as int, so as to
+      67             :   // avoid using lepton conversions.
+      68             :   unsigned i;
+      69      245185 :   bool r=convertToAny(str,i);
+      70      245185 :   if(r) a.setSerial(i);
+      71      245185 :   return r;
+      72             : }
+      73             : 
+      74             : template<class T>
+      75     2227641 : bool Tools::convertToInt(const std::string & str,T & t) {
+      76             :   // First try standard conversion
+      77     2227641 :   if(convertToAny(str,t)) return true;
+      78             :   // Then use lepton
+      79             :   try {
+      80     2008031 :     double r=lepton::Parser::parse(str).evaluate(lepton::Constants());
+      81             : 
+      82             :     // now sanity checks on the resulting number
+      83             : 
+      84             :     // it should not overflow the requested int type:
+      85             :     // (see https://stackoverflow.com/a/526092)
+      86     2008031 :     if(r>std::nextafter(std::numeric_limits<T>::max(), 0)) return false;
+      87     2008031 :     if(r<std::nextafter(std::numeric_limits<T>::min(), 0)) return false;
+      88             : 
+      89             :     // do the actual conversion
+      90     2008031 :     auto tmp=static_cast<T>(std::round(r));
+      91             : 
+      92             :     // it should be *very close* to itself if converted back to double
+      93     2008031 :     double diff= r-static_cast<double>(tmp);
+      94     2008031 :     if(diff*diff > 1e-20) return false;
+      95             :     // this is to accomodate small numerical errors and allow e.g. exp(log(7)) to be integer
+      96             : 
+      97             :     // it should be change if incremented or decremented by one (see https://stackoverflow.com/a/43656140)
+      98     2008027 :     if(r == static_cast<double>(tmp-1)) return false;
+      99     2008026 :     if(r == static_cast<double>(tmp+1)) return false;
+     100             : 
+     101             :     // everything is fine, then store in t
+     102     2008026 :     t=tmp;
+     103     2008026 :     return true;
+     104           0 :   } catch(const PLMD::lepton::Exception& exc) {
+     105             :   }
+     106           0 :   return false;
+     107             : }
+     108             : 
+     109             : 
+     110             : template<class T>
+     111    14034606 : bool Tools::convertToReal(const std::string & str,T & t) {
+     112    14034606 :   if(convertToAny(str,t)) return true;
+     113     8377914 :   if(str=="PI" || str=="+PI" || str=="+pi" || str=="pi") {
+     114     1047281 :     t=pi; return true;
+     115     2094520 :   } else if(str=="-PI" || str=="-pi") {
+     116     1047205 :     t=-pi; return true;
+     117             :   }
+     118             :   try {
+     119          55 :     t=lepton::Parser::parse(str).evaluate(lepton::Constants());
+     120          24 :     return true;
+     121          31 :   } catch(const PLMD::lepton::Exception& exc) {
+     122             :   }
+     123          31 :   if( str.find("PI")!=std::string::npos ) {
+     124           0 :     std::size_t pi_start=str.find_first_of("PI");
+     125           0 :     if(str.substr(pi_start)!="PI") return false;
+     126           0 :     std::istringstream nstr(str.substr(0,pi_start));
+     127           0 :     T ff=0.0; bool ok=static_cast<bool>(nstr>>ff);
+     128           0 :     if(!ok) return false;
+     129           0 :     t=ff*pi;
+     130           0 :     std::string remains; nstr>>remains;
+     131           0 :     return remains.length()==0;
+     132          31 :   } else if( str.find("pi")!=std::string::npos ) {
+     133          15 :     std::size_t pi_start=str.find_first_of("pi");
+     134          30 :     if(str.substr(pi_start)!="pi") return false;
+     135          15 :     std::istringstream nstr(str.substr(0,pi_start));
+     136          15 :     T ff=0.0; bool ok=static_cast<bool>(nstr>>ff);
+     137          15 :     if(!ok) return false;
+     138          15 :     t=ff*pi;
+     139          15 :     std::string remains; nstr>>remains;
+     140          15 :     return remains.length()==0;
+     141          31 :   } else if(str=="NAN") {
+     142           0 :     t=std::numeric_limits<double>::quiet_NaN();
+     143           0 :     return true;
+     144             :   }
+     145             :   return false;
+     146             : }
+     147             : 
+     148           0 : bool Tools::convertNoexcept(const std::string & str,float & t) {
+     149           0 :   return convertToReal(str,t);
+     150             : }
+     151             : 
+     152    14034478 : bool Tools::convertNoexcept(const std::string & str,double & t) {
+     153    14034478 :   return convertToReal(str,t);
+     154             : }
+     155             : 
+     156         128 : bool Tools::convertNoexcept(const std::string & str,long double & t) {
+     157         128 :   return convertToReal(str,t);
+     158             : }
+     159             : 
+     160       78063 : bool Tools::convertNoexcept(const std::string & str,std::string & t) {
+     161             :   t=str;
+     162       78063 :   return true;
+     163             : }
+     164             : 
+     165     3790573 : std::vector<std::string> Tools::getWords(const std::string & line,const char* separators,int * parlevel,const char* parenthesis, const bool& delete_parenthesis) {
+     166     3790573 :   plumed_massert(std::strlen(parenthesis)==1,"multiple parenthesis type not available");
+     167     3790573 :   plumed_massert(parenthesis[0]=='(' || parenthesis[0]=='[' || parenthesis[0]=='{',
+     168             :                  "only ( [ { allowed as parenthesis");
+     169     3790573 :   if(!separators) separators=" \t\n";
+     170     3790573 :   const std::string sep(separators);
+     171     3790573 :   char openpar=parenthesis[0];
+     172             :   char closepar;
+     173             :   if(openpar=='(') closepar=')';
+     174     3790573 :   if(openpar=='[') closepar=']';
+     175     3790573 :   if(openpar=='{') closepar='}';
+     176             :   std::vector<std::string> words;
+     177             :   std::string word;
+     178             :   int parenthesisLevel=0;
+     179     3790573 :   if(parlevel) parenthesisLevel=*parlevel;
+     180   196770165 :   for(unsigned i=0; i<line.length(); i++) {
+     181             :     bool found=false;
+     182             :     bool onParenthesis=false;
+     183   192979592 :     if( (line[i]==openpar || line[i]==closepar) && delete_parenthesis ) onParenthesis=true;
+     184   192979592 :     if(line[i]==closepar) {
+     185        2022 :       parenthesisLevel--;
+     186        2022 :       plumed_massert(parenthesisLevel>=0,"Extra closed parenthesis in '" + line + "'");
+     187             :     }
+     188   772148859 :     if(parenthesisLevel==0) for(unsigned j=0; j<sep.length(); j++) if(line[i]==sep[j]) found=true;
+     189             : // If at parenthesis level zero (outer)
+     190   192979592 :     if(!(parenthesisLevel==0 && (found||onParenthesis))) word.push_back(line[i]);
+     191             :     //if(onParenthesis) word.push_back(' ');
+     192   192979592 :     if(line[i]==openpar) parenthesisLevel++;
+     193   192979592 :     if(found && word.length()>0) {
+     194    11516015 :       if(!parlevel) plumed_massert(parenthesisLevel==0,"Unmatching parenthesis in '" + line + "'");
+     195    11516015 :       words.push_back(word);
+     196             :       word.clear();
+     197             :     }
+     198             :   }
+     199     3790573 :   if(word.length()>0) {
+     200     3673458 :     if(!parlevel) plumed_massert(parenthesisLevel==0,"Unmatching parenthesis in '" + line + "'");
+     201     3673458 :     words.push_back(word);
+     202             :   }
+     203     3790573 :   if(parlevel) *parlevel=parenthesisLevel;
+     204     3790573 :   return words;
+     205           0 : }
+     206             : 
+     207       14560 : bool Tools::getParsedLine(IFile& ifile,std::vector<std::string> & words, bool trimcomments) {
+     208       14560 :   std::string line("");
+     209       14560 :   words.clear();
+     210             :   bool stat;
+     211             :   bool inside=false;
+     212       14560 :   int parlevel=0;
+     213             :   bool mergenext=false;
+     214       31876 :   while((stat=ifile.getline(line))) {
+     215       31098 :     if(trimcomments) trimComments(line);
+     216       31098 :     trim(line);
+     217       31098 :     if(line.length()==0) continue;
+     218       25038 :     std::vector<std::string> w=getWords(line,NULL,&parlevel,"{",trimcomments);
+     219       25038 :     if(!w.empty()) {
+     220       36292 :       if(inside && *(w.begin())=="...") {
+     221             :         inside=false;
+     222        1203 :         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]);
+     223        1203 :         plumed_massert(w.size()<=2,"terminating \"...\" lines cannot consist of more than two words");
+     224        1203 :         w.clear(); if(!trimcomments) words.push_back("...");
+     225       23834 :       } else if(*(w.end()-1)=="...") {
+     226             :         inside=true;
+     227             :         w.erase(w.end()-1);
+     228             :       };
+     229             :       int i0=0;
+     230       25037 :       if(mergenext && words.size()>0 && w.size()>0) {
+     231         128 :         words[words.size()-1]+=" "+w[0];
+     232             :         i0=1;
+     233             :       }
+     234       89698 :       for(unsigned i=i0; i<w.size(); ++i) words.push_back(w[i]);
+     235             :     }
+     236       25038 :     mergenext=(parlevel>0);
+     237       25038 :     if(!inside)break;
+     238       11256 :     if(!trimcomments && parlevel==0) words.push_back("@newline");
+     239       11256 :     else if(!trimcomments) words[words.size()-1] += " @newline";
+     240       25038 :   }
+     241       14560 :   plumed_massert(parlevel==0,"non matching parenthesis");
+     242       14560 :   if(words.size()>0) return true;
+     243             :   return stat;
+     244             : }
+     245             : 
+     246             : 
+     247     2700044 : bool Tools::getline(FILE* fp,std::string & line) {
+     248             :   line="";
+     249             :   const int bufferlength=1024;
+     250             :   char buffer[bufferlength];
+     251             :   bool ret;
+     252  2767545100 :   for(int i=0; i<bufferlength; i++) buffer[i]='\0';
+     253     2700044 :   while((ret=fgets(buffer,bufferlength,fp))) {
+     254     2699321 :     line.append(buffer);
+     255     2699321 :     unsigned ss=std::strlen(buffer);
+     256     2699321 :     if(ss>0) if(buffer[ss-1]=='\n') break;
+     257             :   };
+     258     2700044 :   if(line.length()>0) if(*(line.end()-1)=='\n') line.erase(line.end()-1);
+     259     2700044 :   if(line.length()>0) if(*(line.end()-1)=='\r') line.erase(line.end()-1);
+     260     2700044 :   return ret;
+     261             : }
+     262             : 
+     263      836078 : void Tools::trim(std::string & s) {
+     264      836078 :   size_t n=s.find_last_not_of(" \t");
+     265      836078 :   s=s.substr(0,n+1);
+     266      836078 : }
+     267             : 
+     268     1354472 : void Tools::trimComments(std::string & s) {
+     269     1354472 :   size_t n=s.find_first_of("#");
+     270     1354472 :   s=s.substr(0,n);
+     271     1354472 : }
+     272             : 
+     273      323265 : bool Tools::caseInSensStringCompare(const std::string & str1, const std::string &str2)
+     274             : {
+     275      323265 :   return ((str1.size() == str2.size()) && std::equal(str1.begin(), str1.end(), str2.begin(), [](char c1, char c2) {
+     276      632368 :     return (c1 == c2 || std::toupper(c1) == std::toupper(c2));
+     277      323265 :   }));
+     278             : }
+     279             : 
+     280       90613 : bool Tools::getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep) {
+     281             :   s.clear();
+     282      359857 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     283      323265 :     if((*p).length()==0) continue;
+     284      323265 :     std::string x=(*p).substr(0,key.length());
+     285      323265 :     if(caseInSensStringCompare(x,key)) {
+     286       54021 :       if((*p).length()==key.length())return false;
+     287       54020 :       std::string tmp=(*p).substr(key.length(),(*p).length());
+     288             :       line.erase(p);
+     289             :       s=tmp;
+     290       54020 :       const std::string multi("@replicas:");
+     291       54020 :       if(rep>=0 && startWith(s,multi)) {
+     292          24 :         s=s.substr(multi.length(),s.length());
+     293          24 :         std::vector<std::string> words=getWords(s,"\t\n ,");
+     294          24 :         plumed_massert(rep<static_cast<int>(words.size()),"Number of fields in " + s + " not consistent with number of replicas");
+     295          24 :         s=words[rep];
+     296          24 :       }
+     297             :       return true;
+     298             :     }
+     299             :   };
+     300             :   return false;
+     301             : }
+     302             : 
+     303       11307 : void Tools::interpretRanges(std::vector<std::string>&s) {
+     304             :   std::vector<std::string> news;
+     305       56956 :   for(const auto & p :s) {
+     306       45649 :     news.push_back(p);
+     307       45649 :     size_t dash=p.find("-");
+     308       46260 :     if(dash==std::string::npos) continue;
+     309             :     int first;
+     310        3184 :     if(!Tools::convertToAny(p.substr(0,dash),first)) continue;
+     311         981 :     int stride=1;
+     312             :     int second;
+     313         981 :     size_t colon=p.substr(dash+1).find(":");
+     314         981 :     if(colon!=std::string::npos) {
+     315          63 :       if(!Tools::convertToAny(p.substr(dash+1).substr(0,colon),second) ||
+     316          84 :           !Tools::convertToAny(p.substr(dash+1).substr(colon+1),stride)) continue;
+     317             :     } else {
+     318        1920 :       if(!Tools::convertToAny(p.substr(dash+1),second)) continue;
+     319             :     }
+     320         981 :     news.resize(news.size()-1);
+     321         981 :     if(first<=second) {
+     322         980 :       plumed_massert(stride>0,"interpreting ranges "+ p + ", stride should be positive");
+     323      198399 :       for(int i=first; i<=second; i+=stride) {
+     324             :         std::string ss;
+     325      197419 :         convert(i,ss);
+     326      197419 :         news.push_back(ss);
+     327             :       }
+     328             :     } else {
+     329           1 :       plumed_massert(stride<0,"interpreting ranges "+ p + ", stride should be positive");
+     330           3 :       for(int i=first; i>=second; i+=stride) {
+     331             :         std::string ss;
+     332           2 :         convert(i,ss);
+     333           2 :         news.push_back(ss);
+     334             :       }
+     335             :     }
+     336             :   }
+     337       11307 :   s=news;
+     338       11307 : }
+     339             : 
+     340       14107 : void Tools::interpretLabel(std::vector<std::string>&s) {
+     341       14107 :   if(s.size()<2)return;
+     342       13791 :   std::string s0=s[0];
+     343       13791 :   unsigned l=s0.length();
+     344       13791 :   if(l<1) return;
+     345       13791 :   if(s0[l-1]==':') {
+     346             :     s[0]=s[1];
+     347       21502 :     s[1]="LABEL="+s0.substr(0,l-1);
+     348             :   }
+     349       13791 :   std::transform(s[0].begin(), s[0].end(), s[0].begin(), ::toupper);
+     350             : }
+     351             : 
+     352        5652 : std::vector<std::string> Tools::ls(const std::string&d) {
+     353             :   DIR*dir;
+     354             :   std::vector<std::string> result;
+     355        5652 :   if ((dir=opendir(d.c_str()))) {
+     356             : #if defined(__PLUMED_HAS_READDIR_R)
+     357             :     struct dirent ent;
+     358             : #endif
+     359             :     while(true) {
+     360             :       struct dirent *res;
+     361             : #if defined(__PLUMED_HAS_READDIR_R)
+     362             :       readdir_r(dir,&ent,&res);
+     363             : #else
+     364       88578 :       res=readdir(dir);
+     365             : #endif
+     366       88578 :       if(!res) break;
+     367      403326 :       if(std::string(res->d_name)!="." && std::string(res->d_name)!="..") result.push_back(res->d_name);
+     368             :     }
+     369        5652 :     closedir (dir);
+     370             :   }
+     371        5652 :   return result;
+     372           0 : }
+     373             : 
+     374        4320 : void Tools::stripLeadingAndTrailingBlanks( std::string& str ) {
+     375        4320 :   std::size_t first=str.find_first_not_of(' ');
+     376        4320 :   std::size_t last=str.find_last_not_of(' ');
+     377        8603 :   if( first<=last && first!=std::string::npos) str=str.substr(first,last+1);
+     378        4320 : }
+     379             : 
+     380       11151 : std::string Tools::extension(const std::string&s) {
+     381       11151 :   size_t n=s.find_last_of(".");
+     382             :   std::string ext;
+     383       11151 :   if(n!=std::string::npos && n+1<s.length() && n+5>=s.length()) {
+     384        8138 :     ext=s.substr(n+1);
+     385        8138 :     if(ext.find("/")!=std::string::npos) ext="";
+     386        8138 :     std::string base=s.substr(0,n);
+     387        8138 :     if(base.length()==0) ext="";
+     388        8138 :     if(base.length()>0 && base[base.length()-1]=='/') ext="";
+     389             :   }
+     390       11151 :   return ext;
+     391             : }
+     392             : 
+     393          14 : double Tools::bessel0( const double& val ) {
+     394          14 :   if (std::abs(val)<3.75) {
+     395           2 :     double y = Tools::fastpow( val/3.75, 2 );
+     396           2 :     return 1 + y*(3.5156229 +y*(3.0899424 + y*(1.2067492+y*(0.2659732+y*(0.0360768+y*0.0045813)))));
+     397             :   }
+     398          12 :   double ax=std::abs(val), y=3.75/ax, bx=std::exp(ax)/std::sqrt(ax);
+     399          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)))))));
+     400          12 :   return ax*bx;
+     401             : }
+     402             : 
+     403      876783 : bool Tools::startWith(const std::string & full,const std::string &start) {
+     404      876783 :   return (full.substr(0,start.length())==start);
+     405             : }
+     406             : 
+     407       82463 : bool Tools::findKeyword(const std::vector<std::string>&line,const std::string&key) {
+     408       82463 :   const std::string search(key+"=");
+     409      558849 :   for(const auto & p : line) {
+     410      523600 :     if(startWith(p,search)) return true;
+     411             :   }
+     412             :   return false;
+     413             : }
+     414             : 
+     415         518 : Tools::DirectoryChanger::DirectoryChanger(const char*path) {
+     416         518 :   if(!path) return;
+     417         518 :   if(std::strlen(path)==0) return;
+     418             : #ifdef __PLUMED_HAS_GETCWD
+     419           0 :   char* ret=getcwd(cwd,buffersize);
+     420           0 :   plumed_assert(ret)<<"Name of current directory too long, increase buffer size";
+     421             : #else
+     422             :   plumed_error()<<"You are trying to use DirectoryChanger but your system does not support getcwd";
+     423             : #endif
+     424             : #ifdef __PLUMED_HAS_CHDIR
+     425           0 :   int r=chdir(path);
+     426           0 :   plumed_assert(r==0) <<"Cannot chdir to directory "<<path<<". The directory must exist!";
+     427             : #else
+     428             :   plumed_error()<<"You are trying to use DirectoryChanger but your system does not support chdir";
+     429             : #endif
+     430             : }
+     431             : 
+     432         518 : Tools::DirectoryChanger::~DirectoryChanger() {
+     433             : #ifdef __PLUMED_HAS_CHDIR
+     434         518 :   if(std::strlen(cwd)==0) return;
+     435           0 :   int ret=chdir(cwd);
+     436             : // we cannot put an assertion here (in a destructor) otherwise cppcheck complains
+     437             : // we thus just report the problem
+     438           0 :   if(ret!=0) std::fprintf(stderr,"+++ WARNING: cannot cd back to directory %s\n",cwd);
+     439             : #endif
+     440         518 : }
+     441             : 
+     442             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..822f9c5e30 --- /dev/null +++ b/coverage/tools/Tools.h.func-sort-c.html @@ -0,0 +1,1761 @@ + + + + + + + + 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:596196.7 %
Date:2024-06-10 08:19:14Functions:38842291.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Tools11make_uniqueINS_10SparseGridEJRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISD_EERSB_IS8_SaIS8_EESK_RSB_IjSaIjEERbSO_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_10SparseGridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESI_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar10XDistancesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar11XYDistancesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar15VolumeTetraporeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar16InPlaneDistancesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar16VolumeInEnvelopeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EERbS8_RKNS_3PbcERNS_12CommunicatorERdRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_14manyrestraints6LWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJPS2_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA9_KcdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15crystallization15LocalSteinhardtINS2_2Q3EEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15crystallization15LocalSteinhardtINS2_2Q4EEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15crystallization22InterMolecularTorsionsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15crystallization2Q3EJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15crystallization9VectorSumEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_18DotProductDistanceEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_19MahalanobisDistanceEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_27NormalizedEuclideanDistanceEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsVectorEJRA7_KcRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISD_EERKS7_IjSaIjEERNS_12CommunicatorEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_4isdb7RescaleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_6adjmat20ContactAlignedMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_6colvar8TemplateEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_6dimred9SketchMapEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_6dimred9SmacofMDSEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_7generic15RandomExchangesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_7generic4TimeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_8analysis14LandmarkStagedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_8analysis18SelectRandomFramesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_8function6TargetEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools15convertNoexceptIlEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEfEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIPciEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar16VolumeInCylinderEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar18MultiColvarCombineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar18MultiColvarProductEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar19DistanceFromContourEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar9AlphaBetaEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_12MDAtomsTypedIfEEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_15crystallization11SimpleCubicEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_15crystallization11TetrahedralEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_15crystallization13PolymerAnglesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_18BiasRepresentationEJRSt6vectorIPNS_5ValueESaIS5_EERNS_12CommunicatorERS3_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISG_EESJ_RS3_IjSaIjEERS3_IdSaIdEEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_19IntermolecularDRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_19IntramolecularDRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_23DataFetchingObjectTypedIfEEJRNS_10PlumedMainEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_3ves19Opt_RobbinsMonroSGDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_3ves9Opt_DummyEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4bias13ReweightMetadEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4bias4ABMDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4bias6LWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4maze10Steered_MDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4maze13OptimizerBiasEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4maze19Simulated_AnnealingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4maze22Random_Acceleration_MDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6adjmat10SMACMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6adjmat19ClusterDistributionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6adjmat6SprintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6colvar16ProjectionOnAxisEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6colvar6GHBFIXEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6dimred13SketchMapReadEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6dimred15SketchMapSmacofEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6dimred18SketchMapPointwiseEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_7generic15DumpProjectionsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_7mapping12AdaptivePathEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_8analysis17ReselectLandmarksEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_8analysis21FarthestPointSamplingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_8function15FuncPathGeneralEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_9gridtools11FindContourEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_9gridtools16FourierTransformEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_9gridtools18FindContourSurfaceEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_9gridtools20FindSphericalContourEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_10SubprocessEJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase3MinEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase6AltMinEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar12VolumeCavityEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar19DihedralCorrelationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar6AnglesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar8TorsionsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_14manyrestraints6UWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_15crystallization13MoleculePlaneEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_15crystallization14GradientVesselEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_15crystallization15BondOrientationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_15crystallization8GradientEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_3ves11BF_CombinedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_3ves17TD_MulticanonicalEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_3ves25TD_MultithermalMultibaricEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_3ves8Opt_AdamEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4bias18ExtendedLagrangianEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4bias8ExternalEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4isdb6SelectEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4isdb8SelectorEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4maze11Random_WalkEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4maze7MemeticEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4opes9ECVcustomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4pamm12HBPammMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4pamm15HBPammHydrogensEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4pamm4PAMMEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4sasa10SASA_HASELEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4sasa9SASA_LCPOEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_5fisst5FISSTEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_5setup4LoadEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6adjmat11HBondMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6adjmat15ClusterDiameterEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6adjmat18ClusterWithSurfaceEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6colvar5DimerEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6colvar7ExtraCVEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6colvar7PCARMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6dimred19OutputPCAProjectionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6dimred24ProjectNonLandmarkPointsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_7generic9ResetCellEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_8analysis23ReadDissimilarityMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_8function11FuncPathMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_8function13LocalEnsembleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_9gridtools15InterpolateGridEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_9gridtools9GridToXYZEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase3MaxEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase6LowestEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar13FilterBetweenEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar14VolumeInSphereEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar19CenterOfMultiColvarEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar7XAnglesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar9XYTorsionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_15crystallization2Q4EJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_18secondarystructure9AlphaRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_3ves12BF_GaussiansEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_3ves13OutputFesBiasEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_3ves16BF_CubicBsplinesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_3ves22FermiSwitchingFunctionEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_4bias12ReweightBiasEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_4opes16ECVumbrellasFileEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_5vatom5GhostEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_6colvar9MultiRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_6dimred17SketchMapConjGradEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_6dimred3PCAEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_6logmfd6LogMFDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_7mapping11PropertyMapEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_7mapping23TrigonometricPathVesselEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_8analysis13AverageVesselEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_8analysis7AverageEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_8function9PiecewiseEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar10FilterLessEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar12LocalAverageEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar13NumberOfLinksEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_15crystallization19MoleculeOrientationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_15crystallization7FccubicEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_3ves12BF_ChebyshevEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_3ves21TD_ProductCombinationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_3ves7BF_SineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_3ves9BF_CosineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_3ves9VesDeltaFEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4bias15MovingRestraintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4bias27ReweightTemperaturePressureEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4isdb3PREEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4isdb7CaliberEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4opes9ECVlinearEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_6adjmat13MatrixRowSumsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_6adjmat9DumpGraphEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_6colvar5ERMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_6funnel6FunnelEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools10CompletionEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools10GenExampleEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools11GenTemplateEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools2ktEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools6DriverIfEEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_9gridtools13IntegrateGridEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase7HighestEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_15MultiDomainRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_15crystallization15LocalSteinhardtINS2_2Q6EEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_15crystallization4SMACEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_3ves26TD_GeneralizedExtremeValueEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_6adjmat16MatrixColumnSumsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_6colvar7EEFSolvEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_6funnel9FUNNEL_PSEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_7generic10WrapAroundEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_7mapping7PCAVarsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_8function7annfunc3ANNEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_10SparseGridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESJ_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_15crystallization10VectorMeanEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_3ves19WellTemperedModiferEJRdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_3ves32TD_ExponentiallyModifiedGaussianEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_4isdb9JCouplingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_6adjmat14TopologyMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_7generic5DebugEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_7mapping4PathEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_8analysis11WhamWeightsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_8analysis13OutputPDBFileEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_8analysis13WhamHistogramEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_9gridtools8DumpCubeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar10FilterMoreEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_4RMSDEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_4opes9OPESmetadINS2_11explorationEEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_6dimred32ClassicalMultiDimensionalScalingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_7cltools11PdbRenumberEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_7cltools5PesMDEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_7generic8UpdateIfEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_7mapping11ZpathVesselEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase7MomentsEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar6BridgeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_RbbS8_RKNS_3PbcERNS_12CommunicatorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_18BiasRepresentationEJRSt6vectorIPNS_5ValueESaIS5_EERNS_12CommunicatorERS3_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISG_EESJ_RS3_IjSaIjEERbRdSO_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_3eds3EDSEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_3ves14TD_ExponentialEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_3ves20TD_GeneralizedNormalEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_4maze4LossEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_4opes16ECVumbrellasLineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_6adjmat13OutputClusterEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_6colvar10ContactMapEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_6colvar8DHEnergyEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_7mapping9PathToolsEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_8analysis16SelectWithStrideEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_8analysis24PrintDissimilarityMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_9gridtools13AverageOnGridEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA11_KcRdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_15crystallization21EnvironmentSimilarityEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3drr7drrtoolEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3ves11TD_VonMisesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3ves13TD_ChiSquaredEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3ves6TD_ChiEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3ves7TD_GridEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERKSA_IS8_SaIS8_EESJ_RKSA_IjSaIjEEbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_4opes20ECVmultiThermalBaricEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_5vatom9FixedAtomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_6colvar4CellEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_6colvar6VolumeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_7generic13FitToTemplateEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_7generic20EffectiveEnergyDriftEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_8analysis9CommittorEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_8function12FilesHandlerEJRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EERbRNS2_12FuncSumHillsERNS_3LogEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_8function12FuncSumHillsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_18secondarystructure12ParabetaRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_3ves9BF_CustomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESI_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_7mapping11SpathVesselEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_9DirectionEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase9HistogramEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar18MultiColvarDensityEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar7DensityEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EERbS8_RKNS_3PbcERNS_12CommunicatorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_4isdb3NOEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_4opes15ECVmultiThermalEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_6colvar11PropertyMapEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_18secondarystructure12AntibetaRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_3drr27DynamicReferenceRestrainingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_3piv3PIVEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_3ves20TD_LinearCombinationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_4bias12ReweightWhamEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_6adjmat13ContactMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_6colvar5DRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_7generic14DumpMassChargeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_7generic6PlumedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_8function4SortEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJDnRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_13
_ZN4PLMD5Tools11make_uniqueINS_7cltools14CLToolSumHillsEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_13
_ZN4PLMD5Tools11make_uniqueINS_7cltools8SimpleMDEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_13
_ZN4PLMD5Tools11make_uniqueINS_8analysis28EuclideanDissimilarityMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_13
_ZN4PLMD5Tools11make_uniqueINS_3ves9FesWeightEJdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_4isdb14FretEfficiencyEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_4isdb4SAXSEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_4opes9OPESmetadINS2_11convergenceEEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_6colvar7PathMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11parseVectorIlEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi14
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_bbRbRKNS_3PbcERNS_12CommunicatorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools11make_uniqueINS_15crystallization2Q6EJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools11make_uniqueINS_3ves22TD_ProductDistributionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools11make_uniqueINS_6adjmat13DFSClusteringEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools11make_uniqueINS_9gridtools12ConvertToFESEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmEEvRKT_RT0_15
_ZN4PLMD5Tools11make_uniqueINS_3ves9BF_PowersEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_16
_ZN4PLMD5Tools11make_uniqueINS_3ves9TD_CustomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_16
_ZN4PLMD5Tools5parseImEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i16
_ZN4PLMD5Tools11make_uniqueINS_4bias6UWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_17
_ZN4PLMD5Tools11make_uniqueINS_6colvar10ColvarFakeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_17
_ZN4PLMD5Tools11make_uniqueINS_7generic5FlushEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_17
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElEEvRKT_RT0_17
_ZN4PLMD5Tools11make_uniqueINS_4isdb11CS2BackboneEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_18
_ZN4PLMD5Tools11make_uniqueINS_6colvar5AngleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_18
_ZN4PLMD5Tools11make_uniqueINS_7generic7IncludeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_18
_ZN4PLMD5Tools11make_uniqueINS_4isdb13MetainferenceEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_19
_ZN4PLMD5Tools11make_uniqueINS_5setup5UnitsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_19
_ZN4PLMD5Tools11make_uniqueINS_4isdb4EMMIEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_20
_ZN4PLMD5Tools11make_uniqueINS_8analysis16OutputColvarFileEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_20
_ZN4PLMD5Tools11make_uniqueINS_11FlexibleBinEJRiPNS_4bias5MetaDERdRSt6vectorIdSaIdEESB_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_22
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar12VolumeAroundEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_22
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar15DumpMultiColvarEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_22
_ZN4PLMD5Tools11make_uniqueINS_9gridtools10GridVesselEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_22
_ZN4PLMD5Tools11make_uniqueINS_6adjmat21AdjacencyMatrixVesselEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_23
_ZN4PLMD5Tools11make_uniqueINS_4s2cm14S2ContactModelEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_24
_ZN4PLMD5Tools11make_uniqueINS_6adjmat11ClusterSizeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_24
_ZN4PLMD5Tools11make_uniqueINS_5DRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_26
_ZN4PLMD5Tools11make_uniqueINS_6adjmat17ClusterPropertiesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_27
_ZN4PLMD5Tools11make_uniqueINS_8function8EnsembleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_27
_ZN4PLMD5Tools11make_uniqueINS_7generic10DumpForcesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_28
_ZN4PLMD5Tools11make_uniqueINS_10SimpleRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_29
_ZN4PLMD5Tools11make_uniqueINS_3ves15TD_WellTemperedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_29
_ZN4PLMD5Tools11make_uniqueINS_4isdb3RDCEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_29
_ZN4PLMD5Tools11make_uniqueINS_4opes12OPESexpandedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_30
_ZN4PLMD5Tools11make_uniqueINS_8analysis18ReadAnalysisFramesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_30
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase8MoreThanEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_31
_ZN4PLMD5Tools11make_uniqueINS_8function5StatsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_31
_ZN4PLMD5Tools11parseVectorIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi31
_ZN4PLMD5Tools11make_uniqueINS_4bias9BiasValueEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_32
_ZN4PLMD5Tools11parseVectorIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi32
_ZN4PLMD5Tools11make_uniqueINS_6colvar8GyrationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_33
_ZN4PLMD5Tools11make_uniqueINS_7generic14WholeMoleculesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_33
_ZN4PLMD5Tools11make_uniqueINS_8analysis9HistogramEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_34
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESJ_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_35
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_RbS8_S8_RKNS_3PbcERNS_12CommunicatorERdRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_36
_ZN4PLMD5Tools11make_uniqueINS_3ves9FesWeightEJRKdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_36
_ZN4PLMD5Tools11make_uniqueINS_9gridtools15HistogramOnGridEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_37
_ZN4PLMD5Tools11make_uniqueINS_4bias7PBMetaDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_38
_ZN4PLMD5Tools11make_uniqueINS_6colvar8ConstantEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_39
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsVectorEJRA11_KcSt6vectorIPNS_5ValueESaIS9_EERS7_IPNS2_14BasisFunctionsESaISD_EERNS_12CommunicatorEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_40
_ZN4PLMD5Tools11make_uniqueINS_3ves23LinearBasisSetExpansionEJRA10_KcdRNS_12CommunicatorESt6vectorIPNS_5ValueESaISB_EERS9_IPNS2_14BasisFunctionsESaISF_EEPNS2_12CoeffsVectorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_40
_ZN4PLMD5Tools11make_uniqueINS_6colvar6EnergyEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_40
_ZN4PLMD5Tools11make_uniqueINS_3ves21MD_LinearExpansionPESEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_44
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase12BridgeVesselEJRNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_46
_ZN4PLMD5Tools11make_uniqueINS_3ves11BF_WaveletsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_47
_ZN4PLMD5Tools11make_uniqueINS_9gridtools8DumpGridEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_49
_ZN4PLMD5Tools11make_uniqueINS_4bias6MaxEntEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_50
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar9DistancesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_51
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar19CoordinationNumbersEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_52
_ZN4PLMD5Tools11make_uniqueINS_6colvar6DipoleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_53
_ZN4PLMD5Tools11make_uniqueINS_6colvar9PuckeringEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_54
_ZN4PLMD5Tools11make_uniqueINS_5setup7RestartEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_56
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase3SumEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_57
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase8LessThanEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_59
_ZN4PLMD5Tools11make_uniqueINS_3ves11BF_LegendreEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_61
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase7BetweenEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_65
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISD_EERSB_IS8_SaIS8_EESK_RSB_IjSaIjEERbSO_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_70
_ZN4PLMD5Tools11make_uniqueINS_3ves20OutputBasisFunctionsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_71
_ZN4PLMD5Tools11make_uniqueINS_6colvar4RMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_72
_ZN4PLMD5Tools11make_uniqueINS_3ves10TD_UniformEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_73
_ZN4PLMD5Tools11make_uniqueINS_3ves19Opt_BachAveragedSGDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_75
_ZN4PLMD5Tools10unique2rawINS_3ves12CoeffsMatrixEEESt6vectorIPT_SaIS6_EERKS4_ISt10unique_ptrIS5_St14default_deleteIS5_EESaISC_EE82
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase4MeanEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_83
_ZN4PLMD5Tools11make_uniqueINS_14GenericMolInfoEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_84
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRA8_KcSt6vectorIPNS_5ValueESaIS8_EERS6_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISG_EESJ_RS6_IjSaIjEEbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_85
_ZN4PLMD5Tools11make_uniqueINS_7generic4ReadEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_86
_ZN4PLMD5Tools11make_uniqueINS_6colvar8PositionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_87
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsVectorEJRA7_KcRSt6vectorIPNS_5ValueESaIS9_EERS7_IPNS2_14BasisFunctionsESaISE_EERNS_12CommunicatorEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_3ves18VesLinearExpansionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_3ves23LinearBasisSetExpansionEJRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRNS_12CommunicatorERSt6vectorIPNS_5ValueESaISG_EERSE_IPNS2_14BasisFunctionsESaISL_EEPNS2_12CoeffsVectorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJPNS_7generic4ReadERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_7generic9DumpAtomsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_3ves10BF_FourierEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_95
_ZN4PLMD5Tools11make_uniqueINS_10PlumedMainEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_102
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA9_KcRdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_103
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase15StoreDataVesselEJRNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_105
_ZN4PLMD5Tools5parseIlEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i109
_ZN4PLMD5Tools11make_uniqueINS_7generic5GroupEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_119
_ZN4PLMD5Tools11make_uniqueINS_3ves24OutputTargetDistributionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_120
_ZN4PLMD5Tools11make_uniqueINS_8function7CombineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_137
_ZN4PLMD5Tools11make_uniqueINS_4bias5MetaDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_155
_ZN4PLMD5Tools11make_uniqueIA_fEENS0_10_Unique_ifIT_E14_Unknown_boundEm159
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_RbS8_S8_RKNS_3PbcERNS_12CommunicatorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_171
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsMatrixEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS2_12CoeffsVectorERNS_12CommunicatorERbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_172
_ZN4PLMD5Tools11make_uniqueINS_4bias9RestraintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_178
_ZN4PLMD5Tools11make_uniqueINS_6colvar12CoordinationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_185
_ZN4PLMD5Tools11make_uniqueIA_A3_fEENS0_10_Unique_ifIT_E14_Unknown_boundEm189
_ZN4PLMD5Tools11make_uniqueINS_3ves11TD_GaussianEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_191
_ZN4PLMD5Tools11make_uniqueINS_4GREXEJRNS_10PlumedMainEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_204
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJDnNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_215
_ZN4PLMD5Tools11make_uniqueINS_4GridEJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EERS9_IS8_SaIS8_EESH_RS9_IjSaIjEERbRKbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_220
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJDnRA4_KcbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_227
_ZN4PLMD5Tools11make_uniqueINS_7generic9EndPlumedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_259
_ZN4PLMD5Tools11make_uniqueINS_7generic15DumpDerivativesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_273
_ZN4PLMD5Tools11make_uniqueINS_7cltools6ManualEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_292
_ZN4PLMD5Tools11make_uniqueINS_5IFileEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_341
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRA11_KcRKSt6vectorIPNS_5ValueESaIS8_EERKS6_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISI_EESM_RKS6_IjSaIjEEbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_407
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRA15_KcRKSt6vectorIPNS_5ValueESaIS8_EERKS6_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISI_EESM_RKS6_IjSaIjEEbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_407
_ZN4PLMD5Tools11make_uniqueINS_8function6CustomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_433
_ZN4PLMD5Tools10unique2rawINS_3ves12CoeffsVectorEEESt6vectorIPT_SaIS6_EERKS4_ISt10unique_ptrIS5_St14default_deleteIS5_EESaISC_EE437
_ZN4PLMD5Tools11make_uniqueINS_11OptimalRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_437
_ZN4PLMD5Tools11make_uniqueINS_6colvar8DistanceEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_455
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsVectorEJRS3_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_487
_ZN4PLMD5Tools11parseVectorIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi515
_ZN4PLMD5Tools11make_uniqueINS_6colvar7TorsionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_652
_ZN4PLMD5Tools11make_uniqueINS_7cltools6DriverIdEEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_716
_ZN4PLMD5Tools7convertIPcjEEvRKT_RT0_786
_ZN4PLMD5Tools11make_uniqueINS_7generic5PrintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_793
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_946
_ZN4PLMD5Tools11make_uniqueINS_5OFileEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_969
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RA19_KcRA9_S7_RdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1092
_ZN4PLMD5Tools11make_uniqueINS_7cltools4InfoEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1216
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2307
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_2307
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2373
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_EEvRKT_RT0_2477
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE3186
_ZN4PLMD5Tools11make_uniqueINS_10CLToolMainEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3445
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i3886
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA13_KcRdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4412
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i5252
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_10AtomNumberEEEvRKT_RT0_5760
_ZN4PLMD5Tools11make_uniqueINS_5vatom6CenterEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7161
_ZN4PLMD5Tools11make_uniqueINS_13SubprocessPidEJRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10002
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i12015
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi12429
_ZN4PLMD5Tools15convertNoexceptIdEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20864
_ZN4PLMD5Tools7convertIdNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_20864
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEERKS5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA9_KcdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_21457
_ZN4PLMD5Tools11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RS8_IT_SaISE_EEi21984
_ZN4PLMDL18dp2cutoffNoStretchEv30395
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJPNS_15ActionWithValueERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_33343
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i34297
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb42714
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE90115
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_90115
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE210598
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_210598
_ZN4PLMD5Tools11make_uniqueINS_12MDAtomsTypedIdEEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_405174
_ZN4PLMD5Tools11make_uniqueINS_23DataFetchingObjectTypedIdEEJRNS_10PlumedMainEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_405174
_ZN4PLMD5Tools11make_uniqueINS_17EuclideanDistanceEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_518364
_ZN4PLMD5Tools11make_uniqueIA_cEENS0_10_Unique_ifIT_E14_Unknown_boundEm852843
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2219352
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3560198
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_11689902
_ZN4PLMD5Tools10unique2rawINS_5ValueEEESt6vectorIPT_SaIS5_EERKS3_ISt10unique_ptrIS4_St14default_deleteIS4_EESaISB_EE13702951
_ZN4PLMD5Tools7fastpowEdi79175734
_ZN4PLMD5Tools3pbcEd1820307218
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tools.h.func.html b/coverage/tools/Tools.h.func.html new file mode 100644 index 0000000000..d8d419f111 --- /dev/null +++ b/coverage/tools/Tools.h.func.html @@ -0,0 +1,1761 @@ + + + + + + + + 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:596196.7 %
Date:2024-06-10 08:19:14Functions:38842291.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD5Tools11make_uniqueIA_A3_fEENS0_10_Unique_ifIT_E14_Unknown_boundEm189
_ZN4PLMD5Tools11make_uniqueIA_cEENS0_10_Unique_ifIT_E14_Unknown_boundEm852843
_ZN4PLMD5Tools11make_uniqueIA_fEENS0_10_Unique_ifIT_E14_Unknown_boundEm159
_ZN4PLMD5Tools11make_uniqueINS_10CLToolMainEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3445
_ZN4PLMD5Tools11make_uniqueINS_10PlumedMainEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_102
_ZN4PLMD5Tools11make_uniqueINS_10SimpleRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_29
_ZN4PLMD5Tools11make_uniqueINS_10SparseGridEJRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISD_EERSB_IS8_SaIS8_EESK_RSB_IjSaIjEERbSO_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_10SparseGridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESJ_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_10SparseGridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESI_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_10SubprocessEJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase12BridgeVesselEJRNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_46
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase15StoreDataVesselEJRNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_105
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase3MaxEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase3MinEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase3SumEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_57
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase4MeanEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_83
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase6AltMinEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase6LowestEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase7BetweenEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_65
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase7HighestEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase7MomentsEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase8LessThanEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_59
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase8MoreThanEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_31
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase9HistogramEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_11FlexibleBinEJRiPNS_4bias5MetaDERdRSt6vectorIdSaIdEESB_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_22
_ZN4PLMD5Tools11make_uniqueINS_11OptimalRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_437
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar10FilterLessEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar10FilterMoreEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar10XDistancesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar11XYDistancesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar12LocalAverageEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar12VolumeAroundEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_22
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar12VolumeCavityEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar13FilterBetweenEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar13NumberOfLinksEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar14VolumeInSphereEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar15DumpMultiColvarEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_22
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar15VolumeTetraporeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar16InPlaneDistancesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar16VolumeInCylinderEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar16VolumeInEnvelopeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar18MultiColvarCombineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar18MultiColvarDensityEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar18MultiColvarProductEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar19CenterOfMultiColvarEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar19CoordinationNumbersEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_52
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar19DihedralCorrelationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar19DistanceFromContourEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar6AnglesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar6BridgeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar7DensityEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar7XAnglesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar8TorsionsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar9AlphaBetaEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar9DistancesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_51
_ZN4PLMD5Tools11make_uniqueINS_11multicolvar9XYTorsionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_12MDAtomsTypedIdEEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_405174
_ZN4PLMD5Tools11make_uniqueINS_12MDAtomsTypedIfEEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EERbS8_RKNS_3PbcERNS_12CommunicatorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EERbS8_RKNS_3PbcERNS_12CommunicatorERdRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_RbS8_S8_RKNS_3PbcERNS_12CommunicatorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_171
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_RbS8_S8_RKNS_3PbcERNS_12CommunicatorERdRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_36
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_RbbS8_RKNS_3PbcERNS_12CommunicatorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_bbRbRKNS_3PbcERNS_12CommunicatorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools11make_uniqueINS_13SubprocessPidEJRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10002
_ZN4PLMD5Tools11make_uniqueINS_14GenericMolInfoEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_84
_ZN4PLMD5Tools11make_uniqueINS_14manyrestraints6LWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_14manyrestraints6UWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJPS2_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEERKS5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA9_KcdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_21457
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA9_KcdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RA19_KcRA9_S7_RdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1092
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA11_KcRdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA13_KcRdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4412
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA9_KcRdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_103
_ZN4PLMD5Tools11make_uniqueINS_15MultiDomainRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_15crystallization10VectorMeanEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_15crystallization11SimpleCubicEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_15crystallization11TetrahedralEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_15crystallization13MoleculePlaneEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_15crystallization13PolymerAnglesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_15crystallization14GradientVesselEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_15crystallization15BondOrientationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_15crystallization15LocalSteinhardtINS2_2Q3EEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15crystallization15LocalSteinhardtINS2_2Q4EEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15crystallization15LocalSteinhardtINS2_2Q6EEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_15crystallization19MoleculeOrientationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_15crystallization21EnvironmentSimilarityEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_15crystallization22InterMolecularTorsionsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15crystallization2Q3EJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_15crystallization2Q4EJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_15crystallization2Q6EJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools11make_uniqueINS_15crystallization4SMACEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_15crystallization7FccubicEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_15crystallization8GradientEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_15crystallization9VectorSumEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_17EuclideanDistanceEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_518364
_ZN4PLMD5Tools11make_uniqueINS_18BiasRepresentationEJRSt6vectorIPNS_5ValueESaIS5_EERNS_12CommunicatorERS3_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISG_EESJ_RS3_IjSaIjEERS3_IdSaIdEEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_18BiasRepresentationEJRSt6vectorIPNS_5ValueESaIS5_EERNS_12CommunicatorERS3_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISG_EESJ_RS3_IjSaIjEERbRdSO_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_18DotProductDistanceEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_18secondarystructure12AntibetaRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_18secondarystructure12ParabetaRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_18secondarystructure9AlphaRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_19IntermolecularDRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_19IntramolecularDRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_19MahalanobisDistanceEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_23DataFetchingObjectTypedIdEEJRNS_10PlumedMainEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_405174
_ZN4PLMD5Tools11make_uniqueINS_23DataFetchingObjectTypedIfEEJRNS_10PlumedMainEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_27NormalizedEuclideanDistanceEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_3drr27DynamicReferenceRestrainingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_3drr7drrtoolEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3eds3EDSEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_3piv3PIVEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_3ves10BF_FourierEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_95
_ZN4PLMD5Tools11make_uniqueINS_3ves10TD_UniformEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_73
_ZN4PLMD5Tools11make_uniqueINS_3ves11BF_CombinedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_3ves11BF_LegendreEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_61
_ZN4PLMD5Tools11make_uniqueINS_3ves11BF_WaveletsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_47
_ZN4PLMD5Tools11make_uniqueINS_3ves11TD_GaussianEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_191
_ZN4PLMD5Tools11make_uniqueINS_3ves11TD_VonMisesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3ves12BF_ChebyshevEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_3ves12BF_GaussiansEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsMatrixEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS2_12CoeffsVectorERNS_12CommunicatorERbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_172
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsVectorEJRA11_KcSt6vectorIPNS_5ValueESaIS9_EERS7_IPNS2_14BasisFunctionsESaISD_EERNS_12CommunicatorEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_40
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsVectorEJRA7_KcRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISD_EERKS7_IjSaIjEERNS_12CommunicatorEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsVectorEJRA7_KcRSt6vectorIPNS_5ValueESaIS9_EERS7_IPNS2_14BasisFunctionsESaISE_EERNS_12CommunicatorEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsVectorEJRS3_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_487
_ZN4PLMD5Tools11make_uniqueINS_3ves13OutputFesBiasEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_3ves13TD_ChiSquaredEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3ves14TD_ExponentialEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_3ves15TD_WellTemperedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_29
_ZN4PLMD5Tools11make_uniqueINS_3ves16BF_CubicBsplinesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_3ves17TD_MulticanonicalEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_3ves18VesLinearExpansionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_3ves19Opt_BachAveragedSGDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_75
_ZN4PLMD5Tools11make_uniqueINS_3ves19Opt_RobbinsMonroSGDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_3ves19WellTemperedModiferEJRdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_3ves20OutputBasisFunctionsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_71
_ZN4PLMD5Tools11make_uniqueINS_3ves20TD_GeneralizedNormalEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_3ves20TD_LinearCombinationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_3ves21MD_LinearExpansionPESEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_44
_ZN4PLMD5Tools11make_uniqueINS_3ves21TD_ProductCombinationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_3ves22FermiSwitchingFunctionEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_3ves22TD_ProductDistributionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools11make_uniqueINS_3ves23LinearBasisSetExpansionEJRA10_KcdRNS_12CommunicatorESt6vectorIPNS_5ValueESaISB_EERS9_IPNS2_14BasisFunctionsESaISF_EEPNS2_12CoeffsVectorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_40
_ZN4PLMD5Tools11make_uniqueINS_3ves23LinearBasisSetExpansionEJRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRNS_12CommunicatorERSt6vectorIPNS_5ValueESaISG_EERSE_IPNS2_14BasisFunctionsESaISL_EEPNS2_12CoeffsVectorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_3ves24OutputTargetDistributionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_120
_ZN4PLMD5Tools11make_uniqueINS_3ves25TD_MultithermalMultibaricEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_3ves26TD_GeneralizedExtremeValueEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_3ves32TD_ExponentiallyModifiedGaussianEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_3ves6TD_ChiEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3ves7BF_SineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_3ves7TD_GridEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_3ves8Opt_AdamEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_3ves9BF_CosineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_3ves9BF_CustomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_3ves9BF_PowersEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_16
_ZN4PLMD5Tools11make_uniqueINS_3ves9FesWeightEJRKdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_36
_ZN4PLMD5Tools11make_uniqueINS_3ves9FesWeightEJdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_3ves9Opt_DummyEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_3ves9TD_CustomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_16
_ZN4PLMD5Tools11make_uniqueINS_3ves9VesDeltaFEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4GREXEJRNS_10PlumedMainEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_204
_ZN4PLMD5Tools11make_uniqueINS_4GridEJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EERS9_IS8_SaIS8_EESH_RS9_IjSaIjEERbRKbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_220
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRA11_KcRKSt6vectorIPNS_5ValueESaIS8_EERKS6_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISI_EESM_RKS6_IjSaIjEEbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_407
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRA15_KcRKSt6vectorIPNS_5ValueESaIS8_EERKS6_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISI_EESM_RKS6_IjSaIjEEbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_407
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRA8_KcSt6vectorIPNS_5ValueESaIS8_EERS6_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISG_EESJ_RS6_IjSaIjEEbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_85
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISD_EERSB_IS8_SaIS8_EESK_RSB_IjSaIjEERbSO_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_70
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESJ_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_35
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERKSA_IS8_SaIS8_EESJ_RKSA_IjSaIjEEbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESI_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_4RMSDEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_4bias12ReweightBiasEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_4bias12ReweightWhamEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_4bias13ReweightMetadEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4bias15MovingRestraintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4bias18ExtendedLagrangianEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4bias27ReweightTemperaturePressureEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4bias4ABMDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4bias5MetaDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_155
_ZN4PLMD5Tools11make_uniqueINS_4bias6LWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4bias6MaxEntEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_50
_ZN4PLMD5Tools11make_uniqueINS_4bias6UWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_17
_ZN4PLMD5Tools11make_uniqueINS_4bias7PBMetaDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_38
_ZN4PLMD5Tools11make_uniqueINS_4bias8ExternalEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4bias9BiasValueEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_32
_ZN4PLMD5Tools11make_uniqueINS_4bias9RestraintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_178
_ZN4PLMD5Tools11make_uniqueINS_4isdb11CS2BackboneEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_18
_ZN4PLMD5Tools11make_uniqueINS_4isdb13MetainferenceEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_19
_ZN4PLMD5Tools11make_uniqueINS_4isdb14FretEfficiencyEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_4isdb3NOEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_4isdb3PREEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4isdb3RDCEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_29
_ZN4PLMD5Tools11make_uniqueINS_4isdb4EMMIEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_20
_ZN4PLMD5Tools11make_uniqueINS_4isdb4SAXSEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_4isdb6SelectEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4isdb7CaliberEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4isdb7RescaleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_4isdb8SelectorEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4isdb9JCouplingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_4maze10Steered_MDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4maze11Random_WalkEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4maze13OptimizerBiasEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4maze19Simulated_AnnealingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4maze22Random_Acceleration_MDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_4maze4LossEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_4maze7MemeticEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4opes12OPESexpandedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_30
_ZN4PLMD5Tools11make_uniqueINS_4opes15ECVmultiThermalEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_4opes16ECVumbrellasFileEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_4opes16ECVumbrellasLineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_4opes20ECVmultiThermalBaricEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_4opes9ECVcustomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4opes9ECVlinearEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_4opes9OPESmetadINS2_11convergenceEEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_4opes9OPESmetadINS2_11explorationEEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_4pamm12HBPammMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4pamm15HBPammHydrogensEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4pamm4PAMMEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4s2cm14S2ContactModelEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_24
_ZN4PLMD5Tools11make_uniqueINS_4sasa10SASA_HASELEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_4sasa9SASA_LCPOEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_5DRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_26
_ZN4PLMD5Tools11make_uniqueINS_5IFileEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_341
_ZN4PLMD5Tools11make_uniqueINS_5OFileEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_969
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJDnNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_215
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJDnRA4_KcbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_227
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJDnRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_13
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3560198
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2373
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJPNS_15ActionWithValueERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_33343
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJPNS_7generic4ReadERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_5fisst5FISSTEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_5setup4LoadEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_5setup5UnitsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_19
_ZN4PLMD5Tools11make_uniqueINS_5setup7RestartEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_56
_ZN4PLMD5Tools11make_uniqueINS_5vatom5GhostEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_5vatom6CenterEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7161
_ZN4PLMD5Tools11make_uniqueINS_5vatom9FixedAtomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_6adjmat10SMACMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6adjmat11ClusterSizeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_24
_ZN4PLMD5Tools11make_uniqueINS_6adjmat11HBondMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6adjmat13ContactMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_6adjmat13DFSClusteringEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools11make_uniqueINS_6adjmat13MatrixRowSumsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_6adjmat13OutputClusterEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_6adjmat14TopologyMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_6adjmat15ClusterDiameterEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6adjmat16MatrixColumnSumsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_6adjmat17ClusterPropertiesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_27
_ZN4PLMD5Tools11make_uniqueINS_6adjmat18ClusterWithSurfaceEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6adjmat19ClusterDistributionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6adjmat20ContactAlignedMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_6adjmat21AdjacencyMatrixVesselEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_23
_ZN4PLMD5Tools11make_uniqueINS_6adjmat6SprintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6adjmat9DumpGraphEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_6colvar10ColvarFakeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_17
_ZN4PLMD5Tools11make_uniqueINS_6colvar10ContactMapEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_6colvar11PropertyMapEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_11
_ZN4PLMD5Tools11make_uniqueINS_6colvar12CoordinationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_185
_ZN4PLMD5Tools11make_uniqueINS_6colvar16ProjectionOnAxisEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6colvar4CellEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_6colvar4RMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_72
_ZN4PLMD5Tools11make_uniqueINS_6colvar5AngleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_18
_ZN4PLMD5Tools11make_uniqueINS_6colvar5DRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_6colvar5DimerEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6colvar5ERMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_6colvar6DipoleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_53
_ZN4PLMD5Tools11make_uniqueINS_6colvar6EnergyEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_40
_ZN4PLMD5Tools11make_uniqueINS_6colvar6GHBFIXEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6colvar6VolumeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_6colvar7EEFSolvEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_6colvar7ExtraCVEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6colvar7PCARMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6colvar7PathMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_6colvar7TorsionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_652
_ZN4PLMD5Tools11make_uniqueINS_6colvar8ConstantEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_39
_ZN4PLMD5Tools11make_uniqueINS_6colvar8DHEnergyEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_6colvar8DistanceEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_455
_ZN4PLMD5Tools11make_uniqueINS_6colvar8GyrationEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_33
_ZN4PLMD5Tools11make_uniqueINS_6colvar8PositionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_87
_ZN4PLMD5Tools11make_uniqueINS_6colvar8TemplateEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_6colvar9MultiRMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_6colvar9PuckeringEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_54
_ZN4PLMD5Tools11make_uniqueINS_6dimred13SketchMapReadEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6dimred15SketchMapSmacofEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6dimred17SketchMapConjGradEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_6dimred18SketchMapPointwiseEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_6dimred19OutputPCAProjectionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6dimred24ProjectNonLandmarkPointsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_6dimred32ClassicalMultiDimensionalScalingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_6dimred3PCAEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_6dimred9SketchMapEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_6dimred9SmacofMDSEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_6funnel6FunnelEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_6funnel9FUNNEL_PSEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_6logmfd6LogMFDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_7cltools10CompletionEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools10GenExampleEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools11GenTemplateEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools11PdbRenumberEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_7cltools14CLToolSumHillsEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_13
_ZN4PLMD5Tools11make_uniqueINS_7cltools2ktEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools4InfoEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1216
_ZN4PLMD5Tools11make_uniqueINS_7cltools5PesMDEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_7cltools6DriverIdEEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_716
_ZN4PLMD5Tools11make_uniqueINS_7cltools6DriverIfEEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools6ManualEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_292
_ZN4PLMD5Tools11make_uniqueINS_7cltools8SimpleMDEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_13
_ZN4PLMD5Tools11make_uniqueINS_7generic10DumpForcesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_28
_ZN4PLMD5Tools11make_uniqueINS_7generic10WrapAroundEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_7generic13FitToTemplateEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_7generic14DumpMassChargeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_7generic14WholeMoleculesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_33
_ZN4PLMD5Tools11make_uniqueINS_7generic15DumpDerivativesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_273
_ZN4PLMD5Tools11make_uniqueINS_7generic15DumpProjectionsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_7generic15RandomExchangesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_7generic20EffectiveEnergyDriftEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_7generic4ReadEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_86
_ZN4PLMD5Tools11make_uniqueINS_7generic4TimeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_7generic5DebugEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_7generic5FlushEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_17
_ZN4PLMD5Tools11make_uniqueINS_7generic5GroupEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_119
_ZN4PLMD5Tools11make_uniqueINS_7generic5PrintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_793
_ZN4PLMD5Tools11make_uniqueINS_7generic6PlumedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_7generic7IncludeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_18
_ZN4PLMD5Tools11make_uniqueINS_7generic8UpdateIfEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_7generic9DumpAtomsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_90
_ZN4PLMD5Tools11make_uniqueINS_7generic9EndPlumedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_259
_ZN4PLMD5Tools11make_uniqueINS_7generic9ResetCellEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_7mapping11PropertyMapEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_7mapping11SpathVesselEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_7mapping11ZpathVesselEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_7mapping12AdaptivePathEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_7mapping23TrigonometricPathVesselEJRKNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_7mapping4PathEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_7mapping7PCAVarsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_7mapping9PathToolsEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_8analysis11WhamWeightsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_8analysis13AverageVesselEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_8analysis13OutputPDBFileEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_8analysis13WhamHistogramEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_8analysis14LandmarkStagedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_8analysis16OutputColvarFileEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_20
_ZN4PLMD5Tools11make_uniqueINS_8analysis16SelectWithStrideEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_8analysis17ReselectLandmarksEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_8analysis18ReadAnalysisFramesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_30
_ZN4PLMD5Tools11make_uniqueINS_8analysis18SelectRandomFramesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_8analysis21FarthestPointSamplingEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_8analysis23ReadDissimilarityMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_8analysis24PrintDissimilarityMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_8analysis28EuclideanDissimilarityMatrixEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_13
_ZN4PLMD5Tools11make_uniqueINS_8analysis7AverageEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_8analysis9CommittorEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_8analysis9HistogramEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_34
_ZN4PLMD5Tools11make_uniqueINS_8function11FuncPathMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_8function12FilesHandlerEJRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EERbRNS2_12FuncSumHillsERNS_3LogEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_8function12FuncSumHillsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_9
_ZN4PLMD5Tools11make_uniqueINS_8function13LocalEnsembleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_8function15FuncPathGeneralEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_8function4SortEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_12
_ZN4PLMD5Tools11make_uniqueINS_8function5StatsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_31
_ZN4PLMD5Tools11make_uniqueINS_8function6CustomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_433
_ZN4PLMD5Tools11make_uniqueINS_8function6TargetEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_8function7CombineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_137
_ZN4PLMD5Tools11make_uniqueINS_8function7annfunc3ANNEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_ZN4PLMD5Tools11make_uniqueINS_8function8EnsembleEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_27
_ZN4PLMD5Tools11make_uniqueINS_8function9PiecewiseEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3
_ZN4PLMD5Tools11make_uniqueINS_9DirectionEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_ZN4PLMD5Tools11make_uniqueINS_9gridtools10GridVesselEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_22
_ZN4PLMD5Tools11make_uniqueINS_9gridtools11FindContourEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_9gridtools12ConvertToFESEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_15
_ZN4PLMD5Tools11make_uniqueINS_9gridtools13AverageOnGridEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_9gridtools13IntegrateGridEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_9gridtools15HistogramOnGridEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_37
_ZN4PLMD5Tools11make_uniqueINS_9gridtools15InterpolateGridEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_9gridtools16FourierTransformEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_9gridtools18FindContourSurfaceEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_9gridtools20FindSphericalContourEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_9gridtools8DumpCubeEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_ZN4PLMD5Tools11make_uniqueINS_9gridtools8DumpGridEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_49
_ZN4PLMD5Tools11make_uniqueINS_9gridtools9GridToXYZEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RS8_IT_SaISE_EEi21984
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi12429
_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_EEi515
_ZN4PLMD5Tools11parseVectorIlEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi14
_ZN4PLMD5Tools15convertNoexceptIdEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20864
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE210598
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE90115
_ZN4PLMD5Tools15convertNoexceptIlEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2307
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE3186
_ZN4PLMD5Tools3pbcEd1820307218
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i34297
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i12015
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i5252
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i3886
_ZN4PLMD5Tools5parseIlEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i109
_ZN4PLMD5Tools5parseImEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i16
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_10AtomNumberEEEvRKT_RT0_5760
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_EEvRKT_RT0_2477
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_11689902
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEfEEvRKT_RT0_0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2219352
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_946
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElEEvRKT_RT0_17
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmEEvRKT_RT0_15
_ZN4PLMD5Tools7convertIPciEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIPcjEEvRKT_RT0_786
_ZN4PLMD5Tools7convertIdNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_20864
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_210598
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_90115
_ZN4PLMD5Tools7convertIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_2307
_ZN4PLMD5Tools7fastpowEdi79175734
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb42714
_ZN4PLMDL18dp2cutoffNoStretchEv30395
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tools.h.gcov.html b/coverage/tools/Tools.h.gcov.html new file mode 100644 index 0000000000..c99760caaf --- /dev/null +++ b/coverage/tools/Tools.h.gcov.html @@ -0,0 +1,424 @@ + + + + + + + + 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:596196.7 %
Date:2024-06-10 08:19:14Functions:38842291.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_Tools_h
+      23             : #define __PLUMED_tools_Tools_h
+      24             : 
+      25             : #include "AtomNumber.h"
+      26             : #include <vector>
+      27             : #include <string>
+      28             : #include <cctype>
+      29             : #include <cstdio>
+      30             : #include <cmath>
+      31             : #include <limits>
+      32             : #include <algorithm>
+      33             : #include <sstream>
+      34             : #include <memory>
+      35             : #include <cstddef>
+      36             : 
+      37             : namespace PLMD {
+      38             : 
+      39             : class IFile;
+      40             : 
+      41             : /// \ingroup TOOLBOX
+      42             : /// Very small non-zero number
+      43             : const double epsilon(std::numeric_limits<double>::epsilon());
+      44             : 
+      45             : /// \ingroup TOOLBOX
+      46             : /// Boltzman constant in kj/K
+      47             : const double kBoltzmann(0.0083144621);
+      48             : 
+      49             : /// \ingroup TOOLBOX
+      50             : /// PI
+      51             : const double pi(3.141592653589793238462643383279502884197169399375105820974944592307);
+      52             : 
+      53             : const double dp2cutoff(6.25);
+      54             : 
+      55             : const double dp2cutoffA=1.00193418799744762399; // 1.0/(1-std::exp(-dp2cutoff));
+      56             : const double dp2cutoffB=-.00193418799744762399; // -std::exp(-dp2cutoff)/(1-std::exp(-dp2cutoff));
+      57             : 
+      58       30395 : inline static bool dp2cutoffNoStretch() {
+      59       30395 :   static const auto* res=std::getenv("PLUMED_DP2CUTOFF_NOSTRETCH");
+      60       30395 :   return res;
+      61             : }
+      62             : 
+      63             : /// \ingroup TOOLBOX
+      64             : /// Empty class which just contains several (static) tools
+      65             : class Tools {
+      66             : /// class to convert a string to a generic type T
+      67             :   template<class T>
+      68             :   static bool convertToAny(const std::string & str,T &t);
+      69             : /// class to convert a string to a real type T.
+      70             : /// T should be either float, double, or long double
+      71             :   template<class T>
+      72             :   static bool convertToReal(const std::string & str,T &t);
+      73             : /// class to convert a string to a int type T
+      74             :   template<class T>
+      75             :   static bool convertToInt(const std::string & str,T &t);
+      76             : public:
+      77             : /// Split the line in words using separators.
+      78             : /// It also take into account parenthesis. Outer parenthesis found are removed from
+      79             : /// output, and the text between them is considered as a single word. Only the
+      80             : /// outer parenthesis are processed, to allow nesting them.
+      81             : /// parlevel, if not NULL, is increased or decreased according to the number of opened/closed parenthesis
+      82             :   static std::vector<std::string> getWords(const std::string & line,const char* sep=NULL,int* parlevel=NULL,const char* parenthesis="{", const bool& delete_parenthesis=true);
+      83             : /// Get a line from the file pointer ifile
+      84             :   static bool getline(FILE*,std::string & line);
+      85             : /// Get a parsed line from the file pointer ifile
+      86             : /// This function already takes care of joining continued lines and splitting the
+      87             : /// resulting line into an array of words
+      88             :   static bool getParsedLine(IFile&ifile,std::vector<std::string> & line, const bool trimcomments=true);
+      89             : /// compare two string in a case insensitive manner
+      90             :   static bool caseInSensStringCompare(const std::string & str1, const std::string &str2);
+      91             : /// Convert a string to a double, reading it
+      92             :   static bool convertNoexcept(const std::string & str,double & t);
+      93             : /// Convert a string to a long double, reading it
+      94             :   static bool convertNoexcept(const std::string & str,long double & t);
+      95             : /// Convert a string to a float, reading it
+      96             :   static bool convertNoexcept(const std::string & str,float & t);
+      97             : /// Convert a string to a int, reading it
+      98             :   static bool convertNoexcept(const std::string & str,int & t);
+      99             : /// Convert a string to a long int, reading it
+     100             :   static bool convertNoexcept(const std::string & str,long int & t);
+     101             : /// Convert a string to an unsigned int, reading it
+     102             :   static bool convertNoexcept(const std::string & str,unsigned & t);
+     103             : /// Convert a string to a long unsigned int, reading it
+     104             :   static bool convertNoexcept(const std::string & str,long unsigned & t);
+     105             : /// Convert a string to a atom number, reading it
+     106             :   static bool convertNoexcept(const std::string & str,AtomNumber & t);
+     107             : /// Convert a string to a string (i.e. copy)
+     108             :   static bool convertNoexcept(const std::string & str,std::string & t);
+     109             : /// Convert anything into a string
+     110             :   template<typename T>
+     111             :   static bool convertNoexcept(T i,std::string & str);
+     112             : /// Convert anything into anything, throwing an exception in case there is an error
+     113             : /// Remove trailing blanks
+     114             :   static void trim(std::string & s);
+     115             : /// Remove trailing comments
+     116             :   static void trimComments(std::string & s);
+     117             : /// Apply pbc for a unitary cell
+     118             :   static double pbc(double);
+     119             : /// Retrieve a key from a vector of options.
+     120             : /// It finds a key starting with "key=" or equal to "key" and copy the
+     121             : /// part after the = on s. E.g.:
+     122             : /// line.push_back("aa=xx");
+     123             : /// getKey(line,"aa",s);
+     124             : /// will set s="xx"
+     125             :   static bool getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep=-1);
+     126             : /// Find a keyword on the input line, eventually deleting it, and saving its value to val
+     127             :   template <typename T,typename U>
+     128    14243139 :   static void convert(const T & t,U & u) {
+     129    14243926 :     plumed_assert(convertNoexcept(t,u)) <<"Error converting  "<<t;
+     130    14243138 :   }
+     131             :   template <typename T>
+     132             :   static bool parse(std::vector<std::string>&line,const std::string&key,T&val,int rep=-1);
+     133             : /// Find a keyword on the input line, eventually deleting it, and saving its value to a vector
+     134             :   template <class T>
+     135             :   static bool parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep=-1);
+     136             : /// Find a keyword without arguments on the input line
+     137             :   static bool parseFlag(std::vector<std::string>&line,const std::string&key,bool&val);
+     138             : /// Find a keyword on the input line, just reporting if it exists or not
+     139             :   static bool findKeyword(const std::vector<std::string>&line,const std::string&key);
+     140             : /// Interpret atom ranges
+     141             :   static void interpretRanges(std::vector<std::string>&);
+     142             : /// Remove duplicates from a vector of type T
+     143             :   template <typename T>
+     144             :   static void removeDuplicates(std::vector<T>& vec);
+     145             : /// interpret ":" syntax for labels
+     146             :   static void interpretLabel(std::vector<std::string>&s);
+     147             : /// list files in a directory
+     148             :   static std::vector<std::string> ls(const std::string&);
+     149             : /// removes leading and trailing blanks from a string
+     150             :   static void stripLeadingAndTrailingBlanks( std::string& str );
+     151             : /// Extract the extensions from a file name.
+     152             : /// E.g.: extension("pippo.xyz")="xyz".
+     153             : /// It only returns extensions with a length between 1 and 4
+     154             : /// E.g.: extension("pippo.12345")="" whereas extenion("pippo.1234")="1234";
+     155             : /// It is also smart enough to detect "/", so that
+     156             : /// extension("pippo/.t")="" whereas extension("pippo/a.t")="t"
+     157             :   static std::string extension(const std::string&);
+     158             : /// Fast int power
+     159             :   static double fastpow(double base,int exp);
+     160             : /// Modified 0th-order Bessel function of the first kind
+     161             :   static double bessel0(const double& val);
+     162             : /// Check if a string full starts with string start.
+     163             : /// Same as full.find(start)==0
+     164             :   static bool startWith(const std::string & full,const std::string &start);
+     165             :   /**
+     166             :     Tool to create a vector of raw pointers from a vector of unique_pointers (const version).
+     167             :   Returning a vector is fast in C++11. It can be used in order to feed a vector<unique_ptr<T>>
+     168             :   to a function that takes a vector<T*>.
+     169             :   \verbatim
+     170             :   // some function that takes a vec
+     171             :   void func(std::vector<Data*> & vec);
+     172             :   std::vector<std::unique_ptr<Data>> vec;
+     173             :   // func(vec); // does not compile
+     174             :   func(Tools::unique2raw(vec)); // compiles
+     175             :   \endverbatim
+     176             :   Notice that the conversion is fast but takes
+     177             :   some time to allocate the new vector and copy the pointers. In case the function
+     178             :   acting on the vector<T*> is very fast and we do not want to add significant overhead,
+     179             :   it might be convenient to store a separate set of raw pointers.
+     180             :   \verbatim
+     181             :   // some function that takes a vec
+     182             :   void func(std::vector<Data*> & vec);
+     183             :   std::vector<std::unique_ptr<Data>> vec;
+     184             : 
+     185             :   // conversion done only once:
+     186             :   auto vec_ptr=Tools::unique2raw(vec);
+     187             : 
+     188             :   for(int i=0;i<1000;i++){
+     189             :     func(vec_ptr);
+     190             :   }
+     191             :   \endverbatim
+     192             :   */
+     193             :   template <typename T>
+     194             :   static std::vector<T*> unique2raw(const std::vector<std::unique_ptr<T>>&);
+     195             : /// Tool to create a vector of raw pointers from a vector of unique_pointers.
+     196             : /// See the non const version.
+     197             :   template <typename T>
+     198             :   static std::vector<const T*> unique2raw(const std::vector<std::unique_ptr<const T>>&);
+     199             : /// Tiny class that changes directory and comes back when going out of scope.
+     200             : /// In case system calls to change dir are not available it throws an exception.
+     201             : /// \warning By construction, changing directory breaks thread safety! Use with care.
+     202             :   class DirectoryChanger {
+     203             :     static const std::size_t buffersize=4096;
+     204             :     char cwd[buffersize]= {0};
+     205             :   public:
+     206             :     explicit DirectoryChanger(const char*path);
+     207             :     ~DirectoryChanger();
+     208             :   };
+     209             : /// Mimic C++14 std::make_unique
+     210             :   template<class T> struct _Unique_if {
+     211             :     typedef std::unique_ptr<T> _Single_object;
+     212             :   };
+     213             :   template<class T> struct _Unique_if<T[]> {
+     214             :     typedef std::unique_ptr<T[]> _Unknown_bound;
+     215             :   };
+     216             :   template<class T, std::size_t N> struct _Unique_if<T[N]> {
+     217             :     typedef void _Known_bound;
+     218             :   };
+     219             :   template<class T, class... Args>
+     220             :   static typename _Unique_if<T>::_Single_object
+     221     4987385 :   make_unique(Args&&... args) {
+     222     8581959 :     return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+     223             :   }
+     224             :   template<class T>
+     225             :   static typename _Unique_if<T>::_Unknown_bound
+     226      853191 :   make_unique(std::size_t n) {
+     227             :     typedef typename std::remove_extent<T>::type U;
+     228   426515820 :     return std::unique_ptr<T>(new U[n]());
+     229             :   }
+     230             :   template<class T, class... Args>
+     231             :   static typename _Unique_if<T>::_Known_bound
+     232             :   make_unique(Args&&...) = delete;
+     233             : };
+     234             : 
+     235             : template <class T>
+     236       55575 : bool Tools::parse(std::vector<std::string>&line,const std::string&key,T&val,int rep) {
+     237             :   std::string s;
+     238      111150 :   if(!getKey(line,key+"=",s,rep)) return false;
+     239       28048 :   if(s.length()>0 && !convertNoexcept(s,val))return false;
+     240             :   return true;
+     241             : }
+     242             : 
+     243             : template <class T>
+     244       35005 : bool Tools::parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep) {
+     245             :   std::string s;
+     246       70010 :   if(!getKey(line,key+"=",s,rep)) return false;
+     247       16271 :   val.clear();
+     248       25939 :   std::vector<std::string> words=getWords(s,"\t\n ,");
+     249      113132 :   for(unsigned i=0; i<words.size(); ++i) {
+     250             :     T v;
+     251       87193 :     std::string s=words[i];
+     252       87193 :     const std::string multi("@replicas:");
+     253       87193 :     if(rep>=0 && startWith(s,multi)) {
+     254           6 :       s=s.substr(multi.length(),s.length());
+     255           6 :       std::vector<std::string> words=getWords(s,"\t\n ,");
+     256           6 :       plumed_assert(rep<static_cast<int>(words.size()));
+     257           6 :       s=words[rep];
+     258           6 :     }
+     259       87193 :     if(!convertNoexcept(s,v))return false;
+     260       87193 :     val.push_back(v);
+     261             :   }
+     262             :   return true;
+     263       25939 : }
+     264             : 
+     265             : template<typename T>
+     266        3186 : void Tools::removeDuplicates(std::vector<T>& vec)
+     267             : {
+     268        3186 :   std::sort(vec.begin(), vec.end());
+     269        3186 :   vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
+     270        3186 : }
+     271             : 
+     272             : inline
+     273       42714 : bool Tools::parseFlag(std::vector<std::string>&line,const std::string&key,bool&val) {
+     274      103986 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     275       62760 :     if(key==*p) {
+     276        1488 :       val=true;
+     277             :       line.erase(p);
+     278             :       return true;
+     279             :     }
+     280             :   }
+     281             :   return false;
+     282             : }
+     283             : 
+     284             : /// beware: this brings any number into a pbc that ranges from -0.5 to 0.5
+     285             : inline
+     286  1820307218 : double Tools::pbc(double x) {
+     287             : #ifdef __PLUMED_PBC_WHILE
+     288             :   while (x>0.5) x-=1.0;
+     289             :   while (x<-0.5) x+=1.0;
+     290             :   return x;
+     291             : #else
+     292             :   if(std::numeric_limits<int>::round_style == std::round_toward_zero) {
+     293             :     const double offset=100.0;
+     294  1820307218 :     const double y=x+offset;
+     295  1820307218 :     if(y>=0) return y-int(y+0.5);
+     296        4577 :     else     return y-int(y-0.5);
+     297             :   } else if(std::numeric_limits<int>::round_style == std::round_to_nearest) {
+     298             :     return x-int(x);
+     299             :   } else return x-floor(x+0.5);
+     300             : #endif
+     301             : }
+     302             : 
+     303             : template<typename T>
+     304      323884 : bool Tools::convertNoexcept(T i,std::string & str) {
+     305      323884 :   std::ostringstream ostr;
+     306      210598 :   ostr<<i;
+     307      323884 :   str=ostr.str();
+     308      323884 :   return true;
+     309      323884 : }
+     310             : 
+     311             : inline
+     312    79175734 : double Tools::fastpow(double base, int exp)
+     313             : {
+     314    79175734 :   if(exp<0) {
+     315           0 :     exp=-exp;
+     316           0 :     base=1.0/base;
+     317             :   }
+     318             :   double result = 1.0;
+     319   375014649 :   while (exp)
+     320             :   {
+     321   262238721 :     if (exp & 1)
+     322   181137188 :       result *= base;
+     323   262238721 :     exp >>= 1;
+     324   262238721 :     base *= base;
+     325             :   }
+     326             : 
+     327    79175734 :   return result;
+     328             : }
+     329             : 
+     330             : template<typename T>
+     331    13703470 : std::vector<T*> Tools::unique2raw(const std::vector<std::unique_ptr<T>> & x) {
+     332    13703470 :   std::vector<T*> v(x.size());
+     333    52721172 :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
+     334    13703470 :   return v;
+     335             : }
+     336             : 
+     337             : template<typename T>
+     338             : std::vector<const T*> Tools::unique2raw(const std::vector<std::unique_ptr<const T>> & x) {
+     339             :   std::vector<const T*> v(x.size());
+     340             :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
+     341             :   return v;
+     342             : }
+     343             : 
+     344             : }
+     345             : 
+     346             : #endif
+     347             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..d65da2211b --- /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-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1084670
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Torsion.cpp.func.html b/coverage/tools/Torsion.cpp.func.html new file mode 100644 index 0000000000..c0ddafdad1 --- /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-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1084670
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Torsion.cpp.gcov.html b/coverage/tools/Torsion.cpp.gcov.html new file mode 100644 index 0000000000..666fc85582 --- /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-06-10 08:19:14Functions: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     1084670 : double Torsion::compute(const Vector& v1,const Vector& v2,const Vector& v3,Vector& d1,Vector& d2,Vector& d3)const {
+      40             : 
+      41     1084670 :   const double modv2(1./v2.modulo());
+      42     1084670 :   const Vector nv2(v2*modv2);
+      43     1084670 :   const Tensor dnv2_v2((Tensor::identity()-extProduct(nv2,nv2))*modv2);
+      44             : 
+      45     1084670 :   const Vector a(crossProduct(v2,v1));
+      46     1084670 :   const Tensor da_dv2(dcrossDv1(v2,v1));
+      47     1084670 :   const Tensor da_dv1(dcrossDv2(v2,v1));
+      48     1084670 :   const Vector b(crossProduct(v3,v2));
+      49     1084670 :   const Tensor db_dv3(dcrossDv1(v3,v2));
+      50     1084670 :   const Tensor db_dv2(dcrossDv2(v3,v2));
+      51     1084670 :   const double cosangle=dotProduct(a,b);
+      52     1084670 :   const Vector dcosangle_dv1=matmul(b,da_dv1);
+      53     1084670 :   const Vector dcosangle_dv2=matmul(b,da_dv2) + matmul(a,db_dv2);
+      54     1084670 :   const Vector dcosangle_dv3=matmul(a,db_dv3);
+      55             : 
+      56     1084670 :   const Vector cab(crossProduct(a,b));
+      57     1084670 :   const Tensor dcab_dv1(matmul(dcrossDv1(a,b),da_dv1));
+      58     1084670 :   const Tensor dcab_dv2(matmul(dcrossDv1(a,b),da_dv2) + matmul(dcrossDv2(a,b),db_dv2));
+      59     1084670 :   const Tensor dcab_dv3(matmul(dcrossDv2(a,b),db_dv3));
+      60             : 
+      61     1084670 :   const double sinangle=dotProduct(cab,nv2);
+      62     1084670 :   const Vector dsinangle_dv1=matmul(nv2,dcab_dv1);
+      63     1084670 :   const Vector dsinangle_dv2=matmul(nv2,dcab_dv2)+matmul(cab,dnv2_v2);
+      64     1084670 :   const Vector dsinangle_dv3=matmul(nv2,dcab_dv3);
+      65             : 
+      66     1084670 :   const double torsion=std::atan2(-sinangle,cosangle);
+      67             : // this is required since v1 and v3 are not normalized:
+      68     1084670 :   const double invR2=1.0/(cosangle*cosangle+sinangle*sinangle);
+      69             : 
+      70     1084670 :   d1= ( -dsinangle_dv1*cosangle + sinangle * dcosangle_dv1 ) *invR2;
+      71     1084670 :   d2= ( -dsinangle_dv2*cosangle + sinangle * dcosangle_dv2 ) *invR2;
+      72     1084670 :   d3= ( -dsinangle_dv3*cosangle + sinangle * dcosangle_dv3 ) *invR2;
+      73             : 
+      74     1084670 :   return torsion;
+      75             : }
+      76             : 
+      77             : }
+      78             : 
+      79             : 
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..54e5ce8530 --- /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:0370.0 %
Date:2024-06-10 08:19:14Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4Tree7getTreeESt6vectorINS_10AtomNumberESaIS2_EE0
_ZN4PLMD4TreeC2EPNS_14GenericMolInfoE0
_ZNK4PLMD4Tree7getRootEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tree.cpp.func.html b/coverage/tools/Tree.cpp.func.html new file mode 100644 index 0000000000..8b193ce9a3 --- /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:0370.0 %
Date:2024-06-10 08:19:14Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4Tree7getTreeESt6vectorINS_10AtomNumberESaIS2_EE0
_ZN4PLMD4TreeC2EPNS_14GenericMolInfoE0
_ZNK4PLMD4Tree7getRootEv0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tree.cpp.gcov.html b/coverage/tools/Tree.cpp.gcov.html new file mode 100644 index 0000000000..773d847b18 --- /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:0370.0 %
Date:2024-06-10 08:19:14Functions:030.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           0 : Tree::Tree(GenericMolInfo* moldat) {
+      34             : // initialize class
+      35           0 :   moldat_ = moldat;
+      36             : // check if molinfo present
+      37           0 :   if(!moldat_) plumed_merror("MOLINFO DATA not found");
+      38             : // check if reference structure is whole
+      39           0 :   if(!moldat_->isWhole()) plumed_merror("Check that reference structure in PDB file is not broken by pbc and set WHOLE in MOLINFO line");
+      40           0 : }
+      41             : 
+      42           0 : 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           0 :   root_.clear();
+      51             : 
+      52             :   // remove atoms not in PDB file
+      53             :   std::vector<AtomNumber> addtotree, addtoroot;
+      54             :   std::vector<AtomNumber> newatoms;
+      55           0 :   newatoms.reserve(atoms.size());
+      56           0 :   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           0 :   newatoms.push_back(atoms[0]);
+      59           0 :   for(unsigned i=1; i<atoms.size(); ++i) {
+      60           0 :     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           0 :       newatoms.push_back(atoms[i]);
+      67             :     }
+      68             :   }
+      69             :   // reassign atoms
+      70           0 :   atoms=newatoms;
+      71             :   // start EMST
+      72           0 :   std::vector<bool> intree(atoms.size(), false);
+      73           0 :   std::vector<double> mindist(atoms.size(), std::numeric_limits<double>::max());
+      74             :   // initialize tree with first atom
+      75           0 :   mindist[0] = 0.0;
+      76             :   // loops
+      77           0 :   for(unsigned i=0; i<atoms.size(); ++i) {
+      78             :     int selected_vertex = -1;
+      79           0 :     for(unsigned j=0; j<atoms.size(); ++j) {
+      80           0 :       if( !intree[j] && (selected_vertex==-1 || mindist[j] < mindist[selected_vertex]) )
+      81           0 :         selected_vertex = j;
+      82             :     }
+      83             :     // add to tree
+      84           0 :     plumed_assert(selected_vertex>=0);
+      85           0 :     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           0 :     for(unsigned j=0; j<atoms.size(); ++j) {
+      91           0 :       double dist = delta(moldat_->getPosition(atoms[selected_vertex]), moldat_->getPosition(atoms[j])).modulo2();
+      92           0 :       if(dist < mindist[j]) mindist[j] = dist;
+      93           0 :       if(dist < minroot && intree[j] && dist>0.0) {
+      94             :         minroot = dist;
+      95           0 :         iroot = j;
+      96             :       }
+      97             :     }
+      98             :     // add to root vector
+      99           0 :     if(iroot>=0) root_.push_back(atoms[iroot]);
+     100             :   }
+     101             : 
+     102             :   // now re-add atoms not present in the PDB
+     103           0 :   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           0 :   return tree;
+     110             : }
+     111             : 
+     112           0 : std::vector<AtomNumber> Tree::getRoot() const
+     113             : {
+     114           0 :   return root_;
+     115             : }
+     116             : 
+     117             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..362bb1d11f --- /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:010.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tree.h.func.html b/coverage/tools/Tree.h.func.html new file mode 100644 index 0000000000..8cdae28f04 --- /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:010.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Tree.h.gcov.html b/coverage/tools/Tree.h.gcov.html new file mode 100644 index 0000000000..c70b7ee25f --- /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:010.0 %
Date:2024-06-10 08:19:14Functions: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           0 : 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.15
+
+ + + 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 0000000000..e2a499ce01 --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev8
_ZN4PLMD11TypesafePtr11fromSafePtrEPv12501
_ZNK4PLMD11TypesafePtr4copyEv506687
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.func.html b/coverage/tools/TypesafePtr.cpp.func.html new file mode 100644 index 0000000000..596448943d --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr11fromSafePtrEPv12501
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev8
_ZNK4PLMD11TypesafePtr4copyEv506687
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.gcov.html b/coverage/tools/TypesafePtr.cpp.gcov.html new file mode 100644 index 0000000000..35b4dbc6ea --- /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-06-10 08:19:14Functions: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       12501 : TypesafePtr TypesafePtr::fromSafePtr(void* safe) {
+      30             :   auto s=(plumed_safeptr_x*)safe;
+      31       12501 :   return TypesafePtr(const_cast<void*>(s->ptr), s->nelem, s->shape, s->flags);
+      32             : }
+      33             : 
+      34      506687 : TypesafePtr TypesafePtr::copy() const {
+      35      506687 :   auto passbyvalue=((flags>>25)&0x7)==1;
+      36      506687 :   if(passbyvalue) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object passed by value";
+      37      506687 :   auto forbidstore=flags&0x10000000;
+      38      506687 :   if(forbidstore) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object for which this was forbidden";
+      39             :   TypesafePtr ret;
+      40      506687 :   ret.ptr=ptr;
+      41      506687 :   ret.flags=flags;
+      42      506687 :   ret.nelem=nelem;
+      43      506687 :   ret.shape=shape;
+      44      506687 :   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.15
+
+ + + 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 0000000000..f799ef8936 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func-sort-c.html @@ -0,0 +1,281 @@ + + + + + + + + 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:11413087.7 %
Date:2024-06-10 08:19:14Functions:405276.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtrC2EfmPKm0
_ZN4PLMD17typesafePtrSizeofI8_IO_FILEEEmv0
_ZN4PLMD17typesafePtrSizeofIKfEEmv0
_ZN4PLMD17typesafePtrSizeofIKjEEmv0
_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
_ZNK4PLMD11TypesafePtr8get_privIKfEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKjEEPT_mPKmb0
_ZN4PLMD17typesafePtrSizeofIfEEmv1
_ZNK4PLMD11TypesafePtr3setIfEEvT_1
_ZNK4PLMD11TypesafePtr8get_privIfEEPT_mPKmb1
_ZNK4PLMD11TypesafePtr8type_strB5cxx11Ev5
_ZN4PLMD11TypesafePtrC2EOS0_64
_ZN4PLMD17typesafePtrSizeofIlEEmv64
_ZNK4PLMD11TypesafePtr3setIlEEvT_64
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb64
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb759
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1711
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb1896
_ZN4PLMD11TypesafePtrC2EimPKm2743
_ZN4PLMD11TypesafePtrC2EdmPKm2853
_ZNK4PLMD11TypesafePtr3setIdEEvT_3004
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb3441
_ZNK4PLMD11TypesafePtr3setIiEEvT_3745
_ZN4PLMD17typesafePtrSizeofIKcEEmv5262
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv12910
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv17281
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb18269
_ZN4PLMD17typesafePtrSizeofIKiEEmv18311
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv47497
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listImE115259
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv132522
_ZN4PLMD17typesafePtrSizeofIdEEmv165678
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb165867
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listImE178161
_ZN4PLMD11TypesafePtrC2ElmPKm237805
_ZN4PLMD17typesafePtrSizeofIKlEEmv237805
_ZNK4PLMD11TypesafePtr3getIlEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv237805
_ZNK4PLMD11TypesafePtr8get_privIKlEEPT_mPKmb237805
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv245643
_ZN4PLMD17typesafePtrSizeofIiEEmv249381
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb249388
_ZN4PLMD17typesafePtrSizeofIKdEEmv320863
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb325164
_ZN4PLMD11TypesafePtraSEOS0_791537
_ZN4PLMDL20typesafePtrSkipCheckEv1004481
_ZN4PLMD11TypesafePtr10init_shapeEPKm1015683
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.func.html b/coverage/tools/TypesafePtr.h.func.html new file mode 100644 index 0000000000..6ed82528cb --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func.html @@ -0,0 +1,281 @@ + + + + + + + + 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:11413087.7 %
Date:2024-06-10 08:19:14Functions:405276.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr10init_shapeEPKm1015683
_ZN4PLMD11TypesafePtrC2EOS0_64
_ZN4PLMD11TypesafePtrC2EdmPKm2853
_ZN4PLMD11TypesafePtrC2EfmPKm0
_ZN4PLMD11TypesafePtrC2EimPKm2743
_ZN4PLMD11TypesafePtrC2ElmPKm237805
_ZN4PLMD11TypesafePtraSEOS0_791537
_ZN4PLMD17typesafePtrSizeofI8_IO_FILEEEmv0
_ZN4PLMD17typesafePtrSizeofIKcEEmv5262
_ZN4PLMD17typesafePtrSizeofIKdEEmv320863
_ZN4PLMD17typesafePtrSizeofIKfEEmv0
_ZN4PLMD17typesafePtrSizeofIKiEEmv18311
_ZN4PLMD17typesafePtrSizeofIKjEEmv0
_ZN4PLMD17typesafePtrSizeofIKlEEmv237805
_ZN4PLMD17typesafePtrSizeofIdEEmv165678
_ZN4PLMD17typesafePtrSizeofIfEEmv1
_ZN4PLMD17typesafePtrSizeofIiEEmv249381
_ZN4PLMD17typesafePtrSizeofIlEEmv64
_ZN4PLMDL20typesafePtrSkipCheckEv1004481
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv132522
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listImE178161
_ZNK4PLMD11TypesafePtr3getIPKfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPKfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv47497
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listImE115259
_ZNK4PLMD11TypesafePtr3getIPfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv245643
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv12910
_ZNK4PLMD11TypesafePtr3getIfEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv17281
_ZNK4PLMD11TypesafePtr3getIjEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIlEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv237805
_ZNK4PLMD11TypesafePtr3setIdEEvT_3004
_ZNK4PLMD11TypesafePtr3setIfEEvT_1
_ZNK4PLMD11TypesafePtr3setIiEEvT_3745
_ZNK4PLMD11TypesafePtr3setIlEEvT_64
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb759
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb3441
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb1896
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb325164
_ZNK4PLMD11TypesafePtr8get_privIKfEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb18269
_ZNK4PLMD11TypesafePtr8get_privIKjEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKlEEPT_mPKmb237805
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1711
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb165867
_ZNK4PLMD11TypesafePtr8get_privIfEEPT_mPKmb1
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb249388
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb64
_ZNK4PLMD11TypesafePtr8type_strB5cxx11Ev5
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.gcov.html b/coverage/tools/TypesafePtr.h.gcov.html new file mode 100644 index 0000000000..d2fc1b1bfa --- /dev/null +++ b/coverage/tools/TypesafePtr.h.gcov.html @@ -0,0 +1,476 @@ + + + + + + + + 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:11413087.7 %
Date:2024-06-10 08:19:14Functions:405276.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     1004481 : static inline bool typesafePtrSkipCheck() {
+      42     1004481 :   static const bool ret=std::getenv("PLUMED_TYPESAFE_IGNORE");
+      43     1004481 :   return ret;
+      44             : }
+      45             : 
+      46             : template<class T>
+      47      997365 : std::size_t typesafePtrSizeof() {
+      48      997365 :   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     1015683 :   inline void init_shape(const std::size_t* shape) {
+      70     1015683 :     this->shape[0]=0;
+      71     1015683 :     if(shape && *shape>0) {
+      72             :       std::size_t nelem_=1;
+      73             :       unsigned i=0;
+      74         812 :       for(i=0; i<this->shape.size(); i++) {
+      75         812 :         this->shape[i]=*shape;
+      76         812 :         if(*shape==0) break;
+      77         464 :         nelem_*=*shape;
+      78         464 :         shape++;
+      79             :       }
+      80         348 :       plumed_assert(i<this->shape.size()); // check that last element is actually zero
+      81         348 :       if(nelem==0) nelem=nelem_;
+      82         348 :       plumed_assert(nelem==nelem_) << "Inconsistent shape/nelem";
+      83             :     }
+      84     1015683 :   }
+      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      239070 :     ptr(ptr),
+      92      239070 :     nelem(nelem),
+      93      239070 :     flags(flags)
+      94             :   {
+      95      239070 :     buffer[0]='\0';
+      96      239070 :     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      226212 :     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     1195936 :   TypesafePtr() {
+     112     1195936 :     shape[0]=0;
+     113     1006040 :     buffer[0]='\0';
+     114             :   }
+     115             : 
+     116             :   TypesafePtr(std::nullptr_t)
+     117      252074 :   {
+     118      252074 :     shape[0]=0;
+     119      251050 :     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        1215 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(void,1)
+     169        1577 :   __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      259694 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(int,3)
+     175          98 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned int,0x100+3)
+     176      237805 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long,3)
+     177             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned long,0x100+3)
+     178             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long long,3)
+     179             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned long long,0x100+3)
+     180           0 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(float,4)
+     181      275466 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(double,4)
+     182             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long double,4)
+     183         758 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(FILE,5)
+     184             : 
+     185             :   ~TypesafePtr() {
+     186     1786693 :   }
+     187             : 
+     188             : 
+     189             :   TypesafePtr(const TypesafePtr&other) = delete;
+     190             : 
+     191             :   TypesafePtr & operator=(const TypesafePtr & other) = delete;
+     192             : 
+     193          64 :   TypesafePtr(TypesafePtr&&other):
+     194          64 :     buffer(other.buffer),
+     195          64 :     ptr(other.ptr==&other.buffer[0] ? &buffer[0] : other.ptr),
+     196          64 :     nelem(other.nelem),
+     197          64 :     shape(other.shape),
+     198          64 :     flags(other.flags)
+     199             :   {
+     200          64 :     other.ptr=nullptr;
+     201          64 :   }
+     202             : 
+     203             :   TypesafePtr copy() const;
+     204             : 
+     205      791537 :   TypesafePtr & operator=(TypesafePtr && other) {
+     206      791537 :     ptr=(other.ptr==&other.buffer[0] ? &buffer[0] : other.ptr);
+     207      791537 :     flags=other.flags;
+     208      791537 :     nelem=other.nelem;
+     209      791537 :     shape=other.shape;
+     210      791537 :     buffer=other.buffer;
+     211      791537 :     other.ptr=nullptr;
+     212      791537 :     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     1004481 :   T* get_priv(std::size_t nelem, const std::size_t* shape, bool byvalue) const {
+     230             : 
+     231     1004481 :     if(typesafePtrSkipCheck()) return (T*) ptr;
+     232             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     233     1004481 :     if(flags==0) return (T*) ptr; // no check
+     234      998130 :     auto size=flags&0xffff;
+     235      998130 :     auto type=(flags>>16)&0xff;
+     236             :     // auto unsi=(flags>>24)&0x1; // ignored
+     237      999841 :     auto cons=(flags>>25)&0x7;
+     238             : 
+     239             :     // type=0: ignore check
+     240             :     // type>5: undefined yet
+     241      998130 :     if(type!=0 && type<=5) {
+     242      510828 :       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      486542 :       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         759 :       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      998125 :     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      999836 :     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      996394 :     if(cons>0) {
+     263             :       if(!std::is_pointer<T>::value) {
+     264             :         if(std::is_void<T>::value) {
+     265        1711 :           if(cons==1) {
+     266           0 :             throw ExceptionTypeError() << "This command expects a void pointer. It received a value instead"<<extra_msg();
+     267             :           }
+     268             :         } else {
+     269      994567 :           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      415882 :           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      415882 :           } 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      999835 :     if(shape && shape[0] && this->shape[0]) {
+     298         675 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     299         675 :         if(shape[i]==0 && this->shape[i]!=0) {
+     300           0 :           throw ExceptionTypeError() << "Incorrect number of axis (passed greater than requested)"<<extra_msg();
+     301             :         }
+     302         675 :         if(shape[i]!=0 && this->shape[i]==0) {
+     303           0 :           throw ExceptionTypeError() << "Incorrect number of axis (requested greater than passed)"<<extra_msg();
+     304             :         }
+     305         675 :         if(shape[i]==0) break;
+     306         450 :         if((shape[i]>this->shape[i])) {
+     307           0 :           throw ExceptionTypeError() << "This command wants " << shape[i] << " elements on axis " << i <<" of this pointer, but " << this->shape[i] << " have been passed"<<extra_msg();
+     308             :         }
+     309         450 :         if(i>0 && (shape[i]<this->shape[i])) {
+     310           0 :           throw ExceptionTypeError() << "This command wants " << shape[i] << " elements on axis " << i <<" of this pointer, but " << this->shape[i] << " have been passed"<<extra_msg();
+     311             :         }
+     312             :       }
+     313             :     }
+     314      999835 :     if(nelem==0 && shape && shape[0]>0) {
+     315      284900 :       nelem=1;
+     316      854700 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     317      854700 :         if(shape[i]==0) break;
+     318      569800 :         nelem*=shape[i];
+     319             :       }
+     320             :     }
+     321             :     // check number of elements
+     322      999835 :     if(nelem>0 && this->nelem>0) if(!(nelem<=this->nelem)) {
+     323           8 :         throw ExceptionTypeError() << "This command wants to access " << nelem << " from this pointer, but only " << this->nelem << " have been passed"<<extra_msg();
+     324             :       }
+     325      999833 :     return (T*) ptr;
+     326             :   }
+     327             : 
+     328             : public:
+     329             : 
+     330             :   template<typename T>
+     331        6814 :   void set(T val) const {
+     332        6814 :     *get_priv<T>(0,nullptr,false)=val;
+     333        6814 :   }
+     334             : 
+     335             :   template<typename T>
+     336      425662 :   typename std::enable_if<std::is_pointer<T>::value,T>::type get() const {
+     337             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     338      430248 :     return get_priv<T_noptr>(0,nullptr,false);
+     339             :   }
+     340             : 
+     341             :   template<typename T>
+     342      267996 :   typename std::enable_if<!std::is_pointer<T>::value,T>::type get() const {
+     343      267996 :     return *get_priv<const T>(1,nullptr,true);
+     344             :   }
+     345             : 
+     346             :   template<typename T>
+     347             :   T get(std::size_t nelem) const {
+     348             :     static_assert(std::is_pointer<T>::value,"only pointer types allowed here");
+     349             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     350        5999 :     return get_priv<T_noptr>(nelem,nullptr,false);
+     351             :   }
+     352             : 
+     353             :   template<typename T>
+     354      293420 :   T get(std::initializer_list<std::size_t> shape) const {
+     355             :     static_assert(std::is_pointer<T>::value,"only pointer types allowed here");
+     356      293420 :     plumed_assert(shape.size()<=maxrank);
+     357             :     std::array<std::size_t,maxrank+1> shape_;
+     358             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     359             :     unsigned j=0;
+     360      880260 :     for(auto i : shape) {
+     361      586840 :       shape_[j]=i;
+     362      586840 :       j++;
+     363             :     }
+     364      293420 :     shape_[j]=0;
+     365      293420 :     return get_priv<T_noptr>(0,&shape_[0],false);
+     366             :   }
+     367             : 
+     368             :   operator bool() const noexcept {
+     369      878943 :     return ptr;
+     370             :   }
+     371             : 
+     372             :   void* getRaw() const noexcept {
+     373         222 :     return ptr;
+     374             :   }
+     375             : 
+     376             :   std::size_t getNelem() const noexcept {
+     377         222 :     return nelem;
+     378             :   }
+     379             : 
+     380             :   const std::size_t* getShape() const noexcept {
+     381             :     return shape.data();
+     382             :   }
+     383             : 
+     384             :   std::size_t getFlags() const noexcept {
+     385         222 :     return flags;
+     386             :   }
+     387             : 
+     388             : private:
+     389             :   std::array<char,32> buffer;
+     390             :   void* ptr=nullptr;
+     391             :   std::size_t nelem=0;
+     392             :   std::array<std::size_t,maxrank+1> shape; // make sure to initialize this!
+     393             :   std::size_t flags=0;
+     394             : };
+     395             : 
+     396             : }
+     397             : 
+     398             : 
+     399             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..de0b281bcf --- /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-06-10 08:19:14Functions: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_traitsIcESaIcEEE33
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units7setMassEd718
_ZN4PLMD5Units9setChargeEd718
_ZN4PLMD5Units9setLengthEd718
_ZN4PLMD5UnitsC2Ev809538
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Units.cpp.func.html b/coverage/tools/Units.cpp.func.html new file mode 100644 index 0000000000..f578d231f5 --- /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-06-10 08:19:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Units7setMassERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD5Units7setMassEd718
_ZN4PLMD5Units7setTimeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZN4PLMD5Units7setTimeEd6
_ZN4PLMD5Units9setChargeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZN4PLMD5Units9setChargeEd718
_ZN4PLMD5Units9setEnergyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units9setLengthERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33
_ZN4PLMD5Units9setLengthEd718
_ZN4PLMD5UnitsC2Ev809538
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Units.cpp.gcov.html b/coverage/tools/Units.cpp.gcov.html new file mode 100644 index 0000000000..b44da7386b --- /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-06-10 08:19:14Functions: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      809538 : Units::Units():
+      28      809538 :   energy(1.0),
+      29      809538 :   energyString("kj/mol"),
+      30      809538 :   length(1.0),
+      31      809538 :   lengthString("nm"),
+      32      809538 :   time(1.0),
+      33      809538 :   timeString("ps"),
+      34      809538 :   charge(1.0),
+      35      809538 :   chargeString("e"),
+      36      809538 :   mass(1.0),
+      37      809538 :   massString("amu")
+      38             : {
+      39      809538 : }
+      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          33 : void Units::setLength(const std::string &s) {
+      64          33 :   lengthString=s;
+      65          33 :   if(s=="nm") {
+      66           2 :     length=1.0;
+      67          31 :   } else if(s=="A") {
+      68          24 :     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          33 : }
+      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         718 : void Units::setLength(const double s) {
+     137         718 :   lengthString="";
+     138         718 :   length=s;
+     139         718 : }
+     140             : 
+     141           6 : void Units::setTime(const double s) {
+     142           6 :   timeString="";
+     143           6 :   time=s;
+     144           6 : }
+     145             : 
+     146         718 : void Units::setCharge(const double s) {
+     147         718 :   chargeString="";
+     148         718 :   charge=s;
+     149         718 : }
+     150             : 
+     151         718 : void Units::setMass(const double s) {
+     152         718 :   massString="";
+     153         718 :   mass=s;
+     154         718 : }
+     155             : 
+     156             : 
+     157             : 
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..64deec76e3 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Units.h.func.html b/coverage/tools/Units.h.func.html new file mode 100644 index 0000000000..e2a2ebc683 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Units.h.gcov.html b/coverage/tools/Units.h.gcov.html new file mode 100644 index 0000000000..73e29d0bbe --- /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-06-10 08:19:14Functions: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    14974890 :   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.15
+
+ + + 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 0000000000..56f9b0c1ff --- /dev/null +++ b/coverage/tools/Vector.h.func-sort-c.html @@ -0,0 +1,289 @@ + + + + + + + + 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-06-10 08:19:14Functions:515494.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EEC2IJffEEEdDpT_0
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE260
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj3EEdVEd8301
_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
_ZNK4PLMD13VectorGenericILj4EEclEj4618728
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_4881117
_ZN4PLMD13VectorGenericILj3EE4zeroEv12803723
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_13491059
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_13491059
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_13594319
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_25428585
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_25428585
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_25531845
_ZN4PLMD13VectorGenericILj4EEixEj27787512
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_39126164
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d40818496
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZNK4PLMD13VectorGenericILj3EE6moduloEv83072108
_ZNK4PLMD13VectorGenericILj3EEngEv106091865
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_166313906
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE191884672
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d281949147
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_316058650
_ZNK4PLMD13VectorGenericILj6EEixEj396376380
_ZN4PLMD13VectorGenericILj3EEC2Ev473570046
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev737296052
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_852185740
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1047333346
_ZNK4PLMD13VectorGenericILj3EEclEj1256149080
_ZN4PLMD13VectorGenericILj3EEclEj1261457172
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1368271492
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1621835256
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_1659517798
_ZN4PLMD13VectorGenericILj3EEmLEd1659864777
_ZN4PLMD13VectorGenericILj3EEixEj2807242464
_ZNK4PLMD13VectorGenericILj3EEixEj3382975252
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Vector.h.func.html b/coverage/tools/Vector.h.func.html new file mode 100644 index 0000000000..9e7b4659a0 --- /dev/null +++ b/coverage/tools/Vector.h.func.html @@ -0,0 +1,289 @@ + + + + + + + + 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-06-10 08:19:14Functions:515494.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_166313906
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_4881117
_ZN4PLMD13VectorGenericILj1EEC2Ev548920
_ZN4PLMD13VectorGenericILj1EEixEj1097840
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_39126164
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_25531845
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_25428585
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdiEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_13594319
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJidEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_13491059
_ZN4PLMD13VectorGenericILj3EE4zeroEv12803723
_ZN4PLMD13VectorGenericILj3EEC2Ev473570046
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_25428585
_ZN4PLMD13VectorGenericILj3EEC2IJdiEEEdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJffEEEdDpT_0
_ZN4PLMD13VectorGenericILj3EEC2IJidEEEdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_13491059
_ZN4PLMD13VectorGenericILj3EEclEj1261457172
_ZN4PLMD13VectorGenericILj3EEdVEd8301
_ZN4PLMD13VectorGenericILj3EEixEj2807242464
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1047333346
_ZN4PLMD13VectorGenericILj3EEmLEd1659864777
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1621835256
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EEC2Ev1747526
_ZN4PLMD13VectorGenericILj4EEC2IJdddEEEdDpT_555994
_ZN4PLMD13VectorGenericILj4EEixEj27787512
_ZN4PLMD13VectorGenericILj4EEmIERKS1_1119102
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_316058650
_ZN4PLMD5deltaILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE260
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE191884672
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d40818496
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_852185740
_ZN4PLMDmiILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d281949147
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_1659517798
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1368271492
_ZNK4PLMD13VectorGenericILj3EE6moduloEv83072108
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev737296052
_ZNK4PLMD13VectorGenericILj3EEclEj1256149080
_ZNK4PLMD13VectorGenericILj3EEixEj3382975252
_ZNK4PLMD13VectorGenericILj3EEngEv106091865
_ZNK4PLMD13VectorGenericILj4EE7modulo2Ev1119102
_ZNK4PLMD13VectorGenericILj4EEclEj4618728
_ZNK4PLMD13VectorGenericILj6EEixEj396376380
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/Vector.h.gcov.html b/coverage/tools/Vector.h.gcov.html new file mode 100644 index 0000000000..d435f98fac --- /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-06-10 08:19:14Functions:515494.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             : #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   119602468 : void VectorGeneric<n>::auxiliaryConstructor(double first,Args... arg)
+     164             : {
+     165   119602468 :   d[n-(sizeof...(Args))-1]=first;
+     166    79920310 :   auxiliaryConstructor(arg...);
+     167   119602468 : }
+     168             : 
+     169             : template <unsigned n>
+     170             : template<typename... Args>
+     171    39682158 : 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    39682158 :   auxiliaryConstructor(first,arg...);
+     175    39682158 : }
+     176             : 
+     177             : template <unsigned n>
+     178    12803723 : void VectorGeneric<n>::zero() {
+     179    12803723 :   LoopUnroller<n>::_zero(d.data());
+     180    12803723 : }
+     181             : 
+     182             : template <unsigned n>
+     183   475870496 : VectorGeneric<n>::VectorGeneric() {
+     184   475321576 :   LoopUnroller<n>::_zero(d.data());
+     185   475870496 : }
+     186             : 
+     187             : template <unsigned n>
+     188  2899777178 : double & VectorGeneric<n>::operator[](unsigned i) {
+     189  2899777178 :   return d[i];
+     190             : }
+     191             : 
+     192             : template <unsigned n>
+     193  3779351632 : const double & VectorGeneric<n>::operator[](unsigned i)const {
+     194  3779351632 :   return d[i];
+     195             : }
+     196             : 
+     197             : template <unsigned n>
+     198  1261457172 : double & VectorGeneric<n>::operator()(unsigned i) {
+     199  1261457172 :   return d[i];
+     200             : }
+     201             : 
+     202             : template <unsigned n>
+     203  1260767808 : const double & VectorGeneric<n>::operator()(unsigned i)const {
+     204  1260767808 :   return d[i];
+     205             : }
+     206             : 
+     207             : template <unsigned n>
+     208  1621835256 : VectorGeneric<n>& VectorGeneric<n>::operator +=(const VectorGeneric<n>& b) {
+     209  1621835256 :   LoopUnroller<n>::_add(d.data(),b.d.data());
+     210  1621835256 :   return *this;
+     211             : }
+     212             : 
+     213             : template <unsigned n>
+     214  1048452448 : VectorGeneric<n>& VectorGeneric<n>::operator -=(const VectorGeneric<n>& b) {
+     215  1048452448 :   LoopUnroller<n>::_sub(d.data(),b.d.data());
+     216  1048452448 :   return *this;
+     217             : }
+     218             : 
+     219             : template <unsigned n>
+     220  1659864777 : VectorGeneric<n>& VectorGeneric<n>::operator *=(double s) {
+     221  1659864777 :   LoopUnroller<n>::_mul(d.data(),s);
+     222  1659864777 :   return *this;
+     223             : }
+     224             : 
+     225             : template <unsigned n>
+     226        8301 : VectorGeneric<n>& VectorGeneric<n>::operator /=(double s) {
+     227        8301 :   LoopUnroller<n>::_mul(d.data(),1.0/s);
+     228        8301 :   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   106091865 : VectorGeneric<n> VectorGeneric<n>::operator -()const {
+     238   106091865 :   VectorGeneric<n> r;
+     239   106091865 :   LoopUnroller<n>::_neg(r.d.data(),d.data());
+     240   106091865 :   return r;
+     241             : }
+     242             : 
+     243             : template <unsigned n>
+     244  1368271492 : VectorGeneric<n> operator+(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     245  1368271492 :   VectorGeneric<n> v(v1);
+     246  1368271492 :   return v+=v2;
+     247             : }
+     248             : 
+     249             : template <unsigned n>
+     250   853304842 : VectorGeneric<n> operator-(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     251   853304842 :   VectorGeneric<n> v(v1);
+     252   853304842 :   return v-=v2;
+     253             : }
+     254             : 
+     255             : template <unsigned n>
+     256  1659517798 : VectorGeneric<n> operator*(double s,const VectorGeneric<n>&v) {
+     257  1659517798 :   VectorGeneric<n> vv(v);
+     258  1659517798 :   return vv*=s;
+     259             : }
+     260             : 
+     261             : template <unsigned n>
+     262   281949147 : VectorGeneric<n> operator*(const VectorGeneric<n>&v,double s) {
+     263   281949147 :   return s*v;
+     264             : }
+     265             : 
+     266             : template <unsigned n>
+     267    40818496 : VectorGeneric<n> operator/(const VectorGeneric<n>&v,double s) {
+     268    40818496 :   return v*(1.0/s);
+     269             : }
+     270             : 
+     271             : template <unsigned n>
+     272   317177752 : VectorGeneric<n> delta(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     273   317177752 :   return v2-v1;
+     274             : }
+     275             : 
+     276             : template <unsigned n>
+     277   738415154 : double VectorGeneric<n>::modulo2()const {
+     278   738415154 :   return LoopUnroller<n>::_sum2(d.data());
+     279             : }
+     280             : 
+     281             : template <unsigned n>
+     282   166313906 : double dotProduct(const VectorGeneric<n>& v1,const VectorGeneric<n>& v2) {
+     283   166313906 :   return LoopUnroller<n>::_dot(v1.d.data(),v2.d.data());
+     284             : }
+     285             : 
+     286             : inline
+     287     4881117 : VectorGeneric<3> crossProduct(const VectorGeneric<3>& v1,const VectorGeneric<3>& v2) {
+     288             :   return VectorGeneric<3>(
+     289     4881117 :            v1[1]*v2[2]-v1[2]*v2[1],
+     290     4881117 :            v1[2]*v2[0]-v1[0]*v2[2],
+     291     4881117 :            v1[0]*v2[1]-v1[1]*v2[0]);
+     292             : }
+     293             : 
+     294             : template<unsigned n>
+     295    83072108 : double VectorGeneric<n>::modulo()const {
+     296    83072108 :   return sqrt(modulo2());
+     297             : }
+     298             : 
+     299             : template<unsigned n>
+     300   191884672 : double modulo2(const VectorGeneric<n>&v) {
+     301   191884672 :   return v.modulo2();
+     302             : }
+     303             : 
+     304             : template<unsigned n>
+     305         260 : double modulo(const VectorGeneric<n>&v) {
+     306         260 :   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.15
+
+ + + 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 0000000000..b7ff3e49f4 --- /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-06-10 08:19:14Functions: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_clEv217
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv217
_ZN4PLMD3h36L12digits_lowerEv7813
_ZN4PLMD3h3610hy36encodeEjiPc103780
_ZN4PLMD3h36L11encode_pureEPKcjjiPc103780
_ZN4PLMD3h36L12digits_upperEv111591
_ZN4PLMD3h3610hy36decodeEjPKcjPi460690
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi460690
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/h36.cpp.func.html b/coverage/tools/h36.cpp.func.html new file mode 100644 index 0000000000..57260b7ab6 --- /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-06-10 08:19:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3h3610hy36decodeEjPKcjPi460690
_ZN4PLMD3h3610hy36encodeEjiPc103780
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi460690
_ZN4PLMD3h36L11encode_pureEPKcjjiPc103780
_ZN4PLMD3h36L12digits_lowerEv7813
_ZN4PLMD3h36L12digits_upperEv111591
_ZN4PLMD3h36L15fill_with_starsEjPc0
_ZN4PLMD3h36L17unsupported_widthEv0
_ZN4PLMD3h36L18value_out_of_rangeEv0
_ZN4PLMD3h36L22invalid_number_literalEv2
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE0_clEv217
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv217
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/h36.cpp.gcov.html b/coverage/tools/h36.cpp.gcov.html new file mode 100644 index 0000000000..4387c8baef --- /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-06-10 08:19:14Functions: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      111591 : digits_upper() { return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
+      62             : 
+      63             : static
+      64             : const char*
+      65        7813 : 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      460690 : 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     2537114 :   for(; i<s_size; i++) {
+     133     2076425 :     si = s[i];
+     134     2076425 :     if (si < 0 || si > 127) {
+     135           0 :       *result = 0;
+     136           0 :       return invalid_number_literal();
+     137             :     }
+     138     2076425 :     if (si == ' ') {
+     139      768606 :       if (!have_non_blank) continue;
+     140           0 :       value *= digits_size;
+     141             :     }
+     142     1307819 :     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     1307819 :       dv = digits_values[si];
+     154     1307819 :       if (dv < 0 || dv >= digits_size) {
+     155           1 :         *result = 0;
+     156           1 :         return invalid_number_literal();
+     157             :       }
+     158     1307818 :       value *= digits_size;
+     159     1307818 :       value += dv;
+     160             :     }
+     161             :   }
+     162      460689 :   if (have_minus) value = -value;
+     163      460689 :   *result = value;
+     164      460689 :   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      460690 : hy36decode(unsigned width, const char* s, unsigned s_size, int* result)
+     261             : {
+     262         217 :   static const std::vector<int> digits_values_upper_vector([]() {
+     263         217 :     std::vector<int> ret(128U,-1);
+     264        8029 :     for(unsigned i=0; i<36U; i++) {
+     265        7812 :       int di = digits_upper()[i];
+     266        7812 :       if (di < 0 || di > 127) {
+     267           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     268             :       }
+     269        7812 :       ret[di] = i;
+     270             :     }
+     271         217 :     return ret;
+     272      460690 :   }());
+     273      460690 :   static const int* digits_values_upper=digits_values_upper_vector.data();
+     274         217 :   static const std::vector<int> digits_values_lower_vector([]() {
+     275         217 :     std::vector<int> ret(128U,-1);
+     276        8029 :     for(unsigned i=0; i<36U; i++) {
+     277        7812 :       int di = digits_lower()[i];
+     278        7812 :       if (di < 0 || di > 127) {
+     279           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     280             :       }
+     281        7812 :       ret[di] = i;
+     282             :     }
+     283         217 :     return ret;
+     284      460690 :   }());
+     285      460690 :   static const int* digits_values_lower=digits_values_lower_vector.data();
+     286             :   int di;
+     287             :   const char* errmsg;
+     288      460690 :   if (s_size == width) {
+     289      460690 :     di = s[0];
+     290      460690 :     if (di >= 0 && di <= 127) {
+     291      460690 :       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      460684 :       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      460684 :         errmsg = decode_pure(digits_values_upper, 10U, s, s_size, result);
+     319      460684 :         if (errmsg) return errmsg;
+     320      460684 :         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.15
+
+ + + diff --git a/coverage/tools/index-sort-f.html b/coverage/tools/index-sort-f.html new file mode 100644 index 0000000000..99425d2f9d --- /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:5445653083.4 %
Date:2024-06-10 08:19:14Functions:1365168780.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Tree.cpp +
0.0%
+
0.0 %0 / 370.0 %0 / 3
Exception.h +
100.0%
+
100.0 %30 / 3014.9 %20 / 134
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
PlumedHandle.cpp +
41.5%41.5%
+
41.5 %17 / 4162.5 %5 / 8
BiasRepresentation.cpp +
75.9%75.9%
+
75.9 %129 / 17063.2 %12 / 19
RootFindingBase.h +
100.0%
+
100.0 %16 / 1666.7 %4 / 6
Brent1DRootSearch.h +
97.4%97.4%
+
97.4 %38 / 3966.7 %6 / 9
Grid.cpp +
71.0%71.0%
+
71.0 %440 / 62071.4 %55 / 77
Keywords.cpp +
53.3%53.3%
+
53.3 %223 / 41873.0 %27 / 37
OpenMP.h +
100.0%
+
100.0 %8 / 875.0 %3 / 4
h36.cpp +
70.1%70.1%
+
70.1 %89 / 12775.0 %9 / 12
TypesafePtr.h +
87.7%87.7%
+
87.7 %114 / 13076.9 %40 / 52
RMSD.h +
85.7%85.7%
+
85.7 %30 / 3577.8 %7 / 9
ERMSD.cpp +
98.4%98.4%
+
98.4 %120 / 12280.0 %4 / 5
OpenMP.cpp +
82.4%82.4%
+
82.4 %14 / 1780.0 %4 / 5
DLLoader.cpp +
81.0%81.0%
+
81.0 %17 / 2180.0 %4 / 5
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
NeighborList.cpp +
89.7%89.7%
+
89.7 %96 / 10780.0 %12 / 15
Communicator.cpp +
82.5%82.5%
+
82.5 %99 / 12080.0 %28 / 35
PDB.cpp +
81.8%81.8%
+
81.8 %239 / 29281.4 %35 / 43
Tensor.h +
96.7%96.7%
+
96.7 %146 / 15182.4 %56 / 68
Subprocess.cpp +
75.3%75.3%
+
75.3 %64 / 8587.5 %14 / 16
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.4%84.4%
+
84.4 %189 / 22490.0 %9 / 10
Random.cpp +
91.6%91.6%
+
91.6 %76 / 8390.9 %10 / 11
IFile.cpp +
98.6%98.6%
+
98.6 %142 / 14491.3 %21 / 23
Pbc.cpp +
95.3%95.3%
+
95.3 %102 / 10791.7 %11 / 12
Tools.h +
96.7%96.7%
+
96.7 %59 / 6191.9 %388 / 422
Tools.cpp +
90.7%90.7%
+
90.7 %214 / 23692.7 %38 / 41
FileBase.cpp +
100.0%
+
100.0 %79 / 7993.3 %14 / 15
Communicator.h +
91.5%91.5%
+
91.5 %43 / 4793.5 %58 / 62
Vector.h +
100.0%
+
100.0 %66 / 6694.4 %51 / 54
ERMSD.h +
100.0%
+
100.0 %1 / 1-0 / 0
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
Tree.h +
0.0%
+
0.0 %0 / 1-0 / 0
Pbc.h +
100.0%
+
100.0 %2 / 2-0 / 0
LinkCells.h +
100.0%
+
100.0 %2 / 2-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
FileBase.h +
100.0%
+
100.0 %5 / 5-0 / 0
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
NeighborList.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
KernelFunctions.h +
100.0%
+
100.0 %8 / 8100.0 %1 / 1
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
AtomNumber.h +
100.0%
+
100.0 %17 / 17100.0 %2 / 2
Keywords.h +
88.2%88.2%
+
88.2 %15 / 17100.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
Stopwatch.cpp +
100.0%
+
100.0 %20 / 20100.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
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
MultiValue.h +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
MolDataClass.cpp +
85.1%85.1%
+
85.1 %406 / 477100.0 %5 / 5
Exception.cpp +
100.0%
+
100.0 %33 / 33100.0 %5 / 5
MultiValue.cpp +
100.0%
+
100.0 %62 / 62100.0 %9 / 9
Stopwatch.h +
92.7%92.7%
+
92.7 %51 / 55100.0 %10 / 10
LinkCells.cpp +
98.8%98.8%
+
98.8 %83 / 84100.0 %10 / 10
SwitchingFunction.cpp +
97.3%97.3%
+
97.3 %256 / 263100.0 %11 / 11
Matrix.h +
100.0%
+
100.0 %140 / 140100.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
Minimise1DBrent.h +
97.6%97.6%
+
97.6 %81 / 83100.0 %12 / 12
DynamicList.h +
100.0%
+
100.0 %47 / 47100.0 %13 / 13
ForwardDecl.h +
100.0%
+
100.0 %4 / 4100.0 %13 / 13
MatrixSquareBracketsAccess.h +
100.0%
+
100.0 %12 / 12100.0 %18 / 18
OFile.cpp +
98.2%98.2%
+
98.2 %217 / 221100.0 %28 / 28
LoopUnroller.h +
100.0%
+
100.0 %31 / 31100.0 %52 / 52
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/index-sort-l.html b/coverage/tools/index-sort-l.html new file mode 100644 index 0000000000..3dcd1cc527 --- /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:5445653083.4 %
Date:2024-06-10 08:19:14Functions:1365168780.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Tree.h +
0.0%
+
0.0 %0 / 1-0 / 0
Tree.cpp +
0.0%
+
0.0 %0 / 370.0 %0 / 3
PlumedHandle.cpp +
41.5%41.5%
+
41.5 %17 / 4162.5 %5 / 8
Keywords.cpp +
53.3%53.3%
+
53.3 %223 / 41873.0 %27 / 37
h36.cpp +
70.1%70.1%
+
70.1 %89 / 12775.0 %9 / 12
Grid.cpp +
71.0%71.0%
+
71.0 %440 / 62071.4 %55 / 77
RMSD.cpp +
73.5%73.5%
+
73.5 %540 / 73552.5 %42 / 80
Subprocess.cpp +
75.3%75.3%
+
75.3 %64 / 8587.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
DLLoader.cpp +
81.0%81.0%
+
81.0 %17 / 2180.0 %4 / 5
PDB.cpp +
81.8%81.8%
+
81.8 %239 / 29281.4 %35 / 43
OpenMP.cpp +
82.4%82.4%
+
82.4 %14 / 1780.0 %4 / 5
Communicator.cpp +
82.5%82.5%
+
82.5 %99 / 12080.0 %28 / 35
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
KernelFunctions.cpp +
84.4%84.4%
+
84.4 %189 / 22490.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.7%87.7%
+
87.7 %114 / 13076.9 %40 / 52
Keywords.h +
88.2%88.2%
+
88.2 %15 / 17100.0 %2 / 2
NeighborList.cpp +
89.7%89.7%
+
89.7 %96 / 10780.0 %12 / 15
Tools.cpp +
90.7%90.7%
+
90.7 %214 / 23692.7 %38 / 41
Units.cpp +
90.7%90.7%
+
90.7 %88 / 97100.0 %11 / 11
Communicator.h +
91.5%91.5%
+
91.5 %43 / 4793.5 %58 / 62
Random.cpp +
91.6%91.6%
+
91.6 %76 / 8390.9 %10 / 11
Stopwatch.h +
92.7%92.7%
+
92.7 %51 / 55100.0 %10 / 10
ConjugateGradient.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %3 / 3
HistogramBead.h +
94.4%94.4%
+
94.4 %17 / 18100.0 %2 / 2
Pbc.cpp +
95.3%95.3%
+
95.3 %102 / 10791.7 %11 / 12
Tensor.h +
96.7%96.7%
+
96.7 %146 / 15182.4 %56 / 68
Tools.h +
96.7%96.7%
+
96.7 %59 / 6191.9 %388 / 422
SwitchingFunction.cpp +
97.3%97.3%
+
97.3 %256 / 263100.0 %11 / 11
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
OFile.cpp +
98.2%98.2%
+
98.2 %217 / 221100.0 %28 / 28
ERMSD.cpp +
98.4%98.4%
+
98.4 %120 / 12280.0 %4 / 5
IFile.cpp +
98.6%98.6%
+
98.6 %142 / 14491.3 %21 / 23
LinkCells.cpp +
98.8%98.8%
+
98.8 %83 / 84100.0 %10 / 10
ERMSD.h +
100.0%
+
100.0 %1 / 1-0 / 0
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
Pbc.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
NeighborList.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
ForwardDecl.h +
100.0%
+
100.0 %4 / 4100.0 %13 / 13
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
FileBase.h +
100.0%
+
100.0 %5 / 5-0 / 0
OFile.h +
100.0%
+
100.0 %6 / 689.7 %96 / 107
KernelFunctions.h +
100.0%
+
100.0 %8 / 8100.0 %1 / 1
OpenMP.h +
100.0%
+
100.0 %8 / 875.0 %3 / 4
MatrixSquareBracketsAccess.h +
100.0%
+
100.0 %12 / 12100.0 %18 / 18
TypesafePtr.cpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
RootFindingBase.h +
100.0%
+
100.0 %16 / 1666.7 %4 / 6
AtomNumber.h +
100.0%
+
100.0 %17 / 17100.0 %2 / 2
Stopwatch.cpp +
100.0%
+
100.0 %20 / 20100.0 %3 / 3
MinimiseBase.h +
100.0%
+
100.0 %26 / 2688.9 %16 / 18
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
Exception.h +
100.0%
+
100.0 %30 / 3014.9 %20 / 134
LoopUnroller.h +
100.0%
+
100.0 %31 / 31100.0 %52 / 52
Grid.h +
100.0%
+
100.0 %32 / 3288.9 %8 / 9
Exception.cpp +
100.0%
+
100.0 %33 / 33100.0 %5 / 5
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 / 6694.4 %51 / 54
FileBase.cpp +
100.0%
+
100.0 %79 / 7993.3 %14 / 15
Matrix.h +
100.0%
+
100.0 %140 / 140100.0 %11 / 11
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/tools/index.html b/coverage/tools/index.html new file mode 100644 index 0000000000..284b1fce9a --- /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:5445653083.4 %
Date:2024-06-10 08:19:14Functions:1365168780.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 %17 / 17100.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 +
82.5%82.5%
+
82.5 %99 / 12080.0 %28 / 35
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 +
81.0%81.0%
+
81.0 %17 / 2180.0 %4 / 5
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 +
100.0%
+
100.0 %1 / 1-0 / 0
Exception.cpp +
100.0%
+
100.0 %33 / 33100.0 %5 / 5
Exception.h +
100.0%
+
100.0 %30 / 3014.9 %20 / 134
FileBase.cpp +
100.0%
+
100.0 %79 / 7993.3 %14 / 15
FileBase.h +
100.0%
+
100.0 %5 / 5-0 / 0
ForwardDecl.h +
100.0%
+
100.0 %4 / 4100.0 %13 / 13
Grid.cpp +
71.0%71.0%
+
71.0 %440 / 62071.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 +
98.6%98.6%
+
98.6 %142 / 14491.3 %21 / 23
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
KernelFunctions.cpp +
84.4%84.4%
+
84.4 %189 / 22490.0 %9 / 10
KernelFunctions.h +
100.0%
+
100.0 %8 / 8100.0 %1 / 1
Keywords.cpp +
53.3%53.3%
+
53.3 %223 / 41873.0 %27 / 37
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 %18 / 18
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 +
89.7%89.7%
+
89.7 %96 / 10780.0 %12 / 15
NeighborList.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
OFile.cpp +
98.2%98.2%
+
98.2 %217 / 221100.0 %28 / 28
OFile.h +
100.0%
+
100.0 %6 / 689.7 %96 / 107
OpenMP.cpp +
82.4%82.4%
+
82.4 %14 / 1780.0 %4 / 5
OpenMP.h +
100.0%
+
100.0 %8 / 875.0 %3 / 4
PDB.cpp +
81.8%81.8%
+
81.8 %239 / 29281.4 %35 / 43
Pbc.cpp +
95.3%95.3%
+
95.3 %102 / 10791.7 %11 / 12
Pbc.h +
100.0%
+
100.0 %2 / 2-0 / 0
PlumedHandle.cpp +
41.5%41.5%
+
41.5 %17 / 4162.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 %20 / 20100.0 %3 / 3
Stopwatch.h +
92.7%92.7%
+
92.7 %51 / 55100.0 %10 / 10
Subprocess.cpp +
75.3%75.3%
+
75.3 %64 / 8587.5 %14 / 16
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
SwitchingFunction.cpp +
97.3%97.3%
+
97.3 %256 / 263100.0 %11 / 11
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
Tensor.h +
96.7%96.7%
+
96.7 %146 / 15182.4 %56 / 68
Tools.cpp +
90.7%90.7%
+
90.7 %214 / 23692.7 %38 / 41
Tools.h +
96.7%96.7%
+
96.7 %59 / 6191.9 %388 / 422
Torsion.cpp +
80.0%80.0%
+
80.0 %28 / 3550.0 %1 / 2
Tree.cpp +
0.0%
+
0.0 %0 / 370.0 %0 / 3
Tree.h +
0.0%
+
0.0 %0 / 1-0 / 0
TypesafePtr.cpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
TypesafePtr.h +
87.7%87.7%
+
87.7 %114 / 13076.9 %40 / 52
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 / 6694.4 %51 / 54
h36.cpp +
70.1%70.1%
+
70.1 %89 / 12775.0 %9 / 12
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..075e5fc580 --- /dev/null +++ b/coverage/vatom/Center.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:10410599.0 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom6CenterC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe1366createERKNS_13ActionOptionsE74
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe135C2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe135D2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe136C2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe136D2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe1356createERKNS_13ActionOptionsE7087
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE7161
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE7163
_ZN4PLMD5vatom6Center9calculateEv13798
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vatom/Center.cpp.func.html b/coverage/vatom/Center.cpp.func.html new file mode 100644 index 0000000000..fadc67d662 --- /dev/null +++ b/coverage/vatom/Center.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:10410599.0 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe1356createERKNS_13ActionOptionsE7087
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe135C2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe135D2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe1366createERKNS_13ActionOptionsE74
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe136C2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe136D2Ev3473
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE7163
_ZN4PLMD5vatom6Center9calculateEv13798
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE7161
_ZN4PLMD5vatom6CenterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vatom/Center.cpp.gcov.html b/coverage/vatom/Center.cpp.gcov.html new file mode 100644 index 0000000000..e16a89f875 --- /dev/null +++ b/coverage/vatom/Center.cpp.gcov.html @@ -0,0 +1,380 @@ + + + + + + + + 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:10410599.0 %
Date:2024-06-10 08:19:14Functions: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 "ActionWithVirtualAtom.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/Atoms.h"
+      26             : #include <cmath>
+      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             :   bool weight_mass;
+     126             :   bool nopbc;
+     127             :   bool first;
+     128             :   bool phases;
+     129             : public:
+     130             :   explicit Center(const ActionOptions&ao);
+     131             :   void calculate() override;
+     132             :   static void registerKeywords( Keywords& keys );
+     133             : };
+     134             : 
+     135       24591 : PLUMED_REGISTER_ACTION(Center,"CENTER")
+     136       10567 : PLUMED_REGISTER_ACTION(Center,"COM")
+     137             : 
+     138        7163 : void Center::registerKeywords(Keywords& keys) {
+     139        7163 :   ActionWithVirtualAtom::registerKeywords(keys);
+     140       14326 :   keys.add("optional","WEIGHTS","Center is computed as a weighted average.");
+     141       14326 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     142       14326 :   keys.addFlag("MASS",false,"If set center is mass weighted");
+     143       14326 :   keys.addFlag("PHASES",false,"Compute center using trigonometric phases");
+     144        7163 : }
+     145             : 
+     146        7161 : Center::Center(const ActionOptions&ao):
+     147             :   Action(ao),
+     148             :   ActionWithVirtualAtom(ao),
+     149        7161 :   weight_mass(false),
+     150        7161 :   nopbc(false),
+     151        7161 :   first(true),
+     152        7161 :   phases(false)
+     153             : {
+     154             :   std::vector<AtomNumber> atoms;
+     155       14322 :   parseAtomList("ATOMS",atoms);
+     156        7161 :   if(atoms.size()==0) error("at least one atom should be specified");
+     157        7161 :   parseVector("WEIGHTS",weights);
+     158        7161 :   parseFlag("MASS",weight_mass);
+     159        7161 :   parseFlag("NOPBC",nopbc);
+     160       14322 :   parseFlag("PHASES",phases);
+     161        7161 :   if( getName()=="COM") weight_mass=true;
+     162        7161 :   checkRead();
+     163        7161 :   log.printf("  of atoms:");
+     164       37413 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     165       30252 :     if(i%25==0) log<<"\n";
+     166       30252 :     log.printf(" %d",atoms[i].serial());
+     167             :   }
+     168        7161 :   log<<"\n";
+     169        7161 :   if(weight_mass) {
+     170          77 :     log<<"  mass weighted\n";
+     171          77 :     if(weights.size()!=0) error("WEIGHTS and MASS keywords should not be used simultaneously");
+     172             :   } else {
+     173        7084 :     if( weights.size()==0) {
+     174         107 :       log<<" using the geometric center\n";
+     175         107 :       weights.resize( atoms.size() );
+     176        1318 :       for(unsigned i=0; i<atoms.size(); i++) weights[i] = 1.;
+     177             :     } else {
+     178        6977 :       log<<" with weights:";
+     179        6979 :       if( weights.size()!=atoms.size() ) error("number of elements in weight vector does not match the number of atoms");
+     180       35074 :       for(unsigned i=0; i<weights.size(); ++i) {
+     181       28098 :         if(i%25==0) log<<"\n";
+     182       28098 :         log.printf(" %f",weights[i]);
+     183             :       }
+     184        6976 :       log.printf("\n");
+     185             :     }
+     186             :   }
+     187        7159 :   if(phases) {
+     188           3 :     log<<"  Phases will be used to take into account PBC\n";
+     189        7156 :   } else if(nopbc) {
+     190          45 :     log<<"  PBC will be ignored\n";
+     191             :   } else {
+     192        7111 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     193             :   }
+     194        7159 :   requestAtoms(atoms);
+     195        7163 : }
+     196             : 
+     197       13798 : void Center::calculate() {
+     198       13798 :   Vector pos;
+     199             :   double mass(0.0);
+     200       13798 :   const bool dophases=(getPbc().isSet() ? phases : false);
+     201             : 
+     202       13798 :   if(!nopbc && !dophases) makeWhole();
+     203             : 
+     204       13798 :   if( first && weight_mass) {
+     205         725 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     206         659 :       if(std::isnan(getMass(i))) {
+     207           0 :         error(
+     208             :           "You are trying to compute a CENTER or COM but masses are not known.\n"
+     209             :           "        If you are using plumed driver, please use the --mc option"
+     210             :         );
+     211             :       }
+     212             :     }
+     213          66 :     first=false;
+     214             :   }
+     215             : 
+     216       13798 :   std::vector<Tensor> deriv(getNumberOfAtoms());
+     217       93241 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) mass+=getMass(i);
+     218       13798 :   if( plumed.getAtoms().chargesWereSet() ) {
+     219             :     double charge(0.0);
+     220       60621 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) charge+=getCharge(i);
+     221             :     setCharge(charge);
+     222             :   } else {
+     223             :     setCharge(0.0);
+     224             :   }
+     225             :   double wtot=0.0;
+     226       57907 :   for(unsigned i=0; i<weights.size(); i++) wtot+=weights[i];
+     227             : 
+     228       13798 :   if(dophases) {
+     229         240 :     dcenter_sin.resize(getNumberOfAtoms());
+     230         240 :     dcenter_cos.resize(getNumberOfAtoms());
+     231         240 :     Vector center_sin;
+     232         240 :     Vector center_cos;
+     233         240 :     Tensor invbox2pi=2*pi*getPbc().getInvBox();
+     234         240 :     Tensor box2pi=getPbc().getBox() / (2*pi);
+     235         960 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     236             :       double w=0;
+     237         720 :       if(weight_mass) w=getMass(i)/mass;
+     238         720 :       else w=weights[i]/wtot;
+     239             : 
+     240             : // real to scaled
+     241         720 :       const Vector scaled=matmul(getPosition(i),invbox2pi);
+     242             :       const Vector ccos(
+     243         720 :         w*std::cos(scaled[0]),
+     244         720 :         w*std::cos(scaled[1]),
+     245         720 :         w*std::cos(scaled[2])
+     246         720 :       );
+     247             :       const Vector csin(
+     248         720 :         w*std::sin(scaled[0]),
+     249         720 :         w*std::sin(scaled[1]),
+     250         720 :         w*std::sin(scaled[2])
+     251         720 :       );
+     252         720 :       center_cos+=ccos;
+     253         720 :       center_sin+=csin;
+     254        9360 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     255             : // k over real coordinates
+     256             : // l over scaled coordinates
+     257        6480 :           dcenter_sin[i][l][k]=ccos[l]*invbox2pi[k][l];
+     258        6480 :           dcenter_cos[i][l][k]=-csin[l]*invbox2pi[k][l];
+     259             :         }
+     260             :     }
+     261             :     const Vector c(
+     262         240 :       std::atan2(center_sin[0],center_cos[0]),
+     263         240 :       std::atan2(center_sin[1],center_cos[1]),
+     264         240 :       std::atan2(center_sin[2],center_cos[2])
+     265         240 :     );
+     266             : 
+     267             : // normalization is convenient for doing derivatives later
+     268         960 :     for(unsigned l=0; l<3; l++) {
+     269         720 :       double norm=1.0/(center_sin[l]*center_sin[l]+center_cos[l]*center_cos[l]);
+     270         720 :       center_sin[l]*=norm;
+     271         720 :       center_cos[l]*=norm;
+     272             :     }
+     273             : 
+     274         960 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     275         720 :       Tensor dd;
+     276        9360 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     277             : // k over real coordinates
+     278             : // l over scaled coordinates
+     279        6480 :           dd[l][k]= (center_cos[l]*dcenter_sin[i][l][k] - center_sin[l]*dcenter_cos[i][l][k]);
+     280             :         }
+     281             : // scaled to real
+     282         720 :       deriv[i]=matmul(dd,box2pi);
+     283             :     }
+     284             :     setMass(mass);
+     285             :     setAtomsDerivatives(deriv);
+     286             : // scaled to real
+     287         240 :     setPosition(matmul(c,box2pi));
+     288             :   } else {
+     289       92281 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     290             :       double w=0;
+     291       78723 :       if(weight_mass) w=getMass(i)/mass;
+     292       43389 :       else w=weights[i]/wtot;
+     293       78723 :       pos+=w*getPosition(i);
+     294       78723 :       deriv[i]=w*Tensor::identity();
+     295             :     }
+     296             :     setPosition(pos);
+     297             :     setMass(mass);
+     298             :     setAtomsDerivatives(deriv);
+     299             :   }
+     300       13798 : }
+     301             : 
+     302             : }
+     303             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..84a658f765 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3232100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom9FixedAtomC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe976createERKNS_13ActionOptionsE9
_ZN4PLMD5vatom9FixedAtomC1ERKNS_13ActionOptionsE9
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD5vatom9FixedAtom9calculateEv603
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe97C2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe97D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.func.html b/coverage/vatom/FixedAtom.cpp.func.html new file mode 100644 index 0000000000..ebc2f9a3be --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3232100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe976createERKNS_13ActionOptionsE9
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe97C2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe97D2Ev3473
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD5vatom9FixedAtom9calculateEv603
_ZN4PLMD5vatom9FixedAtomC1ERKNS_13ActionOptionsE9
_ZN4PLMD5vatom9FixedAtomC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.gcov.html b/coverage/vatom/FixedAtom.cpp.gcov.html new file mode 100644 index 0000000000..32949714d3 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + + 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:3232100.0 %
Date:2024-06-10 08:19:14Functions: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 "ActionWithVirtualAtom.h"
+      23             : #include "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 to 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             :   double mass,charge;
+      90             :   bool scaled_components;
+      91             : public:
+      92             :   explicit FixedAtom(const ActionOptions&ao);
+      93             :   void calculate() override;
+      94             :   static void registerKeywords( Keywords& keys );
+      95             : };
+      96             : 
+      97       10437 : PLUMED_REGISTER_ACTION(FixedAtom,"FIXEDATOM")
+      98             : 
+      99          10 : void FixedAtom::registerKeywords(Keywords& keys) {
+     100          10 :   ActionWithVirtualAtom::registerKeywords(keys);
+     101          20 :   keys.add("compulsory","AT","coordinates of the virtual atom");
+     102          20 :   keys.add("compulsory","SET_MASS","1","mass of the virtual atom");
+     103          20 :   keys.add("compulsory","SET_CHARGE","0","charge of the virtual atom");
+     104          20 :   keys.addFlag("SCALED_COMPONENTS",false,"use scaled components");
+     105          10 : }
+     106             : 
+     107           9 : FixedAtom::FixedAtom(const ActionOptions&ao):
+     108             :   Action(ao),
+     109           9 :   ActionWithVirtualAtom(ao)
+     110             : {
+     111             :   std::vector<AtomNumber> atoms;
+     112          18 :   parseAtomList("ATOMS",atoms);
+     113           9 :   if(atoms.size()!=0) error("ATOMS should be empty");
+     114             : 
+     115          18 :   parseFlag("SCALED_COMPONENTS",scaled_components);
+     116             : 
+     117             :   std::vector<double> at;
+     118          18 :   parseVector("AT",at);
+     119           9 :   if(at.size()!=3) error("AT should be a list of three real numbers");
+     120             : 
+     121           9 :   parse("SET_MASS",mass);
+     122          18 :   parse("SET_CHARGE",charge);
+     123             : 
+     124           9 :   coord[0]=at[0];
+     125           9 :   coord[1]=at[1];
+     126           9 :   coord[2]=at[2];
+     127             : 
+     128           9 :   checkRead();
+     129           9 :   log<<"  AT position "<<coord[0]<<" "<<coord[1]<<" "<<coord[2]<<"\n";
+     130           9 :   if(scaled_components) log<<"  position is in scaled components\n";
+     131           9 : }
+     132             : 
+     133         603 : void FixedAtom::calculate() {
+     134         603 :   std::vector<Tensor> deriv(getNumberOfAtoms());
+     135         603 :   if(scaled_components) {
+     136           5 :     setPosition(getPbc().scaledToReal(coord));
+     137             :   } else {
+     138             :     setPosition(coord);
+     139             :   }
+     140         603 :   setMass(mass);
+     141         603 :   setCharge(charge);
+     142             :   setAtomsDerivatives(deriv);
+     143             : // Virial contribution
+     144         603 :   if(!scaled_components) setBoxDerivativesNoPbc();
+     145             : // notice that with scaled components there is no additional virial contribution
+     146         603 : }
+     147             : 
+     148             : }
+     149             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..be0876720b --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:6969100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom5GhostC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe626createERKNS_13ActionOptionsE3
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE3
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD5vatom5Ghost9calculateEv7
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe62C2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe62D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.func.html b/coverage/vatom/Ghost.cpp.func.html new file mode 100644 index 0000000000..cc1aada44b --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:6969100.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe626createERKNS_13ActionOptionsE3
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe62C2Ev3473
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe62D2Ev3473
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD5vatom5Ghost9calculateEv7
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE3
_ZN4PLMD5vatom5GhostC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.gcov.html b/coverage/vatom/Ghost.cpp.gcov.html new file mode 100644 index 0000000000..ed9ff7669f --- /dev/null +++ b/coverage/vatom/Ghost.cpp.gcov.html @@ -0,0 +1,261 @@ + + + + + + + + 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:6969100.0 %
Date:2024-06-10 08:19:14Functions: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 "ActionWithVirtualAtom.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "tools/Vector.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace vatom {
+      29             : 
+      30             : //+PLUMEDOC VATOM GHOST
+      31             : /*
+      32             : Calculate the absolute position of a ghost atom with fixed coordinates in the local reference frame formed by three atoms.
+      33             : 
+      34             : The computed ghost atom is stored as a virtual atom that can be accessed in
+      35             :  an atom list through the the label for the GHOST action that creates it.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : The following input instructs plumed to print the distance between the
+      40             : ghost atom and the center of mass for atoms 15,20:
+      41             : \plumedfile
+      42             : c1: GHOST ATOMS=1,5,10 COORDINATES=10.0,10.0,10.0
+      43             : c2: COM ATOMS=15,20
+      44             : d1: DISTANCE ATOMS=c1,c2
+      45             : PRINT ARG=d1
+      46             : \endplumedfile
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : 
+      52             : class Ghost:
+      53             :   public ActionWithVirtualAtom
+      54             : {
+      55             :   std::vector<double> coord;
+      56             : public:
+      57             :   explicit Ghost(const ActionOptions&ao);
+      58             :   void calculate() override;
+      59             :   static void registerKeywords( Keywords& keys );
+      60             : };
+      61             : 
+      62       10425 : PLUMED_REGISTER_ACTION(Ghost,"GHOST")
+      63             : 
+      64           4 : void Ghost::registerKeywords(Keywords& keys) {
+      65           4 :   ActionWithVirtualAtom::registerKeywords(keys);
+      66           8 :   keys.add("atoms","COORDINATES","coordinates of the ghost atom in the local reference frame");
+      67           4 : }
+      68             : 
+      69           3 : Ghost::Ghost(const ActionOptions&ao):
+      70             :   Action(ao),
+      71           3 :   ActionWithVirtualAtom(ao)
+      72             : {
+      73             :   std::vector<AtomNumber> atoms;
+      74           6 :   parseAtomList("ATOMS",atoms);
+      75           3 :   if(atoms.size()!=3) error("ATOMS should contain a list of three atoms");
+      76             : 
+      77           6 :   parseVector("COORDINATES",coord);
+      78           3 :   if(coord.size()!=3) error("COORDINATES should be a list of three real numbers");
+      79             : 
+      80           3 :   checkRead();
+      81           3 :   log.printf("  of atoms");
+      82          12 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial());
+      83           3 :   log.printf("\n");
+      84           3 :   requestAtoms(atoms);
+      85           3 : }
+      86             : 
+      87           7 : void Ghost::calculate() {
+      88           7 :   Vector pos;
+      89           7 :   std::vector<Tensor> deriv(getNumberOfAtoms());
+      90             :   std::vector<Vector> n;
+      91             : 
+      92             : // first versor
+      93           7 :   Vector n01 = delta(getPosition(0), getPosition(1));
+      94          14 :   n.push_back(n01/n01.modulo());
+      95             : 
+      96             : // auxiliary vector
+      97           7 :   Vector n02 = delta(getPosition(0), getPosition(2));
+      98             : 
+      99             : // second versor
+     100           7 :   Vector n03 = crossProduct(n[0],n02);
+     101           7 :   double n03_norm = n03.modulo();
+     102          14 :   n.push_back(n03/n03_norm);
+     103             : 
+     104             : // third versor
+     105          14 :   n.push_back(crossProduct(n[0],n[1]));
+     106             : 
+     107             : // origin of the reference system
+     108           7 :   pos = getPosition(0);
+     109             : 
+     110          28 :   for(unsigned i=0; i<3; ++i) {
+     111          21 :     pos += coord[i] * n[i];
+     112             :   }
+     113             : 
+     114             :   setPosition(pos);
+     115             :   setMass(1.0);
+     116             :   setCharge(0.0);
+     117             : 
+     118             : // some useful tensors for derivatives
+     119           7 :   Tensor dn0d0  = (-Tensor::identity()+Tensor(n[0],n[0]))/n01.modulo();
+     120           7 :   Tensor dn0d1  = (+Tensor::identity()-Tensor(n[0],n[0]))/n01.modulo();
+     121           7 :   Tensor dn02d0 = -Tensor::identity();
+     122           7 :   Tensor dn02d2 =  Tensor::identity();
+     123             : 
+     124             : // derivative of n1 = n0 x n02
+     125           7 :   Tensor dn1d0, dn1d1, dn1d2;
+     126           7 :   Vector aux0, aux1, aux2;
+     127             : 
+     128          28 :   for(unsigned j=0; j<3; ++j) {
+     129             : // derivative of n0 x n02 with respect to point 0, coordinate j
+     130          21 :     Vector tmp00  = Vector( dn0d0(j,0),  dn0d0(j,1),  dn0d0(j,2));
+     131          21 :     Vector tmp020 = Vector(dn02d0(j,0), dn02d0(j,1), dn02d0(j,2));
+     132          21 :     Vector tmp0   = crossProduct(tmp00,n02) + crossProduct(n[0],tmp020);
+     133          21 :     aux0[j]       = dotProduct(tmp0,n[1]);
+     134             : // derivative of n0 x n02 with respect to point 1, coordinate j
+     135          21 :     Vector tmp01  = Vector( dn0d1(j,0),  dn0d1(j,1),  dn0d1(j,2));
+     136          21 :     Vector tmp1   = crossProduct(tmp01,n02);
+     137          21 :     aux1[j]       = dotProduct(tmp1,n[1]);
+     138             : // derivative of n0 x n02 with respect to point 2, coordinate j
+     139          21 :     Vector tmp022 = Vector(dn02d2(j,0), dn02d2(j,1), dn02d2(j,2));
+     140          21 :     Vector tmp2   = crossProduct(n[0],tmp022);
+     141          21 :     aux2[j]       = dotProduct(tmp2,n[1]);
+     142             : // derivative of n1 = (n0 x n02) / || (n0 x n02) ||
+     143          84 :     for(unsigned i=0; i<3; ++i) {
+     144          63 :       dn1d0(j,i) = ( tmp0[i] - aux0[j] * n[1][i] ) / n03_norm;
+     145          63 :       dn1d1(j,i) = ( tmp1[i] - aux1[j] * n[1][i] ) / n03_norm;
+     146          63 :       dn1d2(j,i) = ( tmp2[i] - aux2[j] * n[1][i] ) / n03_norm;
+     147             :     }
+     148             :   }
+     149             : 
+     150             : // Derivative of the last versor n2 = n0 x n1 =  ( n0( n0 n02 ) - n02 ) / || n0 x n02 ||
+     151             : // Scalar product and derivatives
+     152           7 :   double n0_n02 = dotProduct(n[0],n02);
+     153           7 :   Vector dn0_n02d0, dn0_n02d1, dn0_n02d2;
+     154             : 
+     155          28 :   for(unsigned j=0; j<3; ++j) {
+     156          84 :     for(unsigned i=0; i<3; ++i) {
+     157          63 :       dn0_n02d0[j] += dn0d0(j,i)*n02[i] + n[0][i]*dn02d0(j,i);
+     158          63 :       dn0_n02d1[j] += dn0d1(j,i)*n02[i];
+     159          63 :       dn0_n02d2[j] +=                     n[0][i]*dn02d2(j,i);
+     160             :     }
+     161             :   }
+     162             : 
+     163           7 :   Tensor dn2d0, dn2d1, dn2d2;
+     164          28 :   for(unsigned j=0; j<3; ++j) {
+     165          84 :     for(unsigned i=0; i<3; ++i) {
+     166          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;
+     167          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;
+     168          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;
+     169             :     }
+     170             :   }
+     171             : 
+     172             : // Finally, the derivative tensor
+     173           7 :   deriv[0] = Tensor::identity() + coord[0]*dn0d0 + coord[1]*dn1d0 + coord[2]*dn2d0;
+     174           7 :   deriv[1] =                      coord[0]*dn0d1 + coord[1]*dn1d1 + coord[2]*dn2d1;
+     175           7 :   deriv[2] =                                       coord[1]*dn1d2 + coord[2]*dn2d2;
+     176             : 
+     177             :   setAtomsDerivatives(deriv);
+     178             : 
+     179             : // Virial contribution
+     180           7 :   setBoxDerivativesNoPbc();
+     181           7 : }
+     182             : 
+     183             : }
+     184             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vatom/index-sort-f.html b/coverage/vatom/index-sort-f.html new file mode 100644 index 0000000000..4f914493f9 --- /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:20520699.5 %
Date:2024-06-10 08:19:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Ghost.cpp +
100.0%
+
100.0 %69 / 6985.7 %6 / 7
FixedAtom.cpp +
100.0%
+
100.0 %32 / 3285.7 %6 / 7
Center.cpp +
99.0%99.0%
+
99.0 %104 / 10590.0 %9 / 10
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vatom/index-sort-l.html b/coverage/vatom/index-sort-l.html new file mode 100644 index 0000000000..40acba3a52 --- /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:20520699.5 %
Date:2024-06-10 08:19:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Center.cpp +
99.0%99.0%
+
99.0 %104 / 10590.0 %9 / 10
FixedAtom.cpp +
100.0%
+
100.0 %32 / 3285.7 %6 / 7
Ghost.cpp +
100.0%
+
100.0 %69 / 6985.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vatom/index.html b/coverage/vatom/index.html new file mode 100644 index 0000000000..ded1eef822 --- /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:20520699.5 %
Date:2024-06-10 08:19:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Center.cpp +
99.0%99.0%
+
99.0 %104 / 10590.0 %9 / 10
FixedAtom.cpp +
100.0%
+
100.0 %32 / 3285.7 %6 / 7
Ghost.cpp +
100.0%
+
100.0 %69 / 6985.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..2fc1f08d5c --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Chebyshev21setupUniformIntegralsEv3
_ZN4PLMD3ves12BF_ChebyshevC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe996createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12BF_Chebyshev16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe99C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe99D2Ev3473
_ZNK4PLMD3ves12BF_Chebyshev12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_7882
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.func.html b/coverage/ves/BF_Chebyshev.cpp.func.html new file mode 100644 index 0000000000..98f01ade1c --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Chebyshev16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves12BF_Chebyshev21setupUniformIntegralsEv3
_ZN4PLMD3ves12BF_ChebyshevC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe996createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe99C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe99D2Ev3473
_ZNK4PLMD3ves12BF_Chebyshev12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_7882
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.gcov.html b/coverage/ves/BF_Chebyshev.cpp.gcov.html new file mode 100644 index 0000000000..6131020b73 --- /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:3636100.0 %
Date:2024-06-10 08:19:14Functions:77100.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       10423 : PLUMED_REGISTER_ACTION(BF_Chebyshev,"BF_CHEBYSHEV")
+     100             : 
+     101             : 
+     102           5 : void BF_Chebyshev::registerKeywords(Keywords& keys) {
+     103           5 :   BasisFunctions::registerKeywords(keys);
+     104           5 : }
+     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.15
+
+ + + 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 0000000000..38fce0a636 --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:646697.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Combined11setupLabelsEv2
_ZN4PLMD3ves11BF_Combined21setupUniformIntegralsEv2
_ZN4PLMD3ves11BF_CombinedC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe776createERKNS_13ActionOptionsE2
_ZN4PLMD3ves11BF_Combined16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe77C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe77D2Ev3473
_ZNK4PLMD3ves11BF_Combined12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3616
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.func.html b/coverage/ves/BF_Combined.cpp.func.html new file mode 100644 index 0000000000..46eae79221 --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:646697.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Combined11setupLabelsEv2
_ZN4PLMD3ves11BF_Combined16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves11BF_Combined21setupUniformIntegralsEv2
_ZN4PLMD3ves11BF_CombinedC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe776createERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe77C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe77D2Ev3473
_ZNK4PLMD3ves11BF_Combined12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3616
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.gcov.html b/coverage/ves/BF_Combined.cpp.gcov.html new file mode 100644 index 0000000000..18e07129ac --- /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:646697.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(BF_Combined,"BF_COMBINED")
+      78             : 
+      79             : 
+      80           3 : void BF_Combined::registerKeywords(Keywords& keys) {
+      81           3 :   BasisFunctions::registerKeywords(keys);
+      82           3 :   keys.remove("ORDER");
+      83           3 :   keys.remove("MAXIMUM");
+      84           3 :   keys.remove("MINIMUM");
+      85           3 :   keys.remove("NUMERICAL_INTEGRALS");
+      86           3 :   keys.remove("NGRID_POINTS");
+      87           6 :   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           3 : }
+      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.15
+
+ + + 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 0000000000..416900c410 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Cosine21setupUniformIntegralsEv3
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe946createERKNS_13ActionOptionsE4
_ZN4PLMD3ves9BF_Cosine11setupLabelsEv4
_ZN4PLMD3ves9BF_CosineC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9BF_Cosine16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe94C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe94D2Ev3473
_ZNK4PLMD3ves9BF_Cosine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.func.html b/coverage/ves/BF_Cosine.cpp.func.html new file mode 100644 index 0000000000..500ba918d4 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe946createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe94C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe94D2Ev3473
_ZN4PLMD3ves9BF_Cosine11setupLabelsEv4
_ZN4PLMD3ves9BF_Cosine16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves9BF_Cosine21setupUniformIntegralsEv3
_ZN4PLMD3ves9BF_CosineC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves9BF_Cosine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.gcov.html b/coverage/ves/BF_Cosine.cpp.gcov.html new file mode 100644 index 0000000000..f3ecac41e1 --- /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:3636100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_ACTION(BF_Cosine,"BF_COSINE")
+      95             : 
+      96             : 
+      97           5 : void BF_Cosine::registerKeywords(Keywords& keys) {
+      98           5 :   BasisFunctions::registerKeywords(keys);
+      99           5 : }
+     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.15
+
+ + + 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 0000000000..825683d565 --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:5959100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe996createERKNS_13ActionOptionsE3
_ZN4PLMD3ves16BF_CubicBsplinesC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves16BF_CubicBsplines16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe99C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe99D2Ev3473
_ZNK4PLMD3ves16BF_CubicBsplines12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
_ZNK4PLMD3ves16BF_CubicBsplines6splineEdRd202807
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.func.html b/coverage/ves/BF_CubicBsplines.cpp.func.html new file mode 100644 index 0000000000..7cf326d20d --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:5959100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe996createERKNS_13ActionOptionsE3
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe99C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe99D2Ev3473
_ZN4PLMD3ves16BF_CubicBsplines16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves16BF_CubicBsplinesC2ERKNS_13ActionOptionsE3
_ZNK4PLMD3ves16BF_CubicBsplines12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
_ZNK4PLMD3ves16BF_CubicBsplines6splineEdRd202807
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.gcov.html b/coverage/ves/BF_CubicBsplines.cpp.gcov.html new file mode 100644 index 0000000000..b70afc38c7 --- /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:5959100.0 %
Date:2024-06-10 08:19:14Functions:77100.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       10422 : 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           4 : void BF_CubicBsplines::registerKeywords(Keywords& keys) {
+     105           4 :   BasisFunctions::registerKeywords(keys);
+     106           8 :   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           8 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     108           4 :   keys.remove("NUMERICAL_INTEGRALS");
+     109           4 : }
+     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           9 :   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.15
+
+ + + 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 0000000000..2fe37e9c18 --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:12615382.4 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe1266createERKNS_13ActionOptionsE10
_ZN4PLMD3ves9BF_CustomC2ERKNS_13ActionOptionsE10
_ZN4PLMD3ves9BF_CustomD0Ev10
_ZN4PLMD3ves9BF_CustomD2Ev10
_ZN4PLMD3ves9BF_Custom16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe126C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe126D2Ev3473
_ZNK4PLMD3ves9BF_Custom12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_24204
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.func.html b/coverage/ves/BF_Custom.cpp.func.html new file mode 100644 index 0000000000..22fecd5f0c --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:12615382.4 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe1266createERKNS_13ActionOptionsE10
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe126C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe126D2Ev3473
_ZN4PLMD3ves9BF_Custom16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves9BF_CustomC2ERKNS_13ActionOptionsE10
_ZN4PLMD3ves9BF_CustomD0Ev10
_ZN4PLMD3ves9BF_CustomD2Ev10
_ZNK4PLMD3ves9BF_Custom12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_24204
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.gcov.html b/coverage/ves/BF_Custom.cpp.gcov.html new file mode 100644 index 0000000000..b11fc0ef88 --- /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:12615382.4 %
Date:2024-06-10 08:19:14Functions: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 "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       10429 : PLUMED_REGISTER_ACTION(BF_Custom,"BF_CUSTOM")
+     127             : 
+     128          11 : void BF_Custom::registerKeywords(Keywords& keys) {
+     129          11 :   BasisFunctions::registerKeywords(keys);
+     130          11 :   keys.remove("ORDER");
+     131          22 :   keys.add("numbered","FUNC","The basis functions f_i(x) given in mathematical expressions using _x_ as a variable.");
+     132          22 :   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          22 :   keys.addFlag("PERIODIC",false,"Indicate that the basis functions are periodic.");
+     134          22 :   keys.addFlag("CHECK_NAN_INF",false,"Check that the basis functions do not result in a not a number (nan) or infinity (inf).");
+     135          11 :   keys.remove("NUMERICAL_INTEGRALS");
+     136          11 : }
+     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          14 :     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.15
+
+ + + 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 0000000000..aded706424 --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3939100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10BF_Fourier21setupUniformIntegralsEv94
_ZN4PLMD3ves10BF_Fourier11setupLabelsEv95
_ZN4PLMD3ves10BF_FourierC2ERKNS_13ActionOptionsE95
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe956createERKNS_13ActionOptionsE95
_ZN4PLMD3ves10BF_Fourier16registerKeywordsERNS_8KeywordsE96
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe95C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe95D2Ev3473
_ZNK4PLMD3ves10BF_Fourier12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3244265
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.func.html b/coverage/ves/BF_Fourier.cpp.func.html new file mode 100644 index 0000000000..4db5d317c9 --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3939100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10BF_Fourier11setupLabelsEv95
_ZN4PLMD3ves10BF_Fourier16registerKeywordsERNS_8KeywordsE96
_ZN4PLMD3ves10BF_Fourier21setupUniformIntegralsEv94
_ZN4PLMD3ves10BF_FourierC2ERKNS_13ActionOptionsE95
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe956createERKNS_13ActionOptionsE95
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe95C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe95D2Ev3473
_ZNK4PLMD3ves10BF_Fourier12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3244265
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.gcov.html b/coverage/ves/BF_Fourier.cpp.gcov.html new file mode 100644 index 0000000000..60160be8f2 --- /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:3939100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10514 : PLUMED_REGISTER_ACTION(BF_Fourier,"BF_FOURIER")
+      96             : 
+      97             : 
+      98          96 : void BF_Fourier::registerKeywords(Keywords& keys) {
+      99          96 :   BasisFunctions::registerKeywords(keys);
+     100          96 : }
+     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.15
+
+ + + 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 0000000000..8d7725f9f2 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:5353100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Gaussians11setupLabelsEv3
_ZN4PLMD3ves12BF_GaussiansC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe1146createERKNS_13ActionOptionsE3
_ZN4PLMD3ves12BF_Gaussians16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe114C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe114D2Ev3473
_ZNK4PLMD3ves12BF_Gaussians12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.func.html b/coverage/ves/BF_Gaussians.cpp.func.html new file mode 100644 index 0000000000..52cf8df7b9 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:5353100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Gaussians11setupLabelsEv3
_ZN4PLMD3ves12BF_Gaussians16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves12BF_GaussiansC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe1146createERKNS_13ActionOptionsE3
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe114C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe114D2Ev3473
_ZNK4PLMD3ves12BF_Gaussians12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.gcov.html b/coverage/ves/BF_Gaussians.cpp.gcov.html new file mode 100644 index 0000000000..9220eebc0d --- /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:5353100.0 %
Date:2024-06-10 08:19:14Functions:77100.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       10422 : PLUMED_REGISTER_ACTION(BF_Gaussians,"BF_GAUSSIANS")
+     115             : 
+     116             : 
+     117           4 : void BF_Gaussians::registerKeywords(Keywords& keys) {
+     118           4 :   BasisFunctions::registerKeywords(keys);
+     119           8 :   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           8 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     121           4 :   keys.remove("NUMERICAL_INTEGRALS");
+     122           4 : }
+     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           9 :   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.15
+
+ + + 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 0000000000..87bb6e4c3e --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Legendre21setupUniformIntegralsEv59
_ZN4PLMD3ves11BF_LegendreC2ERKNS_13ActionOptionsE61
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe1066createERKNS_13ActionOptionsE61
_ZN4PLMD3ves11BF_Legendre16registerKeywordsERNS_8KeywordsE62
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe106C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe106D2Ev3473
_ZNK4PLMD3ves11BF_Legendre12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_1625057
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.func.html b/coverage/ves/BF_Legendre.cpp.func.html new file mode 100644 index 0000000000..cb04c5e0a3 --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:4343100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Legendre16registerKeywordsERNS_8KeywordsE62
_ZN4PLMD3ves11BF_Legendre21setupUniformIntegralsEv59
_ZN4PLMD3ves11BF_LegendreC2ERKNS_13ActionOptionsE61
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe1066createERKNS_13ActionOptionsE61
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe106C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe106D2Ev3473
_ZNK4PLMD3ves11BF_Legendre12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_1625057
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.gcov.html b/coverage/ves/BF_Legendre.cpp.gcov.html new file mode 100644 index 0000000000..7dd2557386 --- /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:4343100.0 %
Date:2024-06-10 08:19:14Functions:77100.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       10480 : PLUMED_REGISTER_ACTION(BF_Legendre,"BF_LEGENDRE")
+     107             : 
+     108             : 
+     109          62 : void BF_Legendre::registerKeywords(Keywords& keys) {
+     110          62 :   BasisFunctions::registerKeywords(keys);
+     111         124 :   keys.addFlag("SCALED",false,"Scale the polynomials such that they are orthonormal to 1.");
+     112          62 : }
+     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.15
+
+ + + 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 0000000000..141335859c --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe906createERKNS_13ActionOptionsE16
_ZN4PLMD3ves9BF_Powers11setupLabelsEv16
_ZN4PLMD3ves9BF_PowersC2ERKNS_13ActionOptionsE16
_ZN4PLMD3ves9BF_Powers16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe90C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe90D2Ev3473
_ZNK4PLMD3ves9BF_Powers12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_842119
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.func.html b/coverage/ves/BF_Powers.cpp.func.html new file mode 100644 index 0000000000..c98612d149 --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe906createERKNS_13ActionOptionsE16
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe90C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe90D2Ev3473
_ZN4PLMD3ves9BF_Powers11setupLabelsEv16
_ZN4PLMD3ves9BF_Powers16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD3ves9BF_PowersC2ERKNS_13ActionOptionsE16
_ZNK4PLMD3ves9BF_Powers12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_842119
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.gcov.html b/coverage/ves/BF_Powers.cpp.gcov.html new file mode 100644 index 0000000000..c2f76ecc3e --- /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:3636100.0 %
Date:2024-06-10 08:19:14Functions:77100.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       10435 : PLUMED_REGISTER_ACTION(BF_Powers,"BF_POWERS")
+      91             : 
+      92             : 
+      93          17 : void BF_Powers::registerKeywords(Keywords& keys) {
+      94          17 :   BasisFunctions::registerKeywords(keys);
+      95          34 :   keys.add("optional","NORMALIZATION","The normalization factor that is used to normalize the basis functions. By default it is 1.0.");
+      96          17 :   keys.remove("NUMERICAL_INTEGRALS");
+      97          17 : }
+      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.15
+
+ + + 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 0000000000..c0d7fd9cdc --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7BF_Sine21setupUniformIntegralsEv3
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe936createERKNS_13ActionOptionsE4
_ZN4PLMD3ves7BF_Sine11setupLabelsEv4
_ZN4PLMD3ves7BF_SineC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves7BF_Sine16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe93C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe93D2Ev3473
_ZNK4PLMD3ves7BF_Sine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.func.html b/coverage/ves/BF_Sine.cpp.func.html new file mode 100644 index 0000000000..5c2d2747e7 --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:3636100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe936createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe93C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe93D2Ev3473
_ZN4PLMD3ves7BF_Sine11setupLabelsEv4
_ZN4PLMD3ves7BF_Sine16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves7BF_Sine21setupUniformIntegralsEv3
_ZN4PLMD3ves7BF_SineC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves7BF_Sine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.gcov.html b/coverage/ves/BF_Sine.cpp.gcov.html new file mode 100644 index 0000000000..ad911c76f5 --- /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:3636100.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_ACTION(BF_Sine,"BF_SINE")
+      94             : 
+      95             : 
+      96           5 : void BF_Sine::registerKeywords(Keywords& keys) {
+      97           5 :   BasisFunctions::registerKeywords(keys);
+      98           5 : }
+      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.15
+
+ + + 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 0000000000..0c4f27af78 --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:119119100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Wavelets15getCutoffPointsERKd2
_ZN4PLMD3ves11BF_Wavelets11setupLabelsEv47
_ZN4PLMD3ves11BF_WaveletsC2ERKNS_13ActionOptionsE47
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe2186createERKNS_13ActionOptionsE47
_ZN4PLMD3ves11BF_Wavelets16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe218C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe218D2Ev3473
_ZNK4PLMD3ves11BF_Wavelets12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_62249
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.func.html b/coverage/ves/BF_Wavelets.cpp.func.html new file mode 100644 index 0000000000..8645b50aeb --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:119119100.0 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Wavelets11setupLabelsEv47
_ZN4PLMD3ves11BF_Wavelets15getCutoffPointsERKd2
_ZN4PLMD3ves11BF_Wavelets16registerKeywordsERNS_8KeywordsE48
_ZN4PLMD3ves11BF_WaveletsC2ERKNS_13ActionOptionsE47
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe2186createERKNS_13ActionOptionsE47
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe218C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe218D2Ev3473
_ZNK4PLMD3ves11BF_Wavelets12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_62249
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.gcov.html b/coverage/ves/BF_Wavelets.cpp.gcov.html new file mode 100644 index 0000000000..29e7eab537 --- /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:119119100.0 %
Date:2024-06-10 08:19:14Functions: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             : 
+      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       10466 : PLUMED_REGISTER_ACTION(BF_Wavelets,"BF_WAVELETS")
+     219             : 
+     220             : 
+     221          48 : void BF_Wavelets::registerKeywords(Keywords& keys) {
+     222          48 :   BasisFunctions::registerKeywords(keys);
+     223          96 :   keys.add("compulsory","TYPE","Specify the wavelet type. Currently available are \"DAUBECHIES\" Wavelets with minimum phase and the more symmetric \"SYMLETS\"");
+     224          96 :   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          96 :   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          96 :   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          96 :   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          96 :   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          96 :   keys.addFlag("DUMP_WAVELET_GRID", false, "If this flag is set the grid with the wavelet values will be written to a file called \"wavelet_grid.data\".");
+     230         144 :   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          96 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     232          48 :   keys.remove("NUMERICAL_INTEGRALS");
+     233          48 : }
+     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     2527708 :       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.15
+
+ + + 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 0000000000..3072cf20fc --- /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:22425587.8 %
Date:2024-06-10 08:19:14Functions: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
_ZN4PLMD3ves14BasisFunctions16registerKeywordsERNS_8KeywordsE260
_ZNK4PLMD3ves14BasisFunctions44numericalTargetDistributionIntegralsFromGridEPKNS_4GridE261
_ZNK4PLMD3ves14BasisFunctions8getValueEdjRdRb261
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.func.html b/coverage/ves/BasisFunctions.cpp.func.html new file mode 100644 index 0000000000..c0ff8eb624 --- /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:22425587.8 %
Date:2024-06-10 08:19:14Functions: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_8KeywordsE260
_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.15
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.gcov.html b/coverage/ves/BasisFunctions.cpp.gcov.html new file mode 100644 index 0000000000..d3ca0c9fca --- /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:22425587.8 %
Date:2024-06-10 08:19:14Functions: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         260 : void BasisFunctions::registerKeywords(Keywords& keys) {
+      37         260 :   Action::registerKeywords(keys);
+      38         520 :   keys.add("compulsory","ORDER","The order of the basis function expansion.");
+      39         520 :   keys.add("compulsory","MINIMUM","The minimum of the interval on which the basis functions are defined.");
+      40         520 :   keys.add("compulsory","MAXIMUM","The maximum of the interval on which the basis functions are defined.");
+      41         520 :   keys.add("hidden","NGRID_POINTS","The number of grid points used for numerical integrals");
+      42         520 :   keys.addFlag("DEBUG_INFO",false,"Print out more detailed information about the basis set. Useful for debugging.");
+      43         520 :   keys.addFlag("NUMERICAL_INTEGRALS",false,"Calculate basis function integral for the uniform distribution numerically. Useful for debugging.");
+      44         260 : }
+      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          71 :   values.clear();
+     330          71 :   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       45896 :     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         213 :   ofile_values.addConstantField("bf_keywords").printField("bf_keywords","{"+getKeywordString()+"}");
+     365         213 :   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         213 :   ofile_values.addConstantField("nbins").printField("nbins",static_cast<int>(args_grid.getNbin()[0]));
+     374         213 :   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.15
+
+ + + 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 0000000000..b161305f31 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.func.html b/coverage/ves/BasisFunctions.h.func.html new file mode 100644 index 0000000000..13ec40846a --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.gcov.html b/coverage/ves/BasisFunctions.h.gcov.html new file mode 100644 index 0000000000..ae6db912c6 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..e166e90911 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.func.html b/coverage/ves/CoeffsBase.cpp.func.html new file mode 100644 index 0000000000..431e8f0024 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.gcov.html b/coverage/ves/CoeffsBase.cpp.gcov.html new file mode 100644 index 0000000000..e1215a6e6c --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..c8eb83c445 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves10CoeffsBase8getIndexERKSt6vectorIjSaIjEE10870
_ZNK4PLMD3ves10CoeffsBase10getIndicesEm237974265
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.func.html b/coverage/ves/CoeffsBase.h.func.html new file mode 100644 index 0000000000..7fce1ccd14 --- /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-06-10 08:19:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves10CoeffsBase10getIndicesEm237974265
_ZNK4PLMD3ves10CoeffsBase8getIndexERKSt6vectorIjSaIjEE10870
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.gcov.html b/coverage/ves/CoeffsBase.h.gcov.html new file mode 100644 index 0000000000..861fd5ffcc --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..51fefa30c4 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.func.html b/coverage/ves/CoeffsMatrix.cpp.func.html new file mode 100644 index 0000000000..7842130973 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.gcov.html b/coverage/ves/CoeffsMatrix.cpp.gcov.html new file mode 100644 index 0000000000..614579cc35 --- /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-06-10 08:19:14Functions: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         344 : 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::sprintf(s1.data(),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::sprintf(s1.data(),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::sprintf(s1.data(),int_fmt.c_str(),i);
+     699           0 :       ofile.printField(field_index_row,s1.data());
+     700             :       std::sprintf(s1.data(),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.15
+
+ + + 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 0000000000..c87171c7d9 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.func.html b/coverage/ves/CoeffsMatrix.h.func.html new file mode 100644 index 0000000000..6d8a1045cf --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.gcov.html b/coverage/ves/CoeffsMatrix.h.gcov.html new file mode 100644 index 0000000000..059f6ab846 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..0dafa1d787 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.func.html b/coverage/ves/CoeffsVector.cpp.func.html new file mode 100644 index 0000000000..1247bde74e --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.gcov.html b/coverage/ves/CoeffsVector.cpp.gcov.html new file mode 100644 index 0000000000..8053ceed50 --- /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-06-10 08:19:14Functions: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      683924 : 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::sprintf(s1.data(),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::sprintf(s1.data(),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.15
+
+ + + 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 0000000000..9df56a0e18 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.func.html b/coverage/ves/CoeffsVector.h.func.html new file mode 100644 index 0000000000..dc63356952 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.gcov.html b/coverage/ves/CoeffsVector.h.gcov.html new file mode 100644 index 0000000000..8256e194f6 --- /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-06-10 08:19:14Functions: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   142877485 :   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.15
+
+ + + 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 0000000000..c754272132 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.func.html b/coverage/ves/FermiSwitchingFunction.cpp.func.html new file mode 100644 index 0000000000..c4e6ef088a --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.gcov.html b/coverage/ves/FermiSwitchingFunction.cpp.gcov.html new file mode 100644 index 0000000000..9e9a65d22e --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..bca8f1ab2f --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.func.html b/coverage/ves/GridIntegrationWeights.cpp.func.html new file mode 100644 index 0000000000..dd71a7abdb --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.gcov.html b/coverage/ves/GridIntegrationWeights.cpp.gcov.html new file mode 100644 index 0000000000..5906c926a9 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..25b2712feb --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.func.html b/coverage/ves/GridLinearInterpolation.cpp.func.html new file mode 100644 index 0000000000..bd616041ff --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.gcov.html b/coverage/ves/GridLinearInterpolation.cpp.gcov.html new file mode 100644 index 0000000000..e451777bc1 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..0ed030b657 --- /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-06-10 08:19:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation24multiLinearInterpolationERKSt6vectorIdSaIdEERKS2_IS4_SaIS4_EERS4_d0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.func.html b/coverage/ves/GridLinearInterpolation.h.func.html new file mode 100644 index 0000000000..d5f481fe31 --- /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-06-10 08:19:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation24multiLinearInterpolationERKSt6vectorIdSaIdEERKS2_IS4_SaIS4_EERS4_d0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.gcov.html b/coverage/ves/GridLinearInterpolation.h.gcov.html new file mode 100644 index 0000000000..e1bbb13162 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..c718562272 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14MarginalWeight16projectOuterLoopERd2822
_ZN4PLMD3ves9FesWeight16projectOuterLoopERd5834
_ZN4PLMD3ves14MarginalWeight16projectInnerLoopERdS2_284402
_ZN4PLMD3ves9FesWeight16projectInnerLoopERdS2_703214
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.func.html b/coverage/ves/GridProjWeights.h.func.html new file mode 100644 index 0000000000..711c39ff1c --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14MarginalWeight16projectInnerLoopERdS2_284402
_ZN4PLMD3ves14MarginalWeight16projectOuterLoopERd2822
_ZN4PLMD3ves9FesWeight16projectInnerLoopERdS2_703214
_ZN4PLMD3ves9FesWeight16projectOuterLoopERd5834
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.gcov.html b/coverage/ves/GridProjWeights.h.gcov.html new file mode 100644 index 0000000000..2086310788 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..04ec2e1127 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.func.html b/coverage/ves/LinearBasisSetExpansion.cpp.func.html new file mode 100644 index 0000000000..80dffd0e37 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html b/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html new file mode 100644 index 0000000000..4bf9b3c324 --- /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-06-10 08:19:14Functions: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         260 :   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         260 : }
+     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           9 :     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.15
+
+ + + 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 0000000000..dfaba0d0f2 --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion19getBasisSetConstantEv408
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_b862315
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_1988037
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.func.html b/coverage/ves/LinearBasisSetExpansion.h.func.html new file mode 100644 index 0000000000..813d1bb543 --- /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-06-10 08:19:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_1988037
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_b862315
_ZN4PLMD3ves23LinearBasisSetExpansion19getBasisSetConstantEv408
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.gcov.html b/coverage/ves/LinearBasisSetExpansion.h.gcov.html new file mode 100644 index 0000000000..fc2a3b9bc6 --- /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-06-10 08:19:14Functions: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 int step_of_last_biasgrid_update;
+      78             :   long int step_of_last_biaswithoutcutoffgrid_update;
+      79             :   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 int step) {step_of_last_biasgrid_update = step;}
+     139         712 :   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 int step) {step_of_last_biaswithoutcutoffgrid_update = step;}
+     145          27 :   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 int step) {step_of_last_fesgrid_update = step;}
+     155         539 :   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.15
+
+ + + 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 0000000000..e19d5c4c72 --- /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:32633697.0 %
Date:2024-06-10 08:19:14Functions: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
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeC2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev3473
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD3ves21MD_LinearExpansionPES11calc_energyERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EERS6_3939
_ZN4PLMD3ves21MD_LinearExpansionPES9calc_tempERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE3939
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.func.html b/coverage/ves/MD_LinearExpansionPES.cpp.func.html new file mode 100644 index 0000000000..322896d708 --- /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:32633697.0 %
Date:2024-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMe6createERKNS_13CLToolOptionsE44
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeC2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev3473
_ZN4PLMD3ves21MD_LinearExpansionPES11calc_energyERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EERS6_3939
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE3473
_ZN4PLMD3ves21MD_LinearExpansionPES4mainEP8_IO_FILES3_RNS_12CommunicatorE40
_ZN4PLMD3ves21MD_LinearExpansionPES9calc_tempERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE3939
_ZN4PLMD3ves21MD_LinearExpansionPESC2ERKNS_13CLToolOptionsE44
_ZNK4PLMD3ves21MD_LinearExpansionPES11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html b/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html new file mode 100644 index 0000000000..ee5d18848c --- /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:32633697.0 %
Date:2024-06-10 08:19:14Functions: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 "cltools/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       10463 : PLUMED_REGISTER_CLTOOL(MD_LinearExpansionPES,"ves_md_linearexpansion")
+     151             : 
+     152        3473 : void MD_LinearExpansionPES::registerKeywords( Keywords& keys ) {
+     153        3473 :   CLTool::registerKeywords( keys );
+     154        6946 :   keys.add("compulsory","nstep","10","The number of steps of dynamics you want to run.");
+     155        6946 :   keys.add("compulsory","tstep","0.005","The integration timestep.");
+     156        6946 :   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        6946 :   keys.add("compulsory","friction","10.","The friction of the Langevin thermostat. For multiple replica you can give a separate value for each replica.");
+     158        6946 :   keys.add("compulsory","random_seed","5293818","Value of random number seed.");
+     159        6946 :   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        6946 :   keys.add("compulsory","dimension","1","Number of dimensions, supports 1 to 3.");
+     161       10419 :   keys.add("compulsory","initial_position","Initial position of the particle. For multiple replica you can give a separate value for each replica.");
+     162        6946 :   keys.add("compulsory","replicas","1","Number of replicas.");
+     163       10419 :   keys.add("compulsory","basis_functions_1","Basis functions for dimension 1.");
+     164       10419 :   keys.add("optional","basis_functions_2","Basis functions for dimension 2 if needed.");
+     165       10419 :   keys.add("optional","basis_functions_3","Basis functions for dimension 3 if needed.");
+     166       10419 :   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       10419 :   keys.add("compulsory","output_coeffs","potential-coeffs.out.data","Filename of the output coefficient file for the potential.");
+     168       10419 :   keys.add("compulsory","output_coeffs_fmt","%30.16e","Format of the output coefficient file for the potential. Useful for regtests.");
+     169       10419 :   keys.add("optional","coeffs_prefactor","prefactor for multiplying the coefficients with. For multiple replica you can give a separate value for each replica.");
+     170       10419 :   keys.add("optional","template_coeffs_file","only generate a template coefficient file with the filename given and exit.");
+     171       10419 :   keys.add("compulsory","output_potential_grid","100","The number of grid points used for the potential and histogram output files.");
+     172       10419 :   keys.add("compulsory","output_potential","potential.data","Filename of the potential output file.");
+     173       10419 :   keys.add("compulsory","output_histogram","histogram.data","Filename of the histogram output file.");
+     174        3473 : }
+     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             :   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          40 :   auto plumed_bf = Tools::make_unique<PLMD::PlumedMain>();
+     327          40 :   unsigned int nn=1;
+     328          80 :   plumed_bf->cmd("setNatoms",&nn);
+     329          80 :   plumed_bf->cmd("setLog",file_dummy);
+     330          80 :   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                       %u\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          78 :   plumed=Tools::make_unique<PLMD::PlumedMain>();
+     512             : 
+     513             : 
+     514             : 
+     515          39 :   if(plumed) {
+     516          39 :     int s=sizeof(double);
+     517          78 :     plumed->cmd("setRealPrecision",&s);
+     518          39 :     if(replicas>1) {
+     519          31 :       if (Communicator::initialized()) {
+     520          93 :         plumed->cmd("GREX setMPIIntracomm",&intra.Get_comm());
+     521          31 :         if (intra.Get_rank()==0) {
+     522          93 :           plumed->cmd("GREX setMPIIntercomm",&inter.Get_comm());
+     523             :         }
+     524          62 :         plumed->cmd("GREX init");
+     525          93 :         plumed->cmd("setMPIComm",&intra.Get_comm());
+     526             :       } else {
+     527           0 :         error("More than 1 replica but no MPI");
+     528             :       }
+     529             :     } else {
+     530          12 :       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          78 :     plumed->cmd("setNoVirial");
+     549          39 :     int natoms=1;
+     550          78 :     plumed->cmd("setNatoms",&natoms);
+     551          78 :     plumed->cmd("setMDEngine","mdrunner_linearexpansion");
+     552          78 :     plumed->cmd("setTimestep",&tstep);
+     553          78 :     plumed->cmd("setPlumedDat",plumed_input.c_str());
+     554          78 :     plumed->cmd("setLogFile",plumed_logfile.c_str());
+     555          78 :     plumed->cmd("setKbT",&temp);
+     556          39 :     double energyunits=1.0;
+     557          78 :     plumed->cmd("setMDEnergyUnits",&energyunits);
+     558          78 :     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 :     int step_tmp = 0;
+     596          78 :     plumed->cmd("setStep",&step_tmp);
+     597          78 :     plumed->cmd("setMasses",&masses[0]);
+     598          78 :     plumed->cmd("setForces",&forces[0][0]);
+     599          78 :     plumed->cmd("setEnergy",&potential);
+     600          78 :     plumed->cmd("setPositions",&positions[0][0]);
+     601          78 :     plumed->cmd("calc");
+     602             :   }
+     603             : 
+     604        3939 :   for(unsigned int istep=0; istep<nsteps; ++istep) {
+     605             :     //if( istep%20==0 && pc.Get_rank()==0 ) printf("Doing step %d\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 :       int istepplusone=istep+1;
+     640        3900 :       plumedWantsToStop=0;
+     641        7800 :       plumed->cmd("setStep",&istepplusone);
+     642        7800 :       plumed->cmd("setMasses",&masses[0]);
+     643        7800 :       plumed->cmd("setForces",&forces[0][0]);
+     644        7800 :       plumed->cmd("setEnergy",&potential);
+     645        7800 :       plumed->cmd("setPositions",&positions[0][0]);
+     646        7800 :       plumed->cmd("setStopFlag",&plumedWantsToStop);
+     647        7800 :       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,"%u %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.15
+
+ + + 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 0000000000..0e1f0f5543 --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:687393.2 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8Opt_AdamC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe756createERKNS_13ActionOptionsE2
_ZN4PLMD3ves8Opt_AdamC1ERKNS_13ActionOptionsE2
_ZN4PLMD3ves8Opt_Adam16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves8Opt_Adam12coeffsUpdateEj20
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe75C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe75D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.func.html b/coverage/ves/Opt_Adam.cpp.func.html new file mode 100644 index 0000000000..e5c2656f3a --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:687393.2 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe756createERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe75C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe75D2Ev3473
_ZN4PLMD3ves8Opt_Adam12coeffsUpdateEj20
_ZN4PLMD3ves8Opt_Adam16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves8Opt_AdamC1ERKNS_13ActionOptionsE2
_ZN4PLMD3ves8Opt_AdamC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.gcov.html b/coverage/ves/Opt_Adam.cpp.gcov.html new file mode 100644 index 0000000000..7f680c5bcd --- /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:687393.2 %
Date:2024-06-10 08:19:14Functions: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 "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       10423 : PLUMED_REGISTER_ACTION(Opt_Adam,"OPT_ADAM")
+      76             : 
+      77             : 
+      78           3 : void Opt_Adam::registerKeywords(Keywords& keys) {
+      79           3 :   Optimizer::registerKeywords(keys);
+      80           3 :   Optimizer::useFixedStepSizeKeywords(keys);
+      81           3 :   Optimizer::useMultipleWalkersKeywords(keys);
+      82           3 :   Optimizer::useMaskKeywords(keys);
+      83           3 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+      84           6 :   keys.add("optional","BETA_1","Parameter for the first moment estimate. Defaults to 0.9");
+      85           6 :   keys.add("optional","BETA_2","Parameter for the second moment estimate. Defaults to 0.999");
+      86           6 :   keys.add("optional","EPSILON","Small parameter to avoid division by zero. Defaults to 1e-8");
+      87           9 :   keys.add("optional","ADAMW_WEIGHT_DECAY","Weight decay parameter for the AdamW variant. Defaults to 0");
+      88           6 :   keys.addFlag("AMSGRAD", false, "Use the AMSGrad variant");
+      89           3 : }
+      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.15
+
+ + + 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 0000000000..5408e8ff23 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:606395.2 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_BachAveragedSGDC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe1996createERKNS_13ActionOptionsE75
_ZN4PLMD3ves19Opt_BachAveragedSGDC1ERKNS_13ActionOptionsE75
_ZN4PLMD3ves19Opt_BachAveragedSGD16registerKeywordsERNS_8KeywordsE76
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe199C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe199D2Ev3473
_ZN4PLMD3ves19Opt_BachAveragedSGD12coeffsUpdateEj22675
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.func.html b/coverage/ves/Opt_BachAveragedSGD.cpp.func.html new file mode 100644 index 0000000000..62946f1afa --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:606395.2 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe1996createERKNS_13ActionOptionsE75
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe199C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe199D2Ev3473
_ZN4PLMD3ves19Opt_BachAveragedSGD12coeffsUpdateEj22675
_ZN4PLMD3ves19Opt_BachAveragedSGD16registerKeywordsERNS_8KeywordsE76
_ZN4PLMD3ves19Opt_BachAveragedSGDC1ERKNS_13ActionOptionsE75
_ZN4PLMD3ves19Opt_BachAveragedSGDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html b/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html new file mode 100644 index 0000000000..ad1aac9f68 --- /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:606395.2 %
Date:2024-06-10 08:19:14Functions: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 "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       10569 : PLUMED_REGISTER_ACTION(Opt_BachAveragedSGD,"OPT_AVERAGED_SGD")
+     200             : 
+     201             : 
+     202          76 : void Opt_BachAveragedSGD::registerKeywords(Keywords& keys) {
+     203          76 :   Optimizer::registerKeywords(keys);
+     204          76 :   Optimizer::useFixedStepSizeKeywords(keys);
+     205          76 :   Optimizer::useMultipleWalkersKeywords(keys);
+     206          76 :   Optimizer::useHessianKeywords(keys);
+     207          76 :   Optimizer::useMaskKeywords(keys);
+     208          76 :   Optimizer::useRestartKeywords(keys);
+     209          76 :   Optimizer::useMonitorAverageGradientKeywords(keys);
+     210          76 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+     211         228 :   keys.add("hidden","COMBINED_GRADIENT_FILE","the name of output file for the combined gradient (gradient + Hessian term)");
+     212         228 :   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         228 :   keys.add("hidden","COMBINED_GRADIENT_FMT","specify format for combined gradient file(s) (useful for decrease the number of digits in regtests)");
+     214         228 :   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          76 : }
+     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.15
+
+ + + 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 0000000000..3d3763b175 --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:212295.5 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Opt_DummyC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe856createERKNS_13ActionOptionsE1
_ZN4PLMD3ves9Opt_DummyC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves9Opt_Dummy16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD3ves9Opt_Dummy12coeffsUpdateEj10
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe85C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe85D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.func.html b/coverage/ves/Opt_Dummy.cpp.func.html new file mode 100644 index 0000000000..90454f25ab --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:212295.5 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe856createERKNS_13ActionOptionsE1
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe85C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe85D2Ev3473
_ZN4PLMD3ves9Opt_Dummy12coeffsUpdateEj10
_ZN4PLMD3ves9Opt_Dummy16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD3ves9Opt_DummyC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves9Opt_DummyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.gcov.html b/coverage/ves/Opt_Dummy.cpp.gcov.html new file mode 100644 index 0000000000..e54812cb11 --- /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:212295.5 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(Opt_Dummy,"OPT_DUMMY")
+      86             : 
+      87             : 
+      88           2 : void Opt_Dummy::registerKeywords(Keywords& keys) {
+      89           2 :   Optimizer::registerKeywords(keys);
+      90             :   //
+      91           2 :   Optimizer::useMultipleWalkersKeywords(keys);
+      92           2 :   Optimizer::useHessianKeywords(keys);
+      93           2 :   Optimizer::useMonitorAverageGradientKeywords(keys);
+      94           4 :   keys.addFlag("MONITOR_HESSIAN",false,"also monitor the Hessian");
+      95           2 : }
+      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.15
+
+ + + 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 0000000000..fafeb376e7 --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:242596.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe546createERKNS_13ActionOptionsE1
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves19Opt_RobbinsMonroSGD16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD3ves19Opt_RobbinsMonroSGD12coeffsUpdateEj10
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe54C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe54D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html new file mode 100644 index 0000000000..2375171e3f --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:242596.0 %
Date:2024-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe546createERKNS_13ActionOptionsE1
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe54C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe54D2Ev3473
_ZN4PLMD3ves19Opt_RobbinsMonroSGD12coeffsUpdateEj10
_ZN4PLMD3ves19Opt_RobbinsMonroSGD16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html new file mode 100644 index 0000000000..5d1d6e5c6c --- /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:242596.0 %
Date:2024-06-10 08:19:14Functions: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 "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       10421 : PLUMED_REGISTER_ACTION(Opt_RobbinsMonroSGD,"OPT_ROBBINS_MONRO_SGD")
+      55             : 
+      56             : 
+      57           2 : void Opt_RobbinsMonroSGD::registerKeywords(Keywords& keys) {
+      58           2 :   Optimizer::registerKeywords(keys);
+      59           2 :   Optimizer::useDynamicStepSizeKeywords(keys);
+      60           2 :   Optimizer::useMultipleWalkersKeywords(keys);
+      61           2 :   Optimizer::useMaskKeywords(keys);
+      62           2 :   Optimizer::useRestartKeywords(keys);
+      63             :   // Optimizer::useMonitorAveragesKeywords(keys);
+      64           2 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+      65           4 :   keys.add("optional","DECAY_CONSTANT","the decay constant used for the step size.");
+      66           2 : }
+      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.15
+
+ + + 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 0000000000..9e04b3c3d0 --- /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:68276389.4 %
Date:2024-06-10 08:19:14Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer14turnOffHessianEv0
_ZN4PLMD3ves9Optimizer25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9OptimizerD0Ev0
_ZN4PLMD3ves9OptimizerD1Ev0
_ZN4PLMD3ves9Optimizer24turnOffCoeffsOutputFilesEv1
_ZN4PLMD3ves9Optimizer26useDynamicStepSizeKeywordsERNS_8KeywordsE2
_ZNK4PLMD3ves9Optimizer30writeTargetDistProjOutputFilesEv4
_ZN4PLMD3ves9Optimizer19readCoeffsFromFilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEb14
_ZNK4PLMD3ves9Optimizer23writeFesProjOutputFilesEv17
_ZNK4PLMD3ves9Optimizer26writeTargetDistOutputFilesEv38
_ZNK4PLMD3ves9Optimizer19writeFesOutputFilesEv75
_ZNK4PLMD3ves9Optimizer20writeBiasOutputFilesEv75
_ZN4PLMD3ves9Optimizer13turnOnHessianEv76
_ZN4PLMD3ves9Optimizer18useHessianKeywordsERNS_8KeywordsE78
_ZN4PLMD3ves9Optimizer18useRestartKeywordsERNS_8KeywordsE78
_ZN4PLMD3ves9Optimizer33useMonitorAverageGradientKeywordsERNS_8KeywordsE78
_ZN4PLMD3ves9Optimizer24useFixedStepSizeKeywordsERNS_8KeywordsE79
_ZN4PLMD3ves9OptimizerC2ERKNS_13ActionOptionsE79
_ZN4PLMD3ves9OptimizerD2Ev79
_ZN4PLMD3ves9Optimizer15useMaskKeywordsERNS_8KeywordsE81
_ZN4PLMD3ves9Optimizer36useDynamicTargetDistributionKeywordsERNS_8KeywordsE81
_ZN4PLMD3ves9Optimizer13enableHessianEPNS0_7VesBiasEb82
_ZN4PLMD3ves9Optimizer16registerKeywordsERNS_8KeywordsE83
_ZN4PLMD3ves9Optimizer26useMultipleWalkersKeywordsERNS_8KeywordsE83
_ZN4PLMD3ves9Optimizer26addCoeffsSetIDsToFilenamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS8_85
_ZN4PLMD3ves9Optimizer32setAllCoeffsSetIterationCountersEv93
_ZNK4PLMD3ves9Optimizer22getIterationCounterStrB5cxx11Ei95
_ZN4PLMD3ves9Optimizer11setupOFilesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS2_ISt10unique_ptrINS_5OFileESt14default_deleteISD_EESaISG_EEb388
_ZN4PLMD3ves9Optimizer22updateOutputComponentsEv22750
_ZN4PLMD3ves9Optimizer16writeOutputFilesEj22810
_ZN4PLMD3ves9Optimizer6updateEv22879
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.func.html b/coverage/ves/Optimizer.cpp.func.html new file mode 100644 index 0000000000..ac9e5c902f --- /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:68276389.4 %
Date:2024-06-10 08:19:14Functions: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_8KeywordsE81
_ZN4PLMD3ves9Optimizer16registerKeywordsERNS_8KeywordsE83
_ZN4PLMD3ves9Optimizer16writeOutputFilesEj22810
_ZN4PLMD3ves9Optimizer18useHessianKeywordsERNS_8KeywordsE78
_ZN4PLMD3ves9Optimizer18useRestartKeywordsERNS_8KeywordsE78
_ZN4PLMD3ves9Optimizer19readCoeffsFromFilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEb14
_ZN4PLMD3ves9Optimizer22updateOutputComponentsEv22750
_ZN4PLMD3ves9Optimizer24turnOffCoeffsOutputFilesEv1
_ZN4PLMD3ves9Optimizer24useFixedStepSizeKeywordsERNS_8KeywordsE79
_ZN4PLMD3ves9Optimizer25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves9Optimizer26addCoeffsSetIDsToFilenamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS8_85
_ZN4PLMD3ves9Optimizer26useDynamicStepSizeKeywordsERNS_8KeywordsE2
_ZN4PLMD3ves9Optimizer26useMultipleWalkersKeywordsERNS_8KeywordsE83
_ZN4PLMD3ves9Optimizer32setAllCoeffsSetIterationCountersEv93
_ZN4PLMD3ves9Optimizer33useMonitorAverageGradientKeywordsERNS_8KeywordsE78
_ZN4PLMD3ves9Optimizer36useDynamicTargetDistributionKeywordsERNS_8KeywordsE81
_ZN4PLMD3ves9Optimizer6updateEv22879
_ZN4PLMD3ves9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9OptimizerC2ERKNS_13ActionOptionsE79
_ZN4PLMD3ves9OptimizerD0Ev0
_ZN4PLMD3ves9OptimizerD1Ev0
_ZN4PLMD3ves9OptimizerD2Ev79
_ZNK4PLMD3ves9Optimizer19writeFesOutputFilesEv75
_ZNK4PLMD3ves9Optimizer20writeBiasOutputFilesEv75
_ZNK4PLMD3ves9Optimizer22getIterationCounterStrB5cxx11Ei95
_ZNK4PLMD3ves9Optimizer23writeFesProjOutputFilesEv17
_ZNK4PLMD3ves9Optimizer26writeTargetDistOutputFilesEv38
_ZNK4PLMD3ves9Optimizer30writeTargetDistProjOutputFilesEv4
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.gcov.html b/coverage/ves/Optimizer.cpp.gcov.html new file mode 100644 index 0000000000..991af1a73f --- /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:68276389.4 %
Date:2024-06-10 08:19:14Functions: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           0 :       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         632 : }
+     791             : 
+     792             : 
+     793          83 : void Optimizer::registerKeywords( Keywords& keys ) {
+     794          83 :   Action::registerKeywords(keys);
+     795          83 :   ActionPilot::registerKeywords(keys);
+     796          83 :   ActionWithValue::registerKeywords(keys);
+     797             :   //
+     798          83 :   keys.remove("NUMERICAL_DERIVATIVES");
+     799             :   // Default always active keywords
+     800         166 :   keys.add("compulsory","BIAS","the label of the VES bias to be optimized");
+     801         166 :   keys.add("compulsory","STRIDE","the frequency of updating the coefficients given in the number of MD steps.");
+     802         166 :   keys.add("compulsory","COEFFS_FILE","coeffs.data","the name of output file for the coefficients");
+     803         166 :   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         166 :   keys.add("optional","COEFFS_FMT","specify format for coefficient file(s) (useful for decrease the number of digits in regtests)");
+     805         249 :   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         166 :   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         166 :   keys.add("hidden","GRADIENT_FILE","the name of output file for the gradient");
+     810         166 :   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         166 :   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         166 :   keys.reserve("compulsory","STEPSIZE","the step size used for the optimization");
+     814         249 :   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         166 :   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         166 :   keys.reserve("hidden","HESSIAN_FILE","the name of output file for the Hessian");
+     818         166 :   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         166 :   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         166 :   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         166 :   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         249 :   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         166 :   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         166 :   keys.addFlag("MONITOR_INSTANTANEOUS_GRADIENT",false,"if quantities related to the instantaneous gradient should be outputted.");
+     829             :   //
+     830         166 :   keys.reserveFlag("MONITOR_AVERAGE_GRADIENT",false,"if the averaged gradient should be monitored and quantities related to it should be outputted.");
+     831         249 :   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         249 :   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         249 :   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         249 :   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         249 :   keys.add("optional","TARGETDIST_AVERAGES_FILE","the name of output file for the target distribution averages. By default it is targetdist-averages.data.");
+     838         249 :   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         249 :   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         166 :   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         166 :   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         166 :   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         249 :   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          83 :   keys.use("RESTART");
+     848             :   //
+     849          83 :   keys.use("UPDATE_FROM");
+     850          83 :   keys.use("UPDATE_UNTIL");
+     851             :   // Components that are always active
+     852         249 :   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         249 :   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          83 : }
+     857             : 
+     858             : 
+     859          78 : void Optimizer::useHessianKeywords(Keywords& keys) {
+     860             :   // keys.use("FULL_HESSIAN");
+     861          78 :   keys.use("HESSIAN_FILE");
+     862          78 :   keys.use("HESSIAN_OUTPUT");
+     863          78 :   keys.use("HESSIAN_FMT");
+     864          78 : }
+     865             : 
+     866             : 
+     867          83 : void Optimizer::useMultipleWalkersKeywords(Keywords& keys) {
+     868          83 :   keys.use("MULTIPLE_WALKERS");
+     869          83 : }
+     870             : 
+     871             : 
+     872          79 : void Optimizer::useFixedStepSizeKeywords(Keywords& keys) {
+     873          79 :   keys.use("STEPSIZE");
+     874          79 : }
+     875             : 
+     876             : 
+     877           2 : void Optimizer::useDynamicStepSizeKeywords(Keywords& keys) {
+     878           2 :   keys.use("INITIAL_STEPSIZE");
+     879           4 :   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           2 : }
+     881             : 
+     882             : 
+     883          81 : void Optimizer::useMaskKeywords(Keywords& keys) {
+     884          81 :   keys.use("MASK_FILE");
+     885          81 :   keys.use("OUTPUT_MASK_FILE");
+     886          81 : }
+     887             : 
+     888             : 
+     889          78 : void Optimizer::useRestartKeywords(Keywords& keys) {
+     890          78 :   keys.use("START_OPTIMIZATION_AFRESH");
+     891          78 : }
+     892             : 
+     893             : 
+     894          78 : void Optimizer::useMonitorAverageGradientKeywords(Keywords& keys) {
+     895          78 :   keys.use("MONITOR_AVERAGE_GRADIENT");
+     896          78 :   keys.use("MONITOR_AVERAGES_GRADIENT_EXP_DECAY");
+     897         234 :   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         234 :   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          78 : }
+     900             : 
+     901             : 
+     902          81 : void Optimizer::useDynamicTargetDistributionKeywords(Keywords& keys) {
+     903          81 :   keys.use("TARGETDIST_STRIDE");
+     904          81 :   keys.use("TARGETDIST_OUTPUT");
+     905          81 :   keys.use("TARGETDIST_PROJ_OUTPUT");
+     906          81 : }
+     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         628 :     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.15
+
+ + + 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 0000000000..03ce0b42d9 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/Optimizer.h.func.html b/coverage/ves/Optimizer.h.func.html new file mode 100644 index 0000000000..1aef4af2cc --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/Optimizer.h.gcov.html b/coverage/ves/Optimizer.h.gcov.html new file mode 100644 index 0000000000..d1d97a711b --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..b7b0be87d7 --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:10911198.2 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20OutputBasisFunctions5applyEv0
_ZN4PLMD3ves20OutputBasisFunctions9calculateEv0
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe966createERKNS_13ActionOptionsE71
_ZN4PLMD3ves20OutputBasisFunctionsC2ERKNS_13ActionOptionsE71
_ZN4PLMD3ves20OutputBasisFunctions16registerKeywordsERNS_8KeywordsE72
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe96C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe96D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.func.html b/coverage/ves/OutputBasisFunctions.cpp.func.html new file mode 100644 index 0000000000..aadb9a4c1c --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:10911198.2 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe966createERKNS_13ActionOptionsE71
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe96C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe96D2Ev3473
_ZN4PLMD3ves20OutputBasisFunctions16registerKeywordsERNS_8KeywordsE72
_ZN4PLMD3ves20OutputBasisFunctions5applyEv0
_ZN4PLMD3ves20OutputBasisFunctions9calculateEv0
_ZN4PLMD3ves20OutputBasisFunctionsC2ERKNS_13ActionOptionsE71
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.gcov.html b/coverage/ves/OutputBasisFunctions.cpp.gcov.html new file mode 100644 index 0000000000..44f18924d6 --- /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:10911198.2 %
Date:2024-06-10 08:19:14Functions:5771.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 "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       10490 : PLUMED_REGISTER_ACTION(OutputBasisFunctions,"VES_OUTPUT_BASISFUNCTIONS")
+      97             : 
+      98          72 : void OutputBasisFunctions::registerKeywords(Keywords& keys) {
+      99          72 :   Action::registerKeywords(keys);
+     100         144 :   keys.add("compulsory","BASIS_FUNCTIONS","the label of the basis functions that you want to use");
+     101         144 :   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         144 :   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         144 :   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         144 :   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         144 :   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         216 :   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         144 :   keys.add("optional","FORMAT_VALUES","the numerical format of the basis function derivatives written to file. By default it is %15.8f.\n");
+     108         144 :   keys.add("optional","FORMAT_DERIVS","the numerical format of the basis function values written to file. By default it is %15.8f.\n");
+     109         216 :   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         216 :   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         144 :   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         216 :   keys.add("numbered","TARGET_DISTRIBUTION","the target distribution to be used.");
+     113         144 :   keys.addFlag("IGNORE_PERIODICITY",false,"if the periodicity of the basis functions should be ignored.");
+     114         144 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"if the derivatives of the basis functions should be calculated numerically.");
+     115          72 : }
+     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.15
+
+ + + 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 0000000000..9757d5c567 --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:616988.4 %
Date:2024-06-10 08:19:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves13OutputFesBias5applyEv0
_ZN4PLMD3ves13OutputFesBias6updateEv0
_ZN4PLMD3ves13OutputFesBias9calculateEv0
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe1106createERKNS_13ActionOptionsE3
_ZN4PLMD3ves13OutputFesBiasC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves13OutputFesBias16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe110C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe110D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.func.html b/coverage/ves/OutputFesBias.cpp.func.html new file mode 100644 index 0000000000..c453a2041e --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:616988.4 %
Date:2024-06-10 08:19:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe1106createERKNS_13ActionOptionsE3
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe110C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe110D2Ev3473
_ZN4PLMD3ves13OutputFesBias16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves13OutputFesBias5applyEv0
_ZN4PLMD3ves13OutputFesBias6updateEv0
_ZN4PLMD3ves13OutputFesBias9calculateEv0
_ZN4PLMD3ves13OutputFesBiasC2ERKNS_13ActionOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.gcov.html b/coverage/ves/OutputFesBias.cpp.gcov.html new file mode 100644 index 0000000000..09ec482dab --- /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:616988.4 %
Date:2024-06-10 08:19:14Functions:5862.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 "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       10422 : PLUMED_REGISTER_ACTION(OutputFesBias,"VES_OUTPUT_FES")
+     111             : 
+     112             : 
+     113           4 : void OutputFesBias::registerKeywords(Keywords& keys) {
+     114           8 :   keys.add("compulsory","BIAS","the label of the VES bias for to output the free energy surfaces and the bias files");
+     115           8 :   keys.add("compulsory","COEFFS_INPUT","the name of input coefficient file");
+     116           8 :   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           8 :   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           8 :   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           4 : }
+     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.15
+
+ + + 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 0000000000..da88dfb844 --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:849093.3 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves24OutputTargetDistribution5applyEv0
_ZN4PLMD3ves24OutputTargetDistribution9calculateEv0
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe926createERKNS_13ActionOptionsE120
_ZN4PLMD3ves24OutputTargetDistributionC2ERKNS_13ActionOptionsE120
_ZN4PLMD3ves24OutputTargetDistribution16registerKeywordsERNS_8KeywordsE121
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe92C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe92D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.func.html b/coverage/ves/OutputTargetDistribution.cpp.func.html new file mode 100644 index 0000000000..7403a5061e --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:849093.3 %
Date:2024-06-10 08:19:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe926createERKNS_13ActionOptionsE120
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe92C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe92D2Ev3473
_ZN4PLMD3ves24OutputTargetDistribution16registerKeywordsERNS_8KeywordsE121
_ZN4PLMD3ves24OutputTargetDistribution5applyEv0
_ZN4PLMD3ves24OutputTargetDistribution9calculateEv0
_ZN4PLMD3ves24OutputTargetDistributionC2ERKNS_13ActionOptionsE120
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.gcov.html b/coverage/ves/OutputTargetDistribution.cpp.gcov.html new file mode 100644 index 0000000000..a577486af3 --- /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:849093.3 %
Date:2024-06-10 08:19:14Functions:5771.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 "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       10539 : PLUMED_REGISTER_ACTION(OutputTargetDistribution,"VES_OUTPUT_TARGET_DISTRIBUTION")
+      93             : 
+      94         121 : void OutputTargetDistribution::registerKeywords(Keywords& keys) {
+      95         121 :   Action::registerKeywords(keys);
+      96         242 :   keys.add("compulsory","GRID_MIN","the lower bounds for the grid");
+      97         242 :   keys.add("compulsory","GRID_MAX","the upper bounds for the grid");
+      98         242 :   keys.add("compulsory","GRID_BINS","the number of bins used for the grid.");
+      99         363 :   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         242 :   keys.add("compulsory","TARGETDIST_FILE","filename of the file for writing the target distribution");
+     101         363 :   keys.add("optional","LOG_TARGETDIST_FILE","filename of the file for writing the log of the target distribution");
+     102         363 :   keys.add("compulsory","TARGET_DISTRIBUTION","the target distribution to be used.");
+     103         242 :   keys.add("optional","FMT_GRIDS","the numerical format of the target distribution grids written to file. By default it is %14.9f");
+     104         242 :   keys.addFlag("DO_1D_PROJECTIONS",false,"Also output the one-dimensional marginal distributions for multi-dimensional target distribution.");
+     105         121 : }
+     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.15
+
+ + + 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 0000000000..93024c1b90 --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:4141100.0 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe916createERKNS_13ActionOptionsE9
_ZN4PLMD3ves6TD_ChiC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves6TD_Chi16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD3ves6TD_Chi8getValueERKSt6vectorIdSaIdEE1509
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe91C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe91D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.func.html b/coverage/ves/TD_Chi.cpp.func.html new file mode 100644 index 0000000000..151dc1e8bd --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:4141100.0 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe916createERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe91C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe91D2Ev3473
_ZN4PLMD3ves6TD_Chi16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves6TD_ChiC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves6TD_Chi8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.gcov.html b/coverage/ves/TD_Chi.cpp.gcov.html new file mode 100644 index 0000000000..6d8347cef8 --- /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:4141100.0 %
Date:2024-06-10 08:19:14Functions:66100.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       10428 : PLUMED_REGISTER_ACTION(TD_Chi,"TD_CHI")
+      92             : 
+      93             : 
+      94          10 : void TD_Chi::registerKeywords(Keywords& keys) {
+      95          10 :   TargetDistribution::registerKeywords(keys);
+      96          20 :   keys.add("compulsory","MINIMUM","The minimum of the chi distribution.");
+      97          20 :   keys.add("compulsory","SIGMA","The \\f$\\sigma\\f$ parameter of the chi distribution given as a positive number.");
+      98          20 :   keys.add("compulsory","KAPPA","The \\f$k\\f$ parameter of the chi distribution given as positive integer larger than 1.");
+      99          10 :   keys.use("WELLTEMPERED_FACTOR");
+     100          10 :   keys.use("SHIFT_TO_ZERO");
+     101          10 :   keys.use("NORMALIZE");
+     102          10 : }
+     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.15
+
+ + + 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 0000000000..04dd7d790b --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:4141100.0 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe916createERKNS_13ActionOptionsE9
_ZN4PLMD3ves13TD_ChiSquaredC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves13TD_ChiSquared16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD3ves13TD_ChiSquared8getValueERKSt6vectorIdSaIdEE1509
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe91C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe91D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.func.html b/coverage/ves/TD_ChiSquared.cpp.func.html new file mode 100644 index 0000000000..52881f1e64 --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:4141100.0 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe916createERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe91C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe91D2Ev3473
_ZN4PLMD3ves13TD_ChiSquared16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves13TD_ChiSquaredC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves13TD_ChiSquared8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.gcov.html b/coverage/ves/TD_ChiSquared.cpp.gcov.html new file mode 100644 index 0000000000..f0f4680125 --- /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:4141100.0 %
Date:2024-06-10 08:19:14Functions:66100.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       10428 : PLUMED_REGISTER_ACTION(TD_ChiSquared,"TD_CHISQUARED")
+      92             : 
+      93             : 
+      94          10 : void TD_ChiSquared::registerKeywords(Keywords& keys) {
+      95          10 :   TargetDistribution::registerKeywords(keys);
+      96          20 :   keys.add("compulsory","MINIMUM","The minimum of the chi-squared distribution.");
+      97          20 :   keys.add("compulsory","SIGMA","The \\f$\\sigma\\f$ parameter of the chi-squared distribution given as a positive number.");
+      98          20 :   keys.add("compulsory","KAPPA","The \\f$k\\f$ parameter of the chi-squared distribution given as positive integer larger than 2.");
+      99          10 :   keys.use("WELLTEMPERED_FACTOR");
+     100          10 :   keys.use("SHIFT_TO_ZERO");
+     101          10 :   keys.use("NORMALIZE");
+     102          10 : }
+     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.15
+
+ + + 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 0000000000..b5a8a1c7f2 --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + 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:789086.7 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves9TD_Custom8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe1466createERKNS_13ActionOptionsE16
_ZN4PLMD3ves9TD_Custom20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE16
_ZN4PLMD3ves9TD_CustomC2ERKNS_13ActionOptionsE16
_ZN4PLMD3ves9TD_CustomD0Ev16
_ZN4PLMD3ves9TD_CustomD2Ev16
_ZN4PLMD3ves9TD_Custom16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD3ves9TD_Custom10updateGridEv46
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe146C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe146D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.func.html b/coverage/ves/TD_Custom.cpp.func.html new file mode 100644 index 0000000000..a93eccade5 --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + 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:789086.7 %
Date:2024-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe1466createERKNS_13ActionOptionsE16
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe146C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe146D2Ev3473
_ZN4PLMD3ves9TD_Custom10updateGridEv46
_ZN4PLMD3ves9TD_Custom16registerKeywordsERNS_8KeywordsE17
_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.15
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.gcov.html b/coverage/ves/TD_Custom.cpp.gcov.html new file mode 100644 index 0000000000..0d379bbef8 --- /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:789086.7 %
Date:2024-06-10 08:19:14Functions: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             : 
+      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          64 :   ~TD_Custom() {};
+     144             : };
+     145             : 
+     146       10435 : PLUMED_REGISTER_ACTION(TD_Custom,"TD_CUSTOM")
+     147             : 
+     148             : 
+     149          17 : void TD_Custom::registerKeywords(Keywords& keys) {
+     150          17 :   TargetDistribution::registerKeywords(keys);
+     151          34 :   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          17 :   keys.use("WELLTEMPERED_FACTOR");
+     153          17 :   keys.use("SHIFT_TO_ZERO");
+     154          17 : }
+     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.15
+
+ + + 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 0000000000..ba2119d6d8 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:2727100.0 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe846createERKNS_13ActionOptionsE8
_ZN4PLMD3ves14TD_ExponentialC2ERKNS_13ActionOptionsE8
_ZN4PLMD3ves14TD_Exponential16registerKeywordsERNS_8KeywordsE9
_ZNK4PLMD3ves14TD_Exponential8getValueERKSt6vectorIdSaIdEE1308
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe84C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe84D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.func.html b/coverage/ves/TD_Exponential.cpp.func.html new file mode 100644 index 0000000000..f6a92a51ee --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:2727100.0 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe846createERKNS_13ActionOptionsE8
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe84C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe84D2Ev3473
_ZN4PLMD3ves14TD_Exponential16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD3ves14TD_ExponentialC2ERKNS_13ActionOptionsE8
_ZNK4PLMD3ves14TD_Exponential8getValueERKSt6vectorIdSaIdEE1308
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.gcov.html b/coverage/ves/TD_Exponential.cpp.gcov.html new file mode 100644 index 0000000000..e557445b8f --- /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:2727100.0 %
Date:2024-06-10 08:19:14Functions:66100.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       10427 : PLUMED_REGISTER_ACTION(TD_Exponential,"TD_EXPONENTIAL")
+      85             : 
+      86             : 
+      87           9 : void TD_Exponential::registerKeywords(Keywords& keys) {
+      88           9 :   TargetDistribution::registerKeywords(keys);
+      89          18 :   keys.add("compulsory","MINIMUM","The minimum of the exponential distribution.");
+      90          18 :   keys.add("compulsory","LAMBDA","The \\f$\\lambda\\f$ parameter of the exponential distribution given as positive number.");
+      91           9 :   keys.use("WELLTEMPERED_FACTOR");
+      92           9 :   keys.use("SHIFT_TO_ZERO");
+      93           9 :   keys.use("NORMALIZE");
+      94           9 : }
+      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.15
+
+ + + 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 0000000000..87be9c35cd --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:586490.6 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe1196createERKNS_13ActionOptionsE6
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussianC2ERKNS_13ActionOptionsE6
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussian16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe119C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe119D2Ev3473
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian8getValueERKSt6vectorIdSaIdEE11206
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian37ExponentiallyModifiedGaussianDiagonalERKSt6vectorIdSaIdEES6_S6_S6_21809
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html new file mode 100644 index 0000000000..796ec38295 --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:586490.6 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe1196createERKNS_13ActionOptionsE6
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe119C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe119D2Ev3473
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussian16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussianC2ERKNS_13ActionOptionsE6
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian37ExponentiallyModifiedGaussianDiagonalERKSt6vectorIdSaIdEES6_S6_S6_21809
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian8getValueERKSt6vectorIdSaIdEE11206
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html new file mode 100644 index 0000000000..306232f40d --- /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:586490.6 %
Date:2024-06-10 08:19:14Functions:77100.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       10425 : PLUMED_REGISTER_ACTION(TD_ExponentiallyModifiedGaussian,"TD_EXPONENTIALLY_MODIFIED_GAUSSIAN")
+     120             : 
+     121             : 
+     122           7 : void TD_ExponentiallyModifiedGaussian::registerKeywords(Keywords& keys) {
+     123           7 :   TargetDistribution::registerKeywords(keys);
+     124          14 :   keys.add("numbered","CENTER","The center of each exponentially modified Gaussian distributions.");
+     125          14 :   keys.add("numbered","SIGMA","The sigma parameters for each exponentially modified Gaussian distributions.");
+     126          14 :   keys.add("numbered","LAMBDA","The lambda parameters for each exponentially modified Gaussian distributions");
+     127          14 :   keys.add("optional","WEIGHTS","The weights of the distributions. By default all are weighted equally.");
+     128           7 :   keys.use("WELLTEMPERED_FACTOR");
+     129           7 :   keys.use("SHIFT_TO_ZERO");
+     130           7 :   keys.use("NORMALIZE");
+     131           7 : }
+     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.15
+
+ + + 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 0000000000..f1b17bf742 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:778590.6 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_GaussianC2ERKNS_13ActionOptionsE191
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe1766createERKNS_13ActionOptionsE191
_ZN4PLMD3ves11TD_Gaussian16registerKeywordsERNS_8KeywordsE192
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe176C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe176D2Ev3473
_ZNK4PLMD3ves11TD_Gaussian10Gaussian2DERKSt6vectorIdSaIdEES6_S6_S6_b40804
_ZNK4PLMD3ves11TD_Gaussian8getValueERKSt6vectorIdSaIdEE229739
_ZNK4PLMD3ves11TD_Gaussian16GaussianDiagonalERKSt6vectorIdSaIdEES6_S6_b292252
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.func.html b/coverage/ves/TD_Gaussian.cpp.func.html new file mode 100644 index 0000000000..4105a84f2e --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:778590.6 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_Gaussian16registerKeywordsERNS_8KeywordsE192
_ZN4PLMD3ves11TD_GaussianC2ERKNS_13ActionOptionsE191
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe1766createERKNS_13ActionOptionsE191
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe176C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe176D2Ev3473
_ZNK4PLMD3ves11TD_Gaussian10Gaussian2DERKSt6vectorIdSaIdEES6_S6_S6_b40804
_ZNK4PLMD3ves11TD_Gaussian16GaussianDiagonalERKSt6vectorIdSaIdEES6_S6_b292252
_ZNK4PLMD3ves11TD_Gaussian8getValueERKSt6vectorIdSaIdEE229739
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.gcov.html b/coverage/ves/TD_Gaussian.cpp.gcov.html new file mode 100644 index 0000000000..d2f449bad1 --- /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:778590.6 %
Date:2024-06-10 08:19:14Functions: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 "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       10610 : PLUMED_REGISTER_ACTION(TD_Gaussian,"TD_GAUSSIAN")
+     177             : 
+     178             : 
+     179         192 : void TD_Gaussian::registerKeywords(Keywords& keys) {
+     180         192 :   TargetDistribution::registerKeywords(keys);
+     181         384 :   keys.add("numbered","CENTER","The centers of the Gaussian distributions.");
+     182         384 :   keys.add("numbered","SIGMA","The standard deviations of the Gaussian distributions.");
+     183         384 :   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         384 :   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         192 :   keys.use("WELLTEMPERED_FACTOR");
+     186         192 :   keys.use("SHIFT_TO_ZERO");
+     187         192 :   keys.use("NORMALIZE");
+     188         192 : }
+     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.15
+
+ + + 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 0000000000..3d97702f63 --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3939100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe1126createERKNS_13ActionOptionsE5
_ZN4PLMD3ves26TD_GeneralizedExtremeValueC2ERKNS_13ActionOptionsE5
_ZN4PLMD3ves26TD_GeneralizedExtremeValue16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue11GEVdiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_1605
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue8getValueERKSt6vectorIdSaIdEE1605
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe112C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe112D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html new file mode 100644 index 0000000000..68da8e0a91 --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:3939100.0 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe1126createERKNS_13ActionOptionsE5
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe112C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe112D2Ev3473
_ZN4PLMD3ves26TD_GeneralizedExtremeValue16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves26TD_GeneralizedExtremeValueC2ERKNS_13ActionOptionsE5
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue11GEVdiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_1605
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue8getValueERKSt6vectorIdSaIdEE1605
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html new file mode 100644 index 0000000000..74e66ea804 --- /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:3939100.0 %
Date:2024-06-10 08:19:14Functions:77100.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       10424 : PLUMED_REGISTER_ACTION(TD_GeneralizedExtremeValue,"TD_GENERALIZED_EXTREME_VALUE")
+     113             : 
+     114             : 
+     115           6 : void TD_GeneralizedExtremeValue::registerKeywords(Keywords& keys) {
+     116           6 :   TargetDistribution::registerKeywords(keys);
+     117          12 :   keys.add("compulsory","LOCATION","The \\f$\\mu\\f$ parameter of the generalized extreme value distribution.");
+     118          12 :   keys.add("compulsory","SCALE","The \\f$\\sigma\\f$ parameter for the generalized extreme value distribution given as a positive number.");
+     119          12 :   keys.add("compulsory","SHAPE","The \\f$\\xi\\f$ parameter for the generalized extreme value distribution.");
+     120           6 :   keys.use("WELLTEMPERED_FACTOR");
+     121           6 :   keys.use("SHIFT_TO_ZERO");
+     122           6 :   keys.use("NORMALIZE");
+     123           6 : }
+     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.15
+
+ + + 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 0000000000..d0d8a48da2 --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:647091.4 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe1146createERKNS_13ActionOptionsE8
_ZN4PLMD3ves20TD_GeneralizedNormalC2ERKNS_13ActionOptionsE8
_ZN4PLMD3ves20TD_GeneralizedNormal16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe114C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe114D2Ev3473
_ZNK4PLMD3ves20TD_GeneralizedNormal8getValueERKSt6vectorIdSaIdEE21608
_ZNK4PLMD3ves20TD_GeneralizedNormal24ExponentialPowerDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_53015
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.func.html b/coverage/ves/TD_GeneralizedNormal.cpp.func.html new file mode 100644 index 0000000000..d20c4de22a --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:647091.4 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe1146createERKNS_13ActionOptionsE8
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe114C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe114D2Ev3473
_ZN4PLMD3ves20TD_GeneralizedNormal16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD3ves20TD_GeneralizedNormalC2ERKNS_13ActionOptionsE8
_ZNK4PLMD3ves20TD_GeneralizedNormal24ExponentialPowerDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_53015
_ZNK4PLMD3ves20TD_GeneralizedNormal8getValueERKSt6vectorIdSaIdEE21608
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html b/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html new file mode 100644 index 0000000000..ed45a98d20 --- /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:647091.4 %
Date:2024-06-10 08:19:14Functions:77100.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       10427 : PLUMED_REGISTER_ACTION(TD_GeneralizedNormal,"TD_GENERALIZED_NORMAL")
+     115             : 
+     116             : 
+     117           9 : void TD_GeneralizedNormal::registerKeywords(Keywords& keys) {
+     118           9 :   TargetDistribution::registerKeywords(keys);
+     119          18 :   keys.add("numbered","CENTER","The center of each generalized normal distribution.");
+     120          18 :   keys.add("numbered","ALPHA","The alpha parameters for each generalized normal distribution.");
+     121          18 :   keys.add("numbered","BETA","The beta parameters for each generalized normal distribution.");
+     122          18 :   keys.add("optional","WEIGHTS","The weights of the generalized normal distribution. By default all are weighted equally.");
+     123           9 :   keys.use("WELLTEMPERED_FACTOR");
+     124           9 :   keys.use("SHIFT_TO_ZERO");
+     125           9 :   keys.use("NORMALIZE");
+     126           9 : }
+     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.15
+
+ + + 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 0000000000..689689c9e2 --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + 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:565994.9 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe1176createERKNS_13ActionOptionsE9
_ZN4PLMD3ves7TD_GridC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves7TD_Grid16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe117C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe117D2Ev3473
_ZNK4PLMD3ves7TD_Grid8getValueERKSt6vectorIdSaIdEE49369
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.func.html b/coverage/ves/TD_Grid.cpp.func.html new file mode 100644 index 0000000000..9dd3ff6337 --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + 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:565994.9 %
Date:2024-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe1176createERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe117C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe117D2Ev3473
_ZN4PLMD3ves7TD_Grid16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves7TD_GridC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves7TD_Grid8getValueERKSt6vectorIdSaIdEE49369
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.gcov.html b/coverage/ves/TD_Grid.cpp.gcov.html new file mode 100644 index 0000000000..d8ca95df7a --- /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:565994.9 %
Date:2024-06-10 08:19:14Functions:66100.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       10428 : PLUMED_REGISTER_ACTION(TD_Grid,"TD_GRID")
+     118             : 
+     119             : 
+     120          10 : void TD_Grid::registerKeywords(Keywords& keys) {
+     121          10 :   TargetDistribution::registerKeywords(keys);
+     122          20 :   keys.add("compulsory","FILE","The name of the external grid file to be used as a target distribution.");
+     123          20 :   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          20 :   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          20 :   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          10 :   keys.use("WELLTEMPERED_FACTOR");
+     127          10 :   keys.use("SHIFT_TO_ZERO");
+     128          10 : }
+     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          27 :     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.15
+
+ + + 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 0000000000..9ffc08d8ba --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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-06-10 08:19:14Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe1496createERKNS_13ActionOptionsE12
_ZN4PLMD3ves20TD_LinearCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE12
_ZN4PLMD3ves20TD_LinearCombinationC2ERKNS_13ActionOptionsE12
_ZN4PLMD3ves20TD_LinearCombination16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD3ves20TD_LinearCombination10updateGridEv22
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe149C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe149D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.func.html b/coverage/ves/TD_LinearCombination.cpp.func.html new file mode 100644 index 0000000000..33e1033d24 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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-06-10 08:19:14Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe1496createERKNS_13ActionOptionsE12
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe149C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe149D2Ev3473
_ZN4PLMD3ves20TD_LinearCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves20TD_LinearCombination10updateGridEv22
_ZN4PLMD3ves20TD_LinearCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves20TD_LinearCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves20TD_LinearCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombination16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD3ves20TD_LinearCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE12
_ZN4PLMD3ves20TD_LinearCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombinationC2ERKNS_13ActionOptionsE12
_ZNK4PLMD3ves20TD_LinearCombination8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.gcov.html b/coverage/ves/TD_LinearCombination.cpp.gcov.html new file mode 100644 index 0000000000..156f0cacc2 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.gcov.html @@ -0,0 +1,351 @@ + + + + + + + + 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-06-10 08:19:14Functions:91369.2 %
+
+ + + + + + + + +

+
          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             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : // class Grid;
+      35             : class Action;
+      36             : 
+      37             : namespace ves {
+      38             : 
+      39             : //+PLUMEDOC VES_TARGETDIST TD_LINEAR_COMBINATION
+      40             : /*
+      41             : Target distribution given by linear combination of distributions (static or dynamic).
+      42             : 
+      43             : Employ a target distribution that is a linear combination of the other
+      44             : distributions, defined as
+      45             : \f[
+      46             : p(\mathbf{s}) = \sum_{i} w_{i} \, p_{i}(\mathbf{s})
+      47             : \f]
+      48             : where the weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      49             : 
+      50             : The labels of the distributions \f$p_{i}(\mathbf{s})\f$ to be used in the
+      51             : linear combination are given in the DISTRIBUTIONS keyword.
+      52             : 
+      53             : The weights \f$w_{i}\f$ can be given using
+      54             : the WEIGHTS keyword. The distributions are weighted equally if no weights are given.
+      55             : 
+      56             : It is assumed that all the distributions \f$p_{i}(\mathbf{s})\f$ are normalized.
+      57             : If that is not the case for some reason should you
+      58             : normalize each distribution separately by using the NORMALIZE
+      59             : keyword when defining them in the input file (i.e. before the
+      60             : TD_LINEAR_COMBINATION action).
+      61             : Note that normalizing the overall
+      62             : linear combination will generally lead to different results than normalizing
+      63             : each distribution separately.
+      64             : 
+      65             : The linear combination will be a dynamic target distribution if one or more
+      66             : of the distributions used is a dynamic distribution, otherwise it will be a
+      67             : static distribution.
+      68             : 
+      69             : \par Examples
+      70             : 
+      71             : Here we employ a linear combination of a uniform and a Gaussian distribution.
+      72             : No weights are given so the two distributions will be weighted equally.
+      73             : \plumedfile
+      74             : td_uni: TD_UNIFORM
+      75             : 
+      76             : td_gauss: TD_GAUSSIAN CENTER1=-2.0 SIGMA1=0.5
+      77             : 
+      78             : td_comb: TD_LINEAR_COMBINATION DISTRIBUTIONS=td_uni,td_gauss
+      79             : \endplumedfile
+      80             : 
+      81             : Here we employ a linear combination of a uniform and two Gaussian distribution.
+      82             : The weights are automatically normalized to 1 such that giving
+      83             : WEIGHTS=1.0,1.0,2.0 as we do here is equal to giving WEIGHTS=0.25,0.25,0.50.
+      84             : \plumedfile
+      85             : td_uni: TD_UNIFORM
+      86             : 
+      87             : td_gauss1: TD_GAUSSIAN CENTER1=-2.0,-2.0 SIGMA1=0.5,0.3
+      88             : 
+      89             : td_gauss2: TD_GAUSSIAN CENTER1=+2.0,+2.0 SIGMA1=0.3,0.5
+      90             : 
+      91             : TD_LINEAR_COMBINATION ...
+      92             :  DISTRIBUTIONS=td_uni,td_gauss1,td_gauss2
+      93             :  WEIGHTS=1.0,1.0,2.0
+      94             :  LABEL=td_comb
+      95             : ... TD_LINEAR_COMBINATION
+      96             : \endplumedfile
+      97             : 
+      98             : In the above example the two Gaussian kernels are given using two separate
+      99             : DISTRIBUTION keywords. As the \ref TD_GAUSSIAN target distribution allows multiple
+     100             : centers is it also possible to use just one DISTRIBUTION keyword for the two
+     101             : Gaussian kernels. This is shown in the following example which will give the
+     102             : exact same result as the one above as the weights have been appropriately
+     103             : adjusted
+     104             : \plumedfile
+     105             : td_uni: TD_UNIFORM
+     106             : 
+     107             : TD_GAUSSIAN ...
+     108             :  CENTER1=-2.0,-2.0  SIGMA1=0.5,0.3
+     109             :  CENTER2=+2.0,+2.0  SIGMA2=0.3,0.5
+     110             :  WEIGHTS=1.0,2.0
+     111             :  LABEL=td_gauss
+     112             : ... TD_GAUSSIAN
+     113             : 
+     114             : TD_LINEAR_COMBINATION ...
+     115             :  DISTRIBUTIONS=td_uni,td_gauss
+     116             :  WEIGHTS=0.25,0.75
+     117             :  LABEL=td_comb
+     118             : ... TD_LINEAR_COMBINATION
+     119             : \endplumedfile
+     120             : 
+     121             : */
+     122             : //+ENDPLUMEDOC
+     123             : 
+     124             : class VesBias;
+     125             : 
+     126             : class TD_LinearCombination: public TargetDistribution {
+     127             : private:
+     128             :   std::vector<TargetDistribution*> distribution_pntrs_;
+     129             :   std::vector<Grid*> grid_pntrs_;
+     130             :   std::vector<double> weights_;
+     131             :   unsigned int ndist_;
+     132             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     133             : public:
+     134             :   static void registerKeywords(Keywords&);
+     135             :   explicit TD_LinearCombination(const ActionOptions& ao);
+     136             :   void updateGrid() override;
+     137             :   double getValue(const std::vector<double>&) const override;
+     138             :   //
+     139             :   void linkVesBias(VesBias*) override;
+     140             :   void linkAction(Action*) override;
+     141             :   //
+     142             :   void linkBiasGrid(Grid*) override;
+     143             :   void linkBiasWithoutCutoffGrid(Grid*) override;
+     144             :   void linkFesGrid(Grid*) override;
+     145             :   //
+     146             : };
+     147             : 
+     148             : 
+     149       10431 : PLUMED_REGISTER_ACTION(TD_LinearCombination,"TD_LINEAR_COMBINATION")
+     150             : 
+     151             : 
+     152          13 : void TD_LinearCombination::registerKeywords(Keywords& keys) {
+     153          13 :   TargetDistribution::registerKeywords(keys);
+     154          26 :   keys.add("compulsory","DISTRIBUTIONS","The labels of the target distribution actions to be used in the linear combination.");
+     155          26 :   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.");
+     156          13 :   keys.use("WELLTEMPERED_FACTOR");
+     157             :   //keys.use("SHIFT_TO_ZERO");
+     158          13 :   keys.use("NORMALIZE");
+     159          13 : }
+     160             : 
+     161             : 
+     162          12 : TD_LinearCombination::TD_LinearCombination(const ActionOptions& ao):
+     163             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     164          24 :   distribution_pntrs_(0),
+     165          12 :   grid_pntrs_(0),
+     166          12 :   weights_(0),
+     167          24 :   ndist_(0)
+     168             : {
+     169             :   std::vector<std::string> targetdist_labels;
+     170          12 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     171             : 
+     172          12 :   std::string error_msg = "";
+     173          24 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     174          12 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     175             : 
+     176          40 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     177          28 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     178          28 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     179          28 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     180             :   }
+     181             : 
+     182          12 :   ndist_ = distribution_pntrs_.size();
+     183          12 :   grid_pntrs_.assign(ndist_,NULL);
+     184          12 :   if(ndist_==0) {plumed_merror(getName()+ ": no distributions are given.");}
+     185          12 :   if(ndist_==1) {plumed_merror(getName()+ ": giving only one distribution does not make sense.");}
+     186             :   //
+     187          24 :   parseVector("WEIGHTS",weights_);
+     188          12 :   if(weights_.size()==0) {weights_.assign(distribution_pntrs_.size(),1.0);}
+     189          12 :   if(distribution_pntrs_.size()!=weights_.size()) {
+     190           0 :     plumed_merror(getName()+ ": there has to be as many weights given in WEIGHTS as the number of target distribution labels given in DISTRIBUTIONS");
+     191             :   }
+     192             :   //
+     193             :   double sum_weights=0.0;
+     194          40 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     195          40 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     196          12 :   checkRead();
+     197          12 : }
+     198             : 
+     199             : 
+     200           0 : double TD_LinearCombination::getValue(const std::vector<double>& argument) const {
+     201           0 :   plumed_merror("getValue not implemented for TD_LinearCombination");
+     202             :   return 0.0;
+     203             : }
+     204             : 
+     205             : 
+     206          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) {
+     207          40 :   for(unsigned int i=0; i<ndist_; i++) {
+     208          28 :     distribution_pntrs_[i]->setupGrids(arguments,min,max,nbins);
+     209          28 :     if(distribution_pntrs_[i]->getDimension()!=this->getDimension()) {
+     210           0 :       plumed_merror(getName() + ": all target distribution must have the same dimension");
+     211             :     }
+     212          28 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     213             :   }
+     214          12 : }
+     215             : 
+     216             : 
+     217          22 : void TD_LinearCombination::updateGrid() {
+     218          70 :   for(unsigned int i=0; i<ndist_; i++) {
+     219          48 :     distribution_pntrs_[i]->updateTargetDist();
+     220             :   }
+     221      162033 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     222             :     double value = 0.0;
+     223      506837 :     for(unsigned int i=0; i<ndist_; i++) {
+     224      344826 :       value += weights_[i]*grid_pntrs_[i]->getValue(l);
+     225             :     }
+     226      162011 :     targetDistGrid().setValue(l,value);
+     227      162011 :     logTargetDistGrid().setValue(l,-std::log(value));
+     228             :   }
+     229          22 :   logTargetDistGrid().setMinToZero();
+     230          22 : }
+     231             : 
+     232             : 
+     233           1 : void TD_LinearCombination::linkVesBias(VesBias* vesbias_pntr_in) {
+     234           1 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     235           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     236           2 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     237             :   }
+     238           1 : }
+     239             : 
+     240             : 
+     241           0 : void TD_LinearCombination::linkAction(Action* action_pntr_in) {
+     242           0 :   TargetDistribution::linkAction(action_pntr_in);
+     243           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     244           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     245             :   }
+     246           0 : }
+     247             : 
+     248             : 
+     249           0 : void TD_LinearCombination::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     250           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     251           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     252           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     253             :   }
+     254           0 : }
+     255             : 
+     256             : 
+     257           0 : void TD_LinearCombination::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     258           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     259           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     260           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     261             :   }
+     262           0 : }
+     263             : 
+     264             : 
+     265           1 : void TD_LinearCombination::linkFesGrid(Grid* fes_grid_pntr_in) {
+     266           1 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     267           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     268           2 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     269             :   }
+     270           1 : }
+     271             : 
+     272             : 
+     273             : }
+     274             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b44afeaf9d --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:19820596.6 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves17TD_Multicanonical8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe1606createERKNS_13ActionOptionsE2
_ZN4PLMD3ves17TD_MulticanonicalC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves17TD_MulticanonicalD0Ev2
_ZN4PLMD3ves17TD_MulticanonicalD2Ev2
_ZN4PLMD3ves17TD_Multicanonical16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves17TD_Multicanonical10updateGridEv14
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe160C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe160D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.func.html b/coverage/ves/TD_Multicanonical.cpp.func.html new file mode 100644 index 0000000000..5ba356abc6 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:19820596.6 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe1606createERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe160C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe160D2Ev3473
_ZN4PLMD3ves17TD_Multicanonical10updateGridEv14
_ZN4PLMD3ves17TD_Multicanonical16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves17TD_MulticanonicalC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves17TD_MulticanonicalD0Ev2
_ZN4PLMD3ves17TD_MulticanonicalD2Ev2
_ZNK4PLMD3ves17TD_Multicanonical8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.gcov.html b/coverage/ves/TD_Multicanonical.cpp.gcov.html new file mode 100644 index 0000000000..4e12b459ff --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.gcov.html @@ -0,0 +1,552 @@ + + + + + + + + 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:19820596.6 %
Date:2024-06-10 08:19:14Functions:8988.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 "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Grid.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/Atoms.h"
+      29             : #include <cfloat>
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : //+PLUMEDOC VES_TARGETDIST TD_MULTICANONICAL
+      36             : /*
+      37             : Multicanonical target distribution (dynamic).
+      38             : 
+      39             : Use the target distribution to sample the multicanonical ensemble \cite Berg-PRL-1992 \cite Piaggi-PRL-2019.
+      40             : In this way, in a single molecular dynamics simulation one can obtain information about the system in a range of temperatures.
+      41             : This range is determined through the keywords MIN_TEMP and MAX_TEMP.
+      42             : 
+      43             : The collective variables (CVs) used to construct the bias potential must be:
+      44             :  1. the energy or,
+      45             :  2. the energy and an order parameter.
+      46             : 
+      47             : Other choices of CVs or a different order of the above mentioned CVs are nonsensical.
+      48             : 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.
+      49             : 
+      50             : The algorithm will explore the free energy at each temperature up to a predefined free
+      51             :  energy threshold \f$\epsilon\f$ specified through the keyword THRESHOLD (in kT units).
+      52             : If only the energy is biased, i.e. no phase transition is considered, then THRESHOLD can be set to around 5.
+      53             : If also an order parameter is used then the THRESHOLD should be greater than the barrier for the transformation in kT.
+      54             : For small systems undergoing a freezing transition THRESHOLD is typically between 20 and 50.
+      55             : 
+      56             : When only the potential energy is used as CV the method is equivalent to the Wang-Landau algorithm \cite wanglandau.
+      57             : 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.
+      58             : 
+      59             : The algorithm works as follows.
+      60             : The target distribution for the potential energy is chosen to be:
+      61             : 
+      62             : \f[
+      63             : p(E)= \left\{\begin{array}{ll}
+      64             :          \frac{1}{E_2-E_1} & \mathrm{if} \quad E_1<E<E_2 \\
+      65             :          0 & \mathrm{otherwise}
+      66             :       \end{array}\right.
+      67             : \f]
+      68             : 
+      69             : where the energy limits \f$E_1\f$ and \f$E_2\f$ are yet to be determined.
+      70             : Clearly the interval \f$E_1–E_2\f$ chosen is related to the interval of temperatures \f$T_1-T_2\f$.
+      71             : To link these two intervals we make use of the following relation:
+      72             : \f[
+      73             : \beta' F_{\beta'}(E) = \beta F_{\beta}(E) + (\beta' - \beta) E + C,
+      74             : \f]
+      75             : 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.
+      76             : Using this relation we employ an iterative procedure to find the energy interval.
+      77             : 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:
+      78             : \f[
+      79             : p^k(E)=\frac{1}{E_2^k-E_1^k} \quad \mathrm{for} \quad E_1^k<E<E_2^k.
+      80             : \f]
+      81             : \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$.
+      82             : The procedure is repeated until convergence.
+      83             : This iterative approach is similar to that in \ref TD_WELLTEMPERED.
+      84             : 
+      85             : 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.
+      86             : 
+      87             : The output of these simulations can be reweighted in order to obtain information at all temperatures in the targeted temperature interval.
+      88             : The reweighting can be performed using the action \ref REWEIGHT_TEMP_PRESS.
+      89             : 
+      90             : \par Examples
+      91             : 
+      92             : The following input can be used to run a simulation in the multicanonical ensemble.
+      93             : The temperature interval to be explored is 400-600 K.
+      94             : The energy is used as collective variable.
+      95             : Legendre polynomials are used to construct the bias potential.
+      96             : The averaged stochastic gradient descent algorithm is chosen to optimize the VES functional.
+      97             : The target distribution is updated every 100 optimization steps (200 ps here) using the last estimation of the free energy.
+      98             : 
+      99             : \plumedfile
+     100             : # Use energy and volume as CVs
+     101             : energy: ENERGY
+     102             : 
+     103             : # Basis functions
+     104             : bf1: BF_LEGENDRE ORDER=20 MINIMUM=-25000 MAXIMUM=-23500
+     105             : 
+     106             : # Target distributions
+     107             : TD_MULTICANONICAL ...
+     108             :  LABEL=td_multi
+     109             :  MIN_TEMP=400
+     110             :  MAX_TEMP=600
+     111             : ... TD_MULTICANONICAL
+     112             : 
+     113             : # Expansion
+     114             : VES_LINEAR_EXPANSION ...
+     115             :  ARG=energy
+     116             :  BASIS_FUNCTIONS=bf1
+     117             :  TEMP=500.0
+     118             :  GRID_BINS=1000
+     119             :  TARGET_DISTRIBUTION=td_multi
+     120             :  LABEL=b1
+     121             : ... VES_LINEAR_EXPANSION
+     122             : 
+     123             : # Optimization algorithm
+     124             : OPT_AVERAGED_SGD ...
+     125             :   BIAS=b1
+     126             :   STRIDE=500
+     127             :   LABEL=o1
+     128             :   STEPSIZE=1.0
+     129             :   FES_OUTPUT=500
+     130             :   BIAS_OUTPUT=500
+     131             :   TARGETDIST_OUTPUT=500
+     132             :   COEFFS_OUTPUT=10
+     133             :   TARGETDIST_STRIDE=100
+     134             : ... OPT_AVERAGED_SGD
+     135             : 
+     136             : \endplumedfile
+     137             : 
+     138             : The multicanonical target distribution can also be used to explore a temperature interval in which a first order phase transitions is observed.
+     139             : 
+     140             : */
+     141             : //+ENDPLUMEDOC
+     142             : 
+     143             : class TD_Multicanonical: public TargetDistribution {
+     144             : private:
+     145             :   double threshold_, min_temp_, max_temp_;
+     146             :   std::vector<double> sigma_;
+     147             :   unsigned steps_temp_;
+     148             :   double epsilon_;
+     149             :   bool smoothening_;
+     150             : public:
+     151             :   static void registerKeywords(Keywords&);
+     152             :   explicit TD_Multicanonical(const ActionOptions& ao);
+     153             :   void updateGrid() override;
+     154             :   double getValue(const std::vector<double>&) const override;
+     155           6 :   ~TD_Multicanonical() {}
+     156             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     157             : };
+     158             : 
+     159             : 
+     160       10421 : PLUMED_REGISTER_ACTION(TD_Multicanonical,"TD_MULTICANONICAL")
+     161             : 
+     162             : 
+     163           3 : void TD_Multicanonical::registerKeywords(Keywords& keys) {
+     164           3 :   TargetDistribution::registerKeywords(keys);
+     165           6 :   keys.add("compulsory","THRESHOLD","5","Maximum exploration free energy in kT.");
+     166           6 :   keys.add("compulsory","EPSILON","10","The zeros of the target distribution are changed to e^-EPSILON.");
+     167           6 :   keys.add("compulsory","MIN_TEMP","Minimum temperature.");
+     168           6 :   keys.add("compulsory","MAX_TEMP","Maximum temperature.");
+     169           6 :   keys.add("optional","STEPS_TEMP","Number of temperature steps. Only for the 2D version, i.e. energy and order parameter.");
+     170           6 :   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.");
+     171           3 : }
+     172             : 
+     173             : 
+     174           2 : TD_Multicanonical::TD_Multicanonical(const ActionOptions& ao):
+     175             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     176           2 :   threshold_(5.0),
+     177           2 :   min_temp_(0.0),
+     178           2 :   max_temp_(1000.0),
+     179           4 :   sigma_(0.0),
+     180           2 :   steps_temp_(20),
+     181           2 :   epsilon_(10.0),
+     182           2 :   smoothening_(true)
+     183             : {
+     184           2 :   log.printf("  Multicanonical target distribution");
+     185           2 :   log.printf("\n");
+     186           2 :   log.printf("  Please read and cite ");
+     187           4 :   log << plumed.cite("Piaggi and Parrinello, Phys. Rev. Lett. 122 (5), 050601 (2019)");
+     188           2 :   log.printf(" and ");
+     189           4 :   log << plumed.cite("Piaggi and Parrinello, J. Chem. Phys. 150 (24), 244119 (2019)");
+     190           2 :   log.printf("\n");
+     191           2 :   parse("THRESHOLD",threshold_);
+     192           2 :   if(threshold_<=0.0) {
+     193           0 :     plumed_merror(getName()+": the value of the threshold should be positive.");
+     194             :   }
+     195           2 :   log.printf("  exploring free energy up to %f kT for each temperature \n",threshold_);
+     196             : 
+     197           2 :   parse("MIN_TEMP",min_temp_);
+     198           2 :   parse("MAX_TEMP",max_temp_);
+     199           2 :   log.printf("  temperatures between %f and %f will be explored \n",min_temp_,max_temp_);
+     200           4 :   parseVector("SIGMA",sigma_);
+     201           2 :   if(sigma_.size()==0) smoothening_=false;
+     202           2 :   if(smoothening_ && (sigma_.size()<1 || sigma_.size()>2) ) plumed_merror(getName()+": SIGMA takes 1 or 2 values as input.");
+     203           2 :   if (smoothening_) {
+     204           2 :     log.printf("  the target distribution will be smoothed using sigma values");
+     205           5 :     for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_[i]);
+     206           2 :     log.printf("\n");
+     207             :   }
+     208             : 
+     209           2 :   parse("STEPS_TEMP",steps_temp_); // Only used in the 2D version
+     210           2 :   steps_temp_ += 1;
+     211           2 :   log.printf("  %d steps in temperatures will be employed (if TD is two-dimensional) \n",steps_temp_);
+     212             : 
+     213           2 :   parse("EPSILON",epsilon_);
+     214           2 :   if(epsilon_<=1.0) {
+     215           0 :     plumed_merror(getName()+": the value of epsilon should be greater than 1.");
+     216             :   }
+     217           2 :   log.printf("  the non relevant regions of the target distribution are set to e^-%f \n",epsilon_);
+     218             : 
+     219             :   setDynamic();
+     220             :   setFesGridNeeded();
+     221           2 :   checkRead();
+     222           2 : }
+     223             : 
+     224             : 
+     225           0 : double TD_Multicanonical::getValue(const std::vector<double>& argument) const {
+     226           0 :   plumed_merror("getValue not implemented for TD_Multicanonical");
+     227             :   return 0.0;
+     228             : }
+     229             : 
+     230             : 
+     231          14 : void TD_Multicanonical::updateGrid() {
+     232          14 :   if (getStep() == 0) {
+     233           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");
+     234           2 :     if(smoothening_ && sigma_.size()!=targetDistGrid().getDimension()) plumed_merror(getName()+": mismatch between SIGMA dimension and number of arguments");
+     235             :     // Use uniform TD
+     236           4 :     std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     237             :     double norm = 0.0;
+     238        2704 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     239             :       double value = 1.0;
+     240        2702 :       norm += integration_weights[l]*value;
+     241        2702 :       targetDistGrid().setValue(l,value);
+     242             :     }
+     243           2 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     244             :   } else {
+     245             :     // Two variants: 1D and 2D
+     246          12 :     if(targetDistGrid().getDimension()==1) {
+     247             :       // 1D variant: Multicanonical without order parameter
+     248             :       // In this variant we find the minimum and maximum relevant potential energies.
+     249             :       // Using this information we construct a uniform target distribution in between these two.
+     250          10 :       double beta = getBeta();
+     251          10 :       double beta_prime_min = 1./(plumed.getAtoms().getKBoltzmann()*min_temp_);
+     252          10 :       double beta_prime_max = 1./(plumed.getAtoms().getKBoltzmann()*max_temp_);
+     253          10 :       plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_Multicanonical!");
+     254             :       // Find minimum of F(U) at temperature min
+     255             :       double minval=DBL_MAX;
+     256          10 :       Grid::index_t minindex = (targetDistGrid().getSize())/2;
+     257          10 :       double minpos = targetDistGrid().getPoint(minindex)[0];
+     258        1020 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     259        1010 :         double value = getFesGridPntr()->getValue(l);
+     260        1010 :         double argument = targetDistGrid().getPoint(l)[0];
+     261        1010 :         value = beta*value + (beta_prime_min-beta)*argument;
+     262        1010 :         if(value<minval) {
+     263             :           minval=value;
+     264             :           minpos=argument;
+     265             :           minindex=l;
+     266             :         }
+     267             :       }
+     268             :       // Find minimum energy at low temperature
+     269          10 :       double minimum_low = minpos;
+     270          11 :       for(Grid::index_t l=minindex; l>1; l-=1) {
+     271          22 :         double argument = targetDistGrid().getPoint(l)[0];
+     272          22 :         double argument_next = targetDistGrid().getPoint(l-1)[0];
+     273          11 :         double value = getFesGridPntr()->getValue(l);
+     274          11 :         double value_next = getFesGridPntr()->getValue(l-1);
+     275          11 :         value = beta*value + (beta_prime_min-beta)*argument - minval;
+     276          11 :         value_next = beta*value_next + (beta_prime_min-beta)*argument_next - minval;
+     277          11 :         if (value<threshold_ && value_next>threshold_) {
+     278          10 :           minimum_low = argument_next;
+     279          10 :           break;
+     280             :         }
+     281             :       }
+     282             :       // Find maximum energy at low temperature
+     283          10 :       double maximum_low = minpos;
+     284          12 :       for(Grid::index_t l=minindex; l<(targetDistGrid().getSize()-1); l++) {
+     285          24 :         double argument = targetDistGrid().getPoint(l)[0];
+     286          24 :         double argument_next = targetDistGrid().getPoint(l+1)[0];
+     287          12 :         double value = getFesGridPntr()->getValue(l);
+     288          12 :         double value_next = getFesGridPntr()->getValue(l+1);
+     289          12 :         value = beta*value + (beta_prime_min-beta)*argument - minval;
+     290          12 :         value_next = beta*value_next + (beta_prime_min-beta)*argument_next - minval;
+     291          12 :         if (value<threshold_ && value_next>threshold_) {
+     292          10 :           maximum_low = argument_next;
+     293          10 :           break;
+     294             :         }
+     295             :       }
+     296             :       // Find minimum of F(U) at temperature max
+     297             :       minval=DBL_MAX;
+     298        1020 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     299        1010 :         double value = getFesGridPntr()->getValue(l);
+     300        1010 :         double argument = targetDistGrid().getPoint(l)[0];
+     301        1010 :         value = beta*value + (beta_prime_max-beta)*argument;
+     302        1010 :         if(value<minval) {
+     303             :           minval=value;
+     304             :           minpos=argument;
+     305             :           minindex=l;
+     306             :         }
+     307             :       }
+     308             :       // Find minimum energy at high temperature
+     309          10 :       double minimum_high = minpos;
+     310          13 :       for(Grid::index_t l=minindex; l>1; l-=1) {
+     311          26 :         double argument = targetDistGrid().getPoint(l)[0];
+     312          26 :         double argument_next = targetDistGrid().getPoint(l-1)[0];
+     313          13 :         double value = getFesGridPntr()->getValue(l);
+     314          13 :         double value_next = getFesGridPntr()->getValue(l-1);
+     315          13 :         value = beta*value + (beta_prime_max-beta)*argument - minval;
+     316          13 :         value_next = beta*value_next + (beta_prime_max-beta)*argument_next - minval;
+     317          13 :         if (value<threshold_ && value_next>threshold_) {
+     318          10 :           minimum_high = argument_next;
+     319          10 :           break;
+     320             :         }
+     321             :       }
+     322             :       // Find maximum energy at high temperature
+     323          10 :       double maximum_high = minpos;
+     324          11 :       for(Grid::index_t l=minindex; l<(targetDistGrid().getSize()-1); l++) {
+     325          22 :         double argument = targetDistGrid().getPoint(l)[0];
+     326          22 :         double argument_next = targetDistGrid().getPoint(l+1)[0];
+     327          11 :         double value = getFesGridPntr()->getValue(l);
+     328          11 :         double value_next = getFesGridPntr()->getValue(l+1);
+     329          11 :         value = beta*value + (beta_prime_max-beta)*argument - minval;
+     330          11 :         value_next = beta*value_next + (beta_prime_max-beta)*argument_next - minval;
+     331          11 :         if (value<threshold_ && value_next>threshold_) {
+     332          10 :           maximum_high = argument_next;
+     333          10 :           break;
+     334             :         }
+     335             :       }
+     336          10 :       double minimum = std::min(minimum_low,minimum_high);
+     337          10 :       double maximum = std::max(maximum_low,maximum_high);
+     338             :       // Construct uniform TD in the interval between minimum and maximum
+     339          20 :       std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     340             :       double norm = 0.0;
+     341        1020 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     342        1010 :         double argument = targetDistGrid().getPoint(l)[0];
+     343             :         double value = 1.0;
+     344             :         double tmp;
+     345        1010 :         if(argument < minimum) {
+     346         217 :           if (smoothening_) tmp = GaussianSwitchingFunc(argument,minimum,sigma_[0]);
+     347           0 :           else tmp = exp(-1.0*epsilon_);
+     348             :         }
+     349         793 :         else if(argument > maximum) {
+     350         199 :           if (smoothening_) tmp = GaussianSwitchingFunc(argument,maximum,sigma_[0]);
+     351           0 :           else tmp = exp(-1.0*epsilon_);
+     352             :         }
+     353             :         else {
+     354             :           tmp = 1.0;
+     355             :         }
+     356             :         value *= tmp;
+     357        1010 :         norm += integration_weights[l]*value;
+     358        1010 :         targetDistGrid().setValue(l,value);
+     359             :       }
+     360          10 :       targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     361           2 :     } else if(targetDistGrid().getDimension()==2) {
+     362             :       // 2D variant: Multicanonical with order parameter
+     363             :       // In this variant we find for each temperature the relevant region of potential energy and order parameter.
+     364             :       // The target distribution will be the union of the relevant regions at all temperatures in the temperature interval.
+     365           2 :       double beta = getBeta();
+     366           2 :       double beta_prime_min = 1./(plumed.getAtoms().getKBoltzmann()*min_temp_);
+     367           2 :       double beta_prime_max = 1./(plumed.getAtoms().getKBoltzmann()*max_temp_);
+     368           2 :       plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_Multicanonical!");
+     369             :       // Set all to zero
+     370        5204 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     371        5202 :         double value = exp(-1.0*epsilon_);
+     372        5202 :         targetDistGrid().setValue(l,value);
+     373             :       }
+     374             :       // Loop over temperatures
+     375          44 :       for(unsigned i=0; i<steps_temp_; i++) {
+     376          42 :         double beta_prime=beta_prime_min + (beta_prime_max-beta_prime_min)*i/(steps_temp_-1);
+     377             :         // Find minimum for this temperature
+     378             :         double minval=DBL_MAX;
+     379      109284 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     380      218484 :           double energy = targetDistGrid().getPoint(l)[0];
+     381      109242 :           double value = getFesGridPntr()->getValue(l);
+     382      109242 :           value = beta*value + (beta_prime-beta)*energy;
+     383      109242 :           if(value<minval) {
+     384             :             minval=value;
+     385             :           }
+     386             :         }
+     387             :         // Now check which energies and volumes are below X kt
+     388      109284 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     389      218484 :           double energy = targetDistGrid().getPoint(l)[0];
+     390      109242 :           double value = getFesGridPntr()->getValue(l);
+     391      109242 :           value = beta*value + (beta_prime-beta)*energy - minval;
+     392      109242 :           if (value<threshold_) {
+     393             :             double value = 1.0;
+     394        7076 :             targetDistGrid().setValue(l,value);
+     395             :           }
+     396             :         }
+     397             :       }
+     398           2 :       if (smoothening_) {
+     399           2 :         std::vector<unsigned> nbin=targetDistGrid().getNbin();
+     400           2 :         std::vector<double> dx=targetDistGrid().getDx();
+     401             :         // Smoothening
+     402         104 :         for(unsigned i=0; i<nbin[0]; i++) {
+     403        5304 :           for(unsigned j=0; j<nbin[1]; j++) {
+     404        5202 :             std::vector<unsigned> indices(2);
+     405        5202 :             indices[0]=i;
+     406        5202 :             indices[1]=j;
+     407        5202 :             Grid::index_t index = targetDistGrid().getIndex(indices);
+     408       10404 :             double energy = targetDistGrid().getPoint(index)[0];
+     409       10404 :             double volume = targetDistGrid().getPoint(index)[1];
+     410        5202 :             double value = targetDistGrid().getValue(index);
+     411        5202 :             if (value>(1-1.e-5)) { // Apply only if this grid point was 1.
+     412             :               // Apply gaussians around
+     413         773 :               std::vector<int> minBin(2), maxBin(2), deltaBin(2); // These cannot be unsigned
+     414             :               // Only consider contributions less than n*sigma bins apart from the actual distance
+     415         773 :               deltaBin[0]=std::floor(6*sigma_[0]/dx[0]);;
+     416         773 :               deltaBin[1]=std::floor(6*sigma_[1]/dx[1]);;
+     417             :               // For energy
+     418         773 :               minBin[0]=i - deltaBin[0];
+     419         773 :               if (minBin[0] < 0) minBin[0]=0;
+     420         773 :               if (minBin[0] > (nbin[0]-1)) minBin[0]=nbin[0]-1;
+     421         773 :               maxBin[0]=i +  deltaBin[0];
+     422         773 :               if (maxBin[0] > (nbin[0]-1)) maxBin[0]=nbin[0]-1;
+     423             :               // For volume
+     424         773 :               minBin[1]=j - deltaBin[1];
+     425         773 :               if (minBin[1] < 0) minBin[1]=0;
+     426         773 :               if (minBin[1] > (nbin[1]-1)) minBin[1]=nbin[1]-1;
+     427         773 :               maxBin[1]=j +  deltaBin[1];
+     428         773 :               if (maxBin[1] > (nbin[1]-1)) maxBin[1]=nbin[1]-1;
+     429       31273 :               for(unsigned l=minBin[0]; l<maxBin[0]+1; l++) {
+     430      549973 :                 for(unsigned m=minBin[1]; m<maxBin[1]+1; m++) {
+     431      519473 :                   std::vector<unsigned> indices_prime(2);
+     432      519473 :                   indices_prime[0]=l;
+     433      519473 :                   indices_prime[1]=m;
+     434      519473 :                   Grid::index_t index_prime = targetDistGrid().getIndex(indices_prime);
+     435     1038946 :                   double energy_prime = targetDistGrid().getPoint(index_prime)[0];
+     436     1038946 :                   double volume_prime = targetDistGrid().getPoint(index_prime)[1];
+     437      519473 :                   double value_prime = targetDistGrid().getValue(index_prime);
+     438             :                   // Apply gaussian
+     439     1558419 :                   double gaussian_value = GaussianSwitchingFunc(energy_prime,energy,sigma_[0])*GaussianSwitchingFunc(volume_prime,volume,sigma_[1]);
+     440      519473 :                   if (value_prime<gaussian_value) {
+     441       19817 :                     targetDistGrid().setValue(index_prime,gaussian_value);
+     442             :                   }
+     443             :                 }
+     444             :               }
+     445             :             }
+     446             :           }
+     447             :         }
+     448             :       }
+     449             :       // Normalize
+     450           4 :       std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     451             :       double norm = 0.0;
+     452        5204 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     453        5202 :         double value = targetDistGrid().getValue(l);
+     454        5202 :         norm += integration_weights[l]*value;
+     455             :       }
+     456           2 :       targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     457           0 :     } else plumed_merror(getName()+": Number of arguments for this target distribution must be 1 or 2");
+     458             :   }
+     459          14 :   updateLogTargetDistGrid();
+     460          14 : }
+     461             : 
+     462             : inline
+     463             : double TD_Multicanonical::GaussianSwitchingFunc(const double argument, const double center, const double sigma) const {
+     464     1039362 :   if(sigma>0.0) {
+     465     1039362 :     double arg=(argument-center)/sigma;
+     466     1039362 :     return exp(-0.5*arg*arg);
+     467             :   }
+     468             :   else {
+     469             :     return 0.0;
+     470             :   }
+     471             : }
+     472             : 
+     473             : 
+     474             : }
+     475             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..37ee59b1b2 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:14815297.4 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves25TD_MultithermalMultibaric8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe2326createERKNS_13ActionOptionsE2
_ZN4PLMD3ves25TD_MultithermalMultibaricC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves25TD_MultithermalMultibaricD0Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaricD2Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaric16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves25TD_MultithermalMultibaric10updateGridEv4
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe232C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe232D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.func.html b/coverage/ves/TD_MultithermalMultibaric.cpp.func.html new file mode 100644 index 0000000000..7dc1f90106 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:14815297.4 %
Date:2024-06-10 08:19:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe2326createERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe232C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe232D2Ev3473
_ZN4PLMD3ves25TD_MultithermalMultibaric10updateGridEv4
_ZN4PLMD3ves25TD_MultithermalMultibaric16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves25TD_MultithermalMultibaricC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves25TD_MultithermalMultibaricD0Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaricD2Ev2
_ZNK4PLMD3ves25TD_MultithermalMultibaric8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html b/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html new file mode 100644 index 0000000000..de9329f3f8 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html @@ -0,0 +1,535 @@ + + + + + + + + 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:14815297.4 %
Date:2024-06-10 08:19:14Functions:8988.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 "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Grid.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/Atoms.h"
+      29             : #include <cfloat>
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : //+PLUMEDOC VES_TARGETDIST TD_MULTITHERMAL_MULTIBARIC
+      36             : /*
+      37             : Multithermal-multibaric target distribution (dynamic).
+      38             : 
+      39             : Use the target distribution to sample the multithermal-multibaric ensemble \cite Piaggi-PRL-2019 \cite Okumura-CPL-2004.
+      40             : In this way, in a single molecular dynamics simulation one can obtain information
+      41             : about the simulated system in a range of temperatures and pressures.
+      42             : This range is determined through the keywords MIN_TEMP, MAX_TEMP, MIN_PRESSURE, and MAX_PRESSURE.
+      43             : One should also specified the target pressure of the barostat with the keyword PRESSURE.
+      44             : 
+      45             : The collective variables (CVs) used to construct the bias potential must be:
+      46             :   1. the potential energy and the volume or,
+      47             :   2. the potential energy, the volume, and an order parameter.
+      48             : 
+      49             : Other choices of CVs or a different order of the above mentioned CVs are nonsensical.
+      50             : 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 .
+      51             : 
+      52             : The algorithm will explore the free energy at each temperature and pressure up to a predefined free
+      53             :  energy threshold \f$\epsilon\f$ specified through the keyword THRESHOLD (in kT units).
+      54             : 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.
+      55             : If also an order parameter is used then the THRESHOLD should be greater than the barrier for the transformation in kT.
+      56             : For small systems undergoing a freezing transition THRESHOLD is typically between 20 and 50.
+      57             : 
+      58             : It is also important to specify the number of intermediate temperatures and pressures to consider.
+      59             : This is done through the keywords STEPS_TEMP and STEPS_PRESSURE.
+      60             : If the number of intermediate temperature and pressures is too small, then holes might appear in the target distribution.
+      61             : If it is too large, the performance will deteriorate with no additional advantage.
+      62             : 
+      63             : We now describe the algorithm more rigorously.
+      64             : The target distribution is given by
+      65             : \f[
+      66             : p(E,\mathcal{V},s)=
+      67             :   \begin{cases}
+      68             :     1/\Omega_{E,\mathcal{V},s} & \text{if there is at least one } \beta',P' \text{ such} \\
+      69             :              & \text{that } \beta' F_{\beta',P'}(E,\mathcal{V},s)<\epsilon \text{ with}  \\
+      70             :              & \beta_1>\beta'>\beta_2 \text{ and } P_1<P'<P_2 \\
+      71             :     0 & \text{otherwise}
+      72             :   \end{cases}
+      73             : \f]
+      74             : 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.
+      75             : 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$.
+      76             : The number of points is determined with the keywords STEPS_TEMP and STEPS_PRESSURE.
+      77             : In practice the target distribution is never set to zero but rather to a small value controlled by the keyword EPSILON.
+      78             : The small value is e^-EPSILON.
+      79             : 
+      80             : Much like in the Wang-Landau algorithm \cite wanglandau or in the multicanonical ensemble \cite Berg-PRL-1992 , a flat histogram is targeted.
+      81             : 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.
+      82             : 
+      83             : 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:
+      84             : \f[
+      85             : \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
+      86             : \f]
+      87             : 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.
+      88             : \f$ \beta F_{\beta,P}(E,\mathcal{V},s) \f$ is not know from the start and is instead found during the simulation.
+      89             : Therefore \f$ p(E,\mathcal{V},s) \f$ is determined iteratively as done in the well tempered target distribution \cite Valsson-JCTC-2015.
+      90             : 
+      91             : 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.
+      92             : The reweighting can be performed using the action \ref REWEIGHT_TEMP_PRESS.
+      93             : 
+      94             : The multicanonical ensemble (fixed volume) can be targeted using \ref TD_MULTICANONICAL.
+      95             : 
+      96             : \par Examples
+      97             : 
+      98             : The following input can be used to run a simulation in the multithermal-multibaric ensemble.
+      99             : The region of the temperature-pressure plane that will be explored is 260-350 K and 1 bar- 300 MPa.
+     100             : The energy and the volume are used as collective variables.
+     101             : Legendre polynomials are used to construct the two dimensional bias potential.
+     102             : The averaged stochastic gradient descent algorithm is chosen to optimize the VES functional.
+     103             : The target distribution is updated every 100 optimization steps (200 ps here) using the last estimation of the free energy.
+     104             : 
+     105             : \plumedfile
+     106             : # Use energy and volume as CVs
+     107             : energy: ENERGY
+     108             : vol: VOLUME
+     109             : 
+     110             : # Basis functions
+     111             : bf1: BF_LEGENDRE ORDER=10 MINIMUM=-14750 MAXIMUM=-12250
+     112             : bf2: BF_LEGENDRE ORDER=10 MINIMUM=6.5 MAXIMUM=8.25
+     113             : 
+     114             : # Target distribution - 1 bar = 0.06022140857 and 300 MPa = 180.66422571
+     115             : TD_MULTITHERMAL_MULTIBARIC ...
+     116             :  MIN_TEMP=260
+     117             :  MAX_TEMP=350
+     118             :  MAX_PRESSURE=180.66422571
+     119             :  MIN_PRESSURE=0.06022140857
+     120             :  PRESSURE=0.06022140857
+     121             :  LABEL=td_multi
+     122             : ... TD_MULTITHERMAL_MULTIBARIC
+     123             : 
+     124             : # Bias expansion
+     125             : VES_LINEAR_EXPANSION ...
+     126             :  ARG=energy,vol
+     127             :  BASIS_FUNCTIONS=bf1,bf2
+     128             :  TEMP=300.0
+     129             :  GRID_BINS=200,200
+     130             :  TARGET_DISTRIBUTION=td_multi
+     131             :  LABEL=b1
+     132             : ... VES_LINEAR_EXPANSION
+     133             : 
+     134             : # Optimization algorithm
+     135             : OPT_AVERAGED_SGD ...
+     136             :   BIAS=b1
+     137             :   STRIDE=500
+     138             :   LABEL=o1
+     139             :   STEPSIZE=1.0
+     140             :   FES_OUTPUT=500
+     141             :   BIAS_OUTPUT=500
+     142             :   TARGETDIST_OUTPUT=500
+     143             :   COEFFS_OUTPUT=100
+     144             :   TARGETDIST_STRIDE=100
+     145             : ... OPT_AVERAGED_SGD
+     146             : 
+     147             : \endplumedfile
+     148             : 
+     149             : 
+     150             : The multithermal-multibaric target distribution can also be used to explore regions of the phase diagram crossed by first order phase transitions.
+     151             : Consider a system of 250 atoms that crystallizes in the FCC crystal structure.
+     152             : The region of the temperature-pressure plane that will be explored is 350-450 K and 1bar-1GPa.
+     153             : We assume that inside this region we can find the liquid-FCC coexistence line that we would like to obtain.
+     154             : In this case in addition to the energy and volume, an order parameter must also be biased.
+     155             : The energy, volume, and an order parameter are used as collective variables to construct the bias potential.
+     156             : We choose as order parameter the \ref FCCUBIC.
+     157             : Legendre polynomials are used to construct the three dimensional bias potential.
+     158             : The averaged stochastic gradient descent algorithm is chosen to optimize the VES functional.
+     159             : The target distribution is updated every 100 optimization steps (200 ps here) using the last estimation of the free energy.
+     160             : 
+     161             : \plumedfile
+     162             : # Use energy, volume and FCCUBIC as CVs
+     163             : energy: ENERGY
+     164             : vol: VOLUME
+     165             : 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}
+     166             : 
+     167             : # Basis functions
+     168             : bf1: BF_LEGENDRE ORDER=8 MINIMUM=-26500 MAXIMUM=-23500
+     169             : bf2: BF_LEGENDRE ORDER=8 MINIMUM=8.0 MAXIMUM=11.5
+     170             : bf3: BF_LEGENDRE ORDER=8 MINIMUM=0.0 MAXIMUM=256.0
+     171             : 
+     172             : # Target distribution
+     173             : TD_MULTITHERMAL_MULTIBARIC ...
+     174             :  LABEL=td_multitp
+     175             :  MIN_TEMP=350.0
+     176             :  MAX_TEMP=450.0
+     177             :  MIN_PRESSURE=0.06022140857
+     178             :  MAX_PRESSURE=602.2140857
+     179             :  PRESSURE=301.10704285
+     180             :  SIGMA=250.0,0.1,10.0
+     181             :  THRESHOLD=15
+     182             :  STEPS_TEMP=20
+     183             :  STEPS_PRESSURE=20
+     184             : ... TD_MULTITHERMAL_MULTIBARIC
+     185             : 
+     186             : # Expansion
+     187             : VES_LINEAR_EXPANSION ...
+     188             :  ARG=energy,vol,fcc.morethan
+     189             :  BASIS_FUNCTIONS=bf1,bf2,bf3
+     190             :  TEMP=400.0
+     191             :  GRID_BINS=40,40,40
+     192             :  TARGET_DISTRIBUTION=td_multitp
+     193             :  LABEL=b1
+     194             : ... VES_LINEAR_EXPANSION
+     195             : 
+     196             : # Optimization algorithm
+     197             : OPT_AVERAGED_SGD ...
+     198             :   BIAS=b1
+     199             :   STRIDE=500
+     200             :   LABEL=o1
+     201             :   STEPSIZE=1.0
+     202             :   FES_OUTPUT=500
+     203             :   BIAS_OUTPUT=500
+     204             :   TARGETDIST_OUTPUT=500
+     205             :   COEFFS_OUTPUT=100
+     206             :   TARGETDIST_STRIDE=500
+     207             : ... OPT_AVERAGED_SGD
+     208             : 
+     209             : \endplumedfile
+     210             : 
+     211             : */
+     212             : //+ENDPLUMEDOC
+     213             : 
+     214             : class TD_MultithermalMultibaric: public TargetDistribution {
+     215             : private:
+     216             :   double threshold_, min_temp_, max_temp_;
+     217             :   double min_press_, max_press_, press_;
+     218             :   double epsilon_;
+     219             :   bool smoothening_;
+     220             :   std::vector<double> sigma_;
+     221             :   unsigned steps_temp_, steps_pressure_;
+     222             : public:
+     223             :   static void registerKeywords(Keywords&);
+     224             :   explicit TD_MultithermalMultibaric(const ActionOptions& ao);
+     225             :   void updateGrid() override;
+     226             :   double getValue(const std::vector<double>&) const override;
+     227           6 :   ~TD_MultithermalMultibaric() {}
+     228             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     229             : };
+     230             : 
+     231             : 
+     232       10421 : PLUMED_REGISTER_ACTION(TD_MultithermalMultibaric,"TD_MULTITHERMAL_MULTIBARIC")
+     233             : 
+     234             : 
+     235           3 : void TD_MultithermalMultibaric::registerKeywords(Keywords& keys) {
+     236           3 :   TargetDistribution::registerKeywords(keys);
+     237           6 :   keys.add("compulsory","THRESHOLD","5","Maximum exploration free energy in kT.");
+     238           6 :   keys.add("compulsory","EPSILON","10","The zeros of the target distribution are changed to e^-EPSILON.");
+     239           6 :   keys.add("compulsory","MIN_TEMP","Minimum energy.");
+     240           6 :   keys.add("compulsory","MAX_TEMP","Maximum energy.");
+     241           6 :   keys.add("compulsory","MIN_PRESSURE","Minimum pressure.");
+     242           6 :   keys.add("compulsory","MAX_PRESSURE","Maximum pressure.");
+     243           6 :   keys.add("compulsory","PRESSURE","Target pressure of the barostat used in the MD engine.");
+     244           6 :   keys.add("compulsory","STEPS_TEMP","20","Number of temperature steps.");
+     245           6 :   keys.add("compulsory","STEPS_PRESSURE","20","Number of pressure steps.");
+     246           6 :   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.");
+     247           3 : }
+     248             : 
+     249             : 
+     250           2 : TD_MultithermalMultibaric::TD_MultithermalMultibaric(const ActionOptions& ao):
+     251             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     252           2 :   threshold_(5.0),
+     253           2 :   min_temp_(0.0),
+     254           2 :   max_temp_(1000.0),
+     255           2 :   min_press_(0.0),
+     256           2 :   max_press_(1000.0),
+     257           2 :   epsilon_(10.0),
+     258           2 :   smoothening_(true),
+     259           2 :   steps_temp_(20),
+     260           2 :   steps_pressure_(20)
+     261             : {
+     262           2 :   log.printf("  Multithermal-multibaric target distribution");
+     263           2 :   log.printf("\n");
+     264             : 
+     265           2 :   log.printf("  Please read and cite ");
+     266           4 :   log << plumed.cite("Piaggi and Parrinello, Phys. Rev. Lett. 122 (5), 050601 (2019)");
+     267           2 :   log.printf(" and ");
+     268           4 :   log << plumed.cite("Piaggi and Parrinello, J. Chem. Phys. 150 (24), 244119 (2019)");
+     269           2 :   log.printf("\n");
+     270             : 
+     271             : 
+     272           2 :   parse("THRESHOLD",threshold_);
+     273           2 :   if(threshold_<=0.0) {
+     274           0 :     plumed_merror(getName()+": the value of the threshold should be positive.");
+     275             :   }
+     276           2 :   log.printf("  exploring free energy up to %f kT for each temperature and pressure\n",threshold_);
+     277           2 :   parse("MIN_TEMP",min_temp_);
+     278           2 :   parse("MAX_TEMP",max_temp_);
+     279           2 :   log.printf("  temperatures between %f and %f will be explored \n",min_temp_,max_temp_);
+     280           2 :   parse("MIN_PRESSURE",min_press_);
+     281           2 :   parse("MAX_PRESSURE",max_press_);
+     282           2 :   log.printf("  pressures between %f and %f will be explored \n",min_press_,max_press_);
+     283           2 :   parse("PRESSURE",press_);
+     284           2 :   log.printf("  pressure of the barostat should have been set to %f. Please check this in the MD engine \n",press_);
+     285           4 :   parseVector("SIGMA",sigma_);
+     286           2 :   if(sigma_.size()==0) smoothening_=false;
+     287           2 :   if(smoothening_ && (sigma_.size()<2 || sigma_.size()>3) ) plumed_merror(getName()+": SIGMA takes 2 or 3 values as input.");
+     288           2 :   if (smoothening_) {
+     289           2 :     log.printf("  the target distribution will be smoothed using sigma values");
+     290           7 :     for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_[i]);
+     291           2 :     log.printf("\n");
+     292             :   }
+     293           2 :   parse("STEPS_TEMP",steps_temp_);
+     294           2 :   parse("STEPS_PRESSURE",steps_pressure_);
+     295           2 :   log.printf("  %d steps in temperatures and %d steps in pressure will be employed \n",steps_temp_,steps_pressure_);
+     296           2 :   steps_temp_ += 1;
+     297           2 :   steps_pressure_ += 1;
+     298           2 :   parse("EPSILON",epsilon_);
+     299           2 :   if(epsilon_<=1.0) {
+     300           0 :     plumed_merror(getName()+": the value of epsilon should be greater than 1.");
+     301             :   }
+     302           2 :   log.printf("  the non relevant regions of the target distribution are set to e^-%f \n",epsilon_);
+     303             :   setDynamic();
+     304             :   setFesGridNeeded();
+     305           2 :   checkRead();
+     306           2 : }
+     307             : 
+     308             : 
+     309           0 : double TD_MultithermalMultibaric::getValue(const std::vector<double>& argument) const {
+     310           0 :   plumed_merror("getValue not implemented for TD_MultithermalMultibaric");
+     311             :   return 0.0;
+     312             : }
+     313             : 
+     314             : 
+     315           4 : void TD_MultithermalMultibaric::updateGrid() {
+     316           4 :   if (getStep() == 0) {
+     317           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");
+     318           2 :     if(smoothening_ && sigma_.size()!=targetDistGrid().getDimension()) plumed_merror(getName()+": mismatch between SIGMA dimension and number of arguments");
+     319             :     // Use uniform TD
+     320           4 :     std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     321             :     double norm = 0.0;
+     322       11864 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     323             :       double value = 1.0;
+     324       11862 :       norm += integration_weights[l]*value;
+     325       11862 :       targetDistGrid().setValue(l,value);
+     326             :     }
+     327           2 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     328             :   } else {
+     329           2 :     double beta = getBeta();
+     330           2 :     double beta_prime_min = 1./(plumed.getAtoms().getKBoltzmann()*min_temp_);
+     331           2 :     double beta_prime_max = 1./(plumed.getAtoms().getKBoltzmann()*max_temp_);
+     332           2 :     plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_MultithermalMultibaric!");
+     333             :     // Set all to current epsilon value
+     334       11864 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     335       11862 :       double value = exp(-1.0*epsilon_);
+     336       11862 :       targetDistGrid().setValue(l,value);
+     337             :     }
+     338             :     // Loop over pressures and temperatures
+     339          44 :     for(unsigned i=0; i<steps_temp_; i++) {
+     340          42 :       double beta_prime=beta_prime_min + (beta_prime_max-beta_prime_min)*i/(steps_temp_-1);
+     341         924 :       for(unsigned j=0; j<steps_pressure_; j++) {
+     342         882 :         double pressure_prime=min_press_ + (max_press_-min_press_)*j/(steps_pressure_-1);
+     343             :         // Find minimum for this pressure and temperature
+     344             :         double minval=DBL_MAX;
+     345     5232024 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     346    10462284 :           double energy = targetDistGrid().getPoint(l)[0];
+     347    10462284 :           double volume = targetDistGrid().getPoint(l)[1];
+     348     5231142 :           double value = getFesGridPntr()->getValue(l);
+     349     5231142 :           value = beta*value + (beta_prime-beta)*energy + (beta_prime*pressure_prime-beta*press_)*volume;
+     350     5231142 :           if(value<minval) {
+     351             :             minval=value;
+     352             :           }
+     353             :         }
+     354             :         // Now check which energies and volumes are below X kt
+     355     5232024 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     356    10462284 :           double energy = targetDistGrid().getPoint(l)[0];
+     357    10462284 :           double volume = targetDistGrid().getPoint(l)[1];
+     358     5231142 :           double value = getFesGridPntr()->getValue(l);
+     359     5231142 :           value = beta*value + (beta_prime-beta)*energy + (beta_prime*pressure_prime-beta*press_)*volume - minval;
+     360     5231142 :           if (value<threshold_) {
+     361             :             double value = 1.0;
+     362       65261 :             targetDistGrid().setValue(l,value);
+     363             :           }
+     364             :         }
+     365             :       }
+     366             :     }
+     367           2 :     if (smoothening_) {
+     368           2 :       std::vector<unsigned> nbin=targetDistGrid().getNbin();
+     369           2 :       std::vector<double> dx=targetDistGrid().getDx();
+     370           2 :       unsigned dim=targetDistGrid().getDimension();
+     371             :       // Smoothening
+     372       11864 :       for(Grid::index_t index=0; index<targetDistGrid().getSize(); index++) {
+     373       11862 :         std::vector<unsigned> indices = targetDistGrid().getIndices(index);
+     374       11862 :         std::vector<double> point = targetDistGrid().getPoint(index);
+     375       11862 :         double value = targetDistGrid().getValue(index);
+     376       11862 :         if (value>(1-1.e-5)) { // Apply only if this grid point was 1.
+     377             :           // Apply gaussians around
+     378        1242 :           std::vector<int> minBin(dim), maxBin(dim); // These cannot be unsigned
+     379             :           // Only consider contributions less than n*sigma bins apart from the actual distance
+     380        4384 :           for(unsigned k=0; k<dim; k++) {
+     381        3142 :             int deltaBin=std::floor(6*sigma_[k]/dx[k]);
+     382        3142 :             minBin[k]=indices[k] - deltaBin;
+     383        3142 :             if (minBin[k] < 0) minBin[k]=0;
+     384        3142 :             if (minBin[k] > (nbin[k]-1)) minBin[k]=nbin[k]-1;
+     385        3142 :             maxBin[k]=indices[k] + deltaBin;
+     386        3142 :             if (maxBin[k] > (nbin[k]-1)) maxBin[k]=nbin[k]-1;
+     387             :           }
+     388        1242 :           if (dim==2) {
+     389        7008 :             for(unsigned l=minBin[0]; l<maxBin[0]+1; l++) {
+     390      115632 :               for(unsigned m=minBin[1]; m<maxBin[1]+1; m++) {
+     391      109208 :                 std::vector<unsigned> indices_prime(dim);
+     392      109208 :                 indices_prime[0]=l;
+     393      109208 :                 indices_prime[1]=m;
+     394      109208 :                 Grid::index_t index_prime = targetDistGrid().getIndex(indices_prime);
+     395      109208 :                 std::vector<double> point_prime = targetDistGrid().getPoint(index_prime);
+     396      109208 :                 double value_prime = targetDistGrid().getValue(index_prime);
+     397             :                 // Apply gaussian
+     398             :                 double gaussian_value = 1;
+     399      327624 :                 for(unsigned k=0; k<dim; k++) {
+     400      436832 :                   gaussian_value *= GaussianSwitchingFunc(point_prime[k],point[k],sigma_[k]);
+     401             :                 }
+     402      109208 :                 if (value_prime<gaussian_value) {
+     403        2761 :                   targetDistGrid().setValue(index_prime,gaussian_value);
+     404             :                 }
+     405             :               }
+     406             :             }
+     407         658 :           } else if (dim==3) {
+     408       12352 :             for(unsigned l=minBin[0]; l<maxBin[0]+1; l++) {
+     409       84952 :               for(unsigned m=minBin[1]; m<maxBin[1]+1; m++) {
+     410      509608 :                 for(unsigned n=minBin[2]; n<maxBin[2]+1; n++) {
+     411      436350 :                   std::vector<unsigned> indices_prime(dim);
+     412      436350 :                   indices_prime[0]=l;
+     413      436350 :                   indices_prime[1]=m;
+     414      436350 :                   indices_prime[2]=n;
+     415      436350 :                   Grid::index_t index_prime = targetDistGrid().getIndex(indices_prime);
+     416      436350 :                   std::vector<double> point_prime = targetDistGrid().getPoint(index_prime);
+     417      436350 :                   double value_prime = targetDistGrid().getValue(index_prime);
+     418             :                   // Apply gaussian
+     419             :                   double gaussian_value = 1;
+     420     1745400 :                   for(unsigned k=0; k<dim; k++) {
+     421     2618100 :                     gaussian_value *= GaussianSwitchingFunc(point_prime[k],point[k],sigma_[k]);
+     422             :                   }
+     423      436350 :                   if (value_prime<gaussian_value) {
+     424       13789 :                     targetDistGrid().setValue(index_prime,gaussian_value);
+     425             :                   }
+     426             :                 }
+     427             :               }
+     428             :             }
+     429             :           }
+     430             :         }
+     431             :       }
+     432             :     }
+     433             :     // Normalize
+     434           4 :     std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     435             :     double norm = 0.0;
+     436       11864 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     437       11862 :       double value = targetDistGrid().getValue(l);
+     438       11862 :       norm += integration_weights[l]*value;
+     439             :     }
+     440           2 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     441             :   }
+     442           4 :   updateLogTargetDistGrid();
+     443           4 : }
+     444             : 
+     445             : inline
+     446             : double TD_MultithermalMultibaric::GaussianSwitchingFunc(const double argument, const double center, const double sigma) const {
+     447     1527466 :   if(sigma>0.0) {
+     448     1527466 :     double arg=(argument-center)/sigma;
+     449     1527466 :     return exp(-0.5*arg*arg);
+     450             :   }
+     451             :   else {
+     452             :     return 0.0;
+     453             :   }
+     454             : }
+     455             : 
+     456             : 
+     457             : }
+     458             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..e8dec1aea3 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:567673.7 %
Date:2024-06-10 08:19:14Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe1406createERKNS_13ActionOptionsE4
_ZN4PLMD3ves21TD_ProductCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE4
_ZN4PLMD3ves21TD_ProductCombinationC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves21TD_ProductCombination16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves21TD_ProductCombination10updateGridEv14
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe140C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe140D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.func.html b/coverage/ves/TD_ProductCombination.cpp.func.html new file mode 100644 index 0000000000..22c26a7095 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:567673.7 %
Date:2024-06-10 08:19:14Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe1406createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe140C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe140D2Ev3473
_ZN4PLMD3ves21TD_ProductCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves21TD_ProductCombination10updateGridEv14
_ZN4PLMD3ves21TD_ProductCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves21TD_ProductCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves21TD_ProductCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombination16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves21TD_ProductCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE4
_ZN4PLMD3ves21TD_ProductCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombinationC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves21TD_ProductCombination8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.gcov.html b/coverage/ves/TD_ProductCombination.cpp.gcov.html new file mode 100644 index 0000000000..6b5f60bb3e --- /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:567673.7 %
Date:2024-06-10 08:19:14Functions:91369.2 %
+
+ + + + + + + + +

+
          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       10423 : PLUMED_REGISTER_ACTION(TD_ProductCombination,"TD_PRODUCT_COMBINATION")
+     141             : 
+     142             : 
+     143           5 : void TD_ProductCombination::registerKeywords(Keywords& keys) {
+     144           5 :   TargetDistribution::registerKeywords(keys);
+     145          10 :   keys.add("compulsory","DISTRIBUTIONS","The labels of the target distribution actions to be used in the product combination.");
+     146           5 :   keys.use("WELLTEMPERED_FACTOR");
+     147           5 :   keys.use("SHIFT_TO_ZERO");
+     148           5 : }
+     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.15
+
+ + + 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 0000000000..fb3be2bb73 --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + 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:497763.6 %
Date:2024-06-10 08:19:14Functions:71353.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe1036createERKNS_13ActionOptionsE15
_ZN4PLMD3ves22TD_ProductDistribution10updateGridEv15
_ZN4PLMD3ves22TD_ProductDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE15
_ZN4PLMD3ves22TD_ProductDistributionC2ERKNS_13ActionOptionsE15
_ZN4PLMD3ves22TD_ProductDistribution16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe103C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe103D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.func.html b/coverage/ves/TD_ProductDistribution.cpp.func.html new file mode 100644 index 0000000000..1ddd7a9ba9 --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + 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:497763.6 %
Date:2024-06-10 08:19:14Functions:71353.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe1036createERKNS_13ActionOptionsE15
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe103C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe103D2Ev3473
_ZN4PLMD3ves22TD_ProductDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves22TD_ProductDistribution10updateGridEv15
_ZN4PLMD3ves22TD_ProductDistribution11linkFesGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves22TD_ProductDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD3ves22TD_ProductDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE15
_ZN4PLMD3ves22TD_ProductDistribution25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistributionC2ERKNS_13ActionOptionsE15
_ZNK4PLMD3ves22TD_ProductDistribution8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.gcov.html b/coverage/ves/TD_ProductDistribution.cpp.gcov.html new file mode 100644 index 0000000000..56a0e6d010 --- /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:497763.6 %
Date:2024-06-10 08:19:14Functions:71353.8 %
+
+ + + + + + + + +

+
          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       10434 : PLUMED_REGISTER_ACTION(TD_ProductDistribution,"TD_PRODUCT_DISTRIBUTION")
+     104             : 
+     105             : 
+     106          16 : void TD_ProductDistribution::registerKeywords(Keywords& keys) {
+     107          16 :   TargetDistribution::registerKeywords(keys);
+     108          32 :   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          16 :   keys.use("WELLTEMPERED_FACTOR");
+     110          16 :   keys.use("SHIFT_TO_ZERO");
+     111          16 :   keys.use("NORMALIZE");
+     112          16 : }
+     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.15
+
+ + + 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 0000000000..adb7518f2f --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + 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:555698.2 %
Date:2024-06-10 08:19:14Functions:77100.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
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe1946createERKNS_13ActionOptionsE73
_ZN4PLMD3ves10TD_Uniform16registerKeywordsERNS_8KeywordsE74
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe194C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe194D2Ev3473
_ZNK4PLMD3ves10TD_Uniform8getValueERKSt6vectorIdSaIdEE118654
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.func.html b/coverage/ves/TD_Uniform.cpp.func.html new file mode 100644 index 0000000000..23a384ca77 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + 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:555698.2 %
Date:2024-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10TD_Uniform16registerKeywordsERNS_8KeywordsE74
_ZN4PLMD3ves10TD_Uniform20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE73
_ZN4PLMD3ves10TD_UniformC2ERKNS_13ActionOptionsE73
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe1946createERKNS_13ActionOptionsE73
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe194C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe194D2Ev3473
_ZNK4PLMD3ves10TD_Uniform8getValueERKSt6vectorIdSaIdEE118654
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.gcov.html b/coverage/ves/TD_Uniform.cpp.gcov.html new file mode 100644 index 0000000000..07f125bd78 --- /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:555698.2 %
Date:2024-06-10 08:19:14Functions:77100.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       10492 : PLUMED_REGISTER_ACTION(TD_Uniform,"TD_UNIFORM")
+     195             : 
+     196             : 
+     197          74 : void TD_Uniform::registerKeywords(Keywords& keys) {
+     198          74 :   TargetDistribution::registerKeywords(keys);
+     199         148 :   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         148 :   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         148 :   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         148 :   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          74 : }
+     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.15
+
+ + + 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 0000000000..135ae5b6b1 --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + 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:757698.7 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_VonMisesC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe1126createERKNS_13ActionOptionsE9
_ZN4PLMD3ves11TD_VonMises16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD3ves11TD_VonMises16getNormalizationEdd19
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe112C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe112D2Ev3473
_ZNK4PLMD3ves11TD_VonMises8getValueERKSt6vectorIdSaIdEE31100
_ZNK4PLMD3ves11TD_VonMises16VonMisesDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_80319
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.func.html b/coverage/ves/TD_VonMises.cpp.func.html new file mode 100644 index 0000000000..314b37ff8d --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + 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:757698.7 %
Date:2024-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_VonMises16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves11TD_VonMisesC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe1126createERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe112C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe112D2Ev3473
_ZNK4PLMD3ves11TD_VonMises16VonMisesDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_80319
_ZNK4PLMD3ves11TD_VonMises16getNormalizationEdd19
_ZNK4PLMD3ves11TD_VonMises8getValueERKSt6vectorIdSaIdEE31100
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.gcov.html b/coverage/ves/TD_VonMises.cpp.gcov.html new file mode 100644 index 0000000000..2b152886a9 --- /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:757698.7 %
Date:2024-06-10 08:19:14Functions: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 "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       10428 : PLUMED_REGISTER_ACTION(TD_VonMises,"TD_VONMISES")
+     113             : 
+     114             : 
+     115          10 : void TD_VonMises::registerKeywords(Keywords& keys) {
+     116          10 :   TargetDistribution::registerKeywords(keys);
+     117          20 :   keys.add("numbered","CENTER","The centers of the Von Mises distributions.");
+     118          20 :   keys.add("numbered","SIGMA","The \"standard deviations\" of the Von Mises distributions.");
+     119          20 :   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          20 :   keys.add("hidden","PERIODS","The periods for each of the dimensions. By default they are 2*pi for each dimension.");
+     121          10 :   keys.use("WELLTEMPERED_FACTOR");
+     122          10 :   keys.use("SHIFT_TO_ZERO");
+     123             :   //keys.use("NORMALIZE");
+     124          10 : }
+     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.15
+
+ + + 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 0000000000..ef89263792 --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + 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:293290.6 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves15TD_WellTemperedD2Ev0
_ZNK4PLMD3ves15TD_WellTempered8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe1136createERKNS_13ActionOptionsE29
_ZN4PLMD3ves15TD_WellTemperedC2ERKNS_13ActionOptionsE29
_ZN4PLMD3ves15TD_WellTemperedD0Ev29
_ZN4PLMD3ves15TD_WellTempered16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD3ves15TD_WellTempered10updateGridEv319
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe113C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe113D2Ev3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.func.html b/coverage/ves/TD_WellTempered.cpp.func.html new file mode 100644 index 0000000000..7fb17f9d89 --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + 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:293290.6 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe1136createERKNS_13ActionOptionsE29
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe113C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe113D2Ev3473
_ZN4PLMD3ves15TD_WellTempered10updateGridEv319
_ZN4PLMD3ves15TD_WellTempered16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD3ves15TD_WellTemperedC2ERKNS_13ActionOptionsE29
_ZN4PLMD3ves15TD_WellTemperedD0Ev29
_ZN4PLMD3ves15TD_WellTemperedD2Ev0
_ZNK4PLMD3ves15TD_WellTempered8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.gcov.html b/coverage/ves/TD_WellTempered.cpp.gcov.html new file mode 100644 index 0000000000..02852c905a --- /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:293290.6 %
Date:2024-06-10 08:19:14Functions:7977.8 %
+
+ + + + + + + + +

+
          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       10448 : PLUMED_REGISTER_ACTION(TD_WellTempered,"TD_WELLTEMPERED")
+     114             : 
+     115             : 
+     116          30 : void TD_WellTempered::registerKeywords(Keywords& keys) {
+     117          30 :   TargetDistribution::registerKeywords(keys);
+     118          60 :   keys.add("compulsory","BIASFACTOR","The bias factor used for the well-tempered distribution.");
+     119          30 : }
+     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.15
+
+ + + 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 0000000000..4b3018cc76 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves19WellTemperedModifer25getModifedTargetDistValueEdRKSt6vectorIdSaIdEE21206
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.func.html b/coverage/ves/TargetDistModifer.h.func.html new file mode 100644 index 0000000000..1d4e4b4c5a --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves19WellTemperedModifer25getModifedTargetDistValueEdRKSt6vectorIdSaIdEE21206
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.gcov.html b/coverage/ves/TargetDistModifer.h.gcov.html new file mode 100644 index 0000000000..5324f3136f --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..0ed534d4e7 --- /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:19021887.2 %
Date:2024-06-10 08:19:14Functions: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_8KeywordsE424
_ZN4PLMD3ves18TargetDistribution16updateTargetDistEv802
_ZN4PLMD3ves18TargetDistribution13integrateGridEPKNS_4GridE901
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.func.html b/coverage/ves/TargetDistribution.cpp.func.html new file mode 100644 index 0000000000..910b36820a --- /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:19021887.2 %
Date:2024-06-10 08:19:14Functions: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_8KeywordsE424
_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.15
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.gcov.html b/coverage/ves/TargetDistribution.cpp.gcov.html new file mode 100644 index 0000000000..37fece3c87 --- /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:19021887.2 %
Date:2024-06-10 08:19:14Functions: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         424 : void TargetDistribution::registerKeywords( Keywords& keys ) {
+      41         424 :   Action::registerKeywords(keys);
+      42        1272 :   keys.reserve("optional","WELLTEMPERED_FACTOR","Broaden the target distribution such that it is taken as [p(s)]^(1/\\f$\\gamma\\f$) where \\f$\\gamma\\f$ is the well tempered factor given here. If this option is active the distribution will be automatically normalized.");
+      43         848 :   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         848 :   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         424 : }
+      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           6 :       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          56 :     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.15
+
+ + + 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 0000000000..0f80b0ab4f --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.func.html b/coverage/ves/TargetDistribution.h.func.html new file mode 100644 index 0000000000..6b33928207 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.gcov.html b/coverage/ves/TargetDistribution.h.gcov.html new file mode 100644 index 0000000000..2f9cda4387 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..71afc124c3 --- /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:33043276.4 %
Date:2024-06-10 08:19:14Functions: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_8KeywordsE91
_ZN4PLMD3ves7VesBias18useGridBinKeywordsERNS_8KeywordsE91
_ZN4PLMD3ves7VesBias21useBiasCutoffKeywordsERNS_8KeywordsE91
_ZN4PLMD3ves7VesBias24useInitialCoeffsKeywordsERNS_8KeywordsE91
_ZN4PLMD3ves7VesBias24useProjectionArgKeywordsERNS_8KeywordsE91
_ZN4PLMD3ves7VesBias29useTargetDistributionKeywordsERNS_8KeywordsE91
_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.15
+
+ + + diff --git a/coverage/ves/VesBias.cpp.func.html b/coverage/ves/VesBias.cpp.func.html new file mode 100644 index 0000000000..aafb4c05b9 --- /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:33043276.4 %
Date:2024-06-10 08:19:14Functions: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_8KeywordsE91
_ZN4PLMD3ves7VesBias18useGridBinKeywordsERNS_8KeywordsE91
_ZN4PLMD3ves7VesBias19multiSimSumAveragesEjd120
_ZN4PLMD3ves7VesBias19readCoeffsFromFilesEv90
_ZN4PLMD3ves7VesBias20addToSampledAveragesERKSt6vectorIdSaIdEEj23556
_ZN4PLMD3ves7VesBias20updateReweightFactorEv0
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKNS0_12CoeffsVectorEj453
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKSt6vectorIdSaIdEEj0
_ZN4PLMD3ves7VesBias21useBiasCutoffKeywordsERNS_8KeywordsE91
_ZN4PLMD3ves7VesBias21useGridLimitsKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias24updateGradientAndHessianEb22810
_ZN4PLMD3ves7VesBias24useInitialCoeffsKeywordsERNS_8KeywordsE91
_ZN4PLMD3ves7VesBias24useProjectionArgKeywordsERNS_8KeywordsE91
_ZN4PLMD3ves7VesBias25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias27checkThatTemperatureIsGivenEv175
_ZN4PLMD3ves7VesBias27setTargetDistAveragesToZeroEj0
_ZN4PLMD3ves7VesBias29useTargetDistributionKeywordsERNS_8KeywordsE91
_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.15
+
+ + + diff --git a/coverage/ves/VesBias.cpp.gcov.html b/coverage/ves/VesBias.cpp.gcov.html new file mode 100644 index 0000000000..e88399b611 --- /dev/null +++ b/coverage/ves/VesBias.cpp.gcov.html @@ -0,0 +1,838 @@ + + + + + + + + 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:33043276.4 %
Date:2024-06-10 08:19:14Functions: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 "core/Atoms.h"
+      36             : #include "tools/File.h"
+      37             : 
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace ves {
+      41             : 
+      42          90 : VesBias::VesBias(const ActionOptions&ao):
+      43             :   Action(ao),
+      44             :   Bias(ao),
+      45          90 :   ncoeffssets_(0),
+      46          90 :   sampled_averages(0),
+      47          90 :   sampled_cross_averages(0),
+      48          90 :   use_multiple_coeffssets_(false),
+      49          90 :   coeffs_fnames(0),
+      50          90 :   ncoeffs_total_(0),
+      51          90 :   optimizer_pntr_(NULL),
+      52          90 :   optimize_coeffs_(false),
+      53          90 :   compute_hessian_(false),
+      54          90 :   diagonal_hessian_(true),
+      55          90 :   aver_counters(0),
+      56          90 :   kbt_(0.0),
+      57          90 :   targetdist_pntrs_(0),
+      58          90 :   dynamic_targetdist_(false),
+      59          90 :   grid_bins_(0),
+      60          90 :   grid_min_(0),
+      61          90 :   grid_max_(0),
+      62          90 :   bias_filename_(""),
+      63          90 :   fes_filename_(""),
+      64          90 :   targetdist_filename_(""),
+      65          90 :   coeffs_id_prefix_("c-"),
+      66          90 :   bias_file_fmt_("14.9f"),
+      67          90 :   fes_file_fmt_("14.9f"),
+      68          90 :   targetdist_file_fmt_("14.9f"),
+      69          90 :   targetdist_restart_file_fmt_("30.16e"),
+      70          90 :   filenames_have_iteration_number_(false),
+      71          90 :   bias_fileoutput_active_(false),
+      72          90 :   fes_fileoutput_active_(false),
+      73          90 :   fesproj_fileoutput_active_(false),
+      74          90 :   dynamic_targetdist_fileoutput_active_(false),
+      75          90 :   static_targetdist_fileoutput_active_(true),
+      76          90 :   bias_cutoff_active_(false),
+      77          90 :   bias_cutoff_value_(0.0),
+      78          90 :   bias_current_max_value(0.0),
+      79          90 :   calc_reweightfactor_(false),
+      80         180 :   optimization_threshold_(0.0)
+      81             : {
+      82          90 :   log.printf("  VES bias, please read and cite ");
+      83         180 :   log << plumed.cite("Valsson and Parrinello, Phys. Rev. Lett. 113, 090601 (2014)");
+      84          90 :   log.printf("\n");
+      85             : 
+      86          90 :   double temp=0.0;
+      87          90 :   parse("TEMP",temp);
+      88          90 :   if(temp>0.0) {
+      89          90 :     kbt_=plumed.getAtoms().getKBoltzmann()*temp;
+      90             :   }
+      91             :   else {
+      92           0 :     kbt_=plumed.getAtoms().getKbT();
+      93             :   }
+      94          90 :   if(kbt_>0.0) {
+      95          90 :     log.printf("  KbT: %f\n",kbt_);
+      96             :   }
+      97             :   // NOTE: the check for that the temperature is given is done when linking the optimizer later on.
+      98             : 
+      99         180 :   if(keywords.exists("COEFFS")) {
+     100         180 :     parseVector("COEFFS",coeffs_fnames);
+     101             :   }
+     102             : 
+     103         180 :   if(keywords.exists("GRID_BINS")) {
+     104         180 :     parseMultipleValues<unsigned int>("GRID_BINS",grid_bins_,getNumberOfArguments(),100);
+     105             :   }
+     106             : 
+     107          90 :   if(keywords.exists("GRID_MIN") && keywords.exists("GRID_MAX")) {
+     108           0 :     parseMultipleValues("GRID_MIN",grid_min_,getNumberOfArguments());
+     109           0 :     parseMultipleValues("GRID_MAX",grid_max_,getNumberOfArguments());
+     110             :   }
+     111             : 
+     112             :   std::vector<std::string> targetdist_labels;
+     113         180 :   if(keywords.exists("TARGET_DISTRIBUTION")) {
+     114         180 :     parseVector("TARGET_DISTRIBUTION",targetdist_labels);
+     115          90 :     if(targetdist_labels.size()>1) {
+     116           0 :       plumed_merror(getName()+" with label "+getLabel()+": multiple target distribution labels not allowed");
+     117             :     }
+     118             :   }
+     119           0 :   else if(keywords.exists("TARGET_DISTRIBUTIONS")) {
+     120           0 :     parseVector("TARGET_DISTRIBUTIONS",targetdist_labels);
+     121             :   }
+     122             : 
+     123          90 :   std::string error_msg = "";
+     124         180 :   targetdist_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     125          90 :   if(error_msg.size()>0) {plumed_merror("Problem with target distribution in "+getName()+": "+error_msg);}
+     126             : 
+     127         135 :   for(unsigned int i=0; i<targetdist_pntrs_.size(); i++) {
+     128          45 :     targetdist_pntrs_[i]->linkVesBias(this);
+     129             :   }
+     130             : 
+     131             : 
+     132          90 :   if(getNumberOfArguments()>2) {
+     133             :     disableStaticTargetDistFileOutput();
+     134             :   }
+     135             : 
+     136             : 
+     137         180 :   if(keywords.exists("BIAS_FILE")) {
+     138         180 :     parse("BIAS_FILE",bias_filename_);
+     139          90 :     if(bias_filename_.size()==0) {
+     140         180 :       bias_filename_ = "bias." + getLabel() + ".data";
+     141             :     }
+     142             :   }
+     143         180 :   if(keywords.exists("FES_FILE")) {
+     144         180 :     parse("FES_FILE",fes_filename_);
+     145          90 :     if(fes_filename_.size()==0) {
+     146         180 :       fes_filename_ = "fes." + getLabel() + ".data";
+     147             :     }
+     148             :   }
+     149         180 :   if(keywords.exists("TARGETDIST_FILE")) {
+     150         180 :     parse("TARGETDIST_FILE",targetdist_filename_);
+     151          90 :     if(targetdist_filename_.size()==0) {
+     152         180 :       targetdist_filename_ = "targetdist." + getLabel() + ".data";
+     153             :     }
+     154             :   }
+     155             :   //
+     156         180 :   if(keywords.exists("BIAS_FILE_FMT")) {
+     157           0 :     parse("BIAS_FILE_FMT",bias_file_fmt_);
+     158             :   }
+     159         180 :   if(keywords.exists("FES_FILE_FMT")) {
+     160           0 :     parse("FES_FILE_FMT",fes_file_fmt_);
+     161             :   }
+     162         180 :   if(keywords.exists("TARGETDIST_FILE_FMT")) {
+     163           0 :     parse("TARGETDIST_FILE_FMT",targetdist_file_fmt_);
+     164             :   }
+     165         180 :   if(keywords.exists("TARGETDIST_RESTART_FILE_FMT")) {
+     166           0 :     parse("TARGETDIST_RESTART_FILE_FMT",targetdist_restart_file_fmt_);
+     167             :   }
+     168             : 
+     169             :   //
+     170         180 :   if(keywords.exists("BIAS_CUTOFF")) {
+     171          90 :     double cutoff_value=0.0;
+     172          90 :     parse("BIAS_CUTOFF",cutoff_value);
+     173          90 :     if(cutoff_value<0.0) {
+     174           0 :       plumed_merror("the value given in BIAS_CUTOFF doesn't make sense, it should be larger than 0.0");
+     175             :     }
+     176             :     //
+     177          90 :     if(cutoff_value>0.0) {
+     178           3 :       double fermi_lambda=10.0;
+     179           3 :       parse("BIAS_CUTOFF_FERMI_LAMBDA",fermi_lambda);
+     180           3 :       setupBiasCutoff(cutoff_value,fermi_lambda);
+     181           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);
+     182           6 :       log << plumed.cite("McCarty, Valsson, Tiwary, and Parrinello, Phys. Rev. Lett. 115, 070601 (2015)");
+     183           3 :       log.printf("\n");
+     184             :     }
+     185             :   }
+     186             : 
+     187             : 
+     188         180 :   if(keywords.exists("PROJ_ARG")) {
+     189             :     std::vector<std::string> proj_arg;
+     190          90 :     for(int i=1;; i++) {
+     191         212 :       if(!parseNumberedVector("PROJ_ARG",i,proj_arg)) {break;}
+     192             :       // checks
+     193          16 :       if(proj_arg.size() > (getNumberOfArguments()-1) ) {
+     194           0 :         plumed_merror("PROJ_ARG must be a subset of ARG");
+     195             :       }
+     196             :       //
+     197          32 :       for(unsigned int k=0; k<proj_arg.size(); k++) {
+     198             :         bool found = false;
+     199          24 :         for(unsigned int l=0; l<getNumberOfArguments(); l++) {
+     200          24 :           if(proj_arg[k]==getPntrToArgument(l)->getName()) {
+     201             :             found = true;
+     202             :             break;
+     203             :           }
+     204             :         }
+     205          16 :         if(!found) {
+     206           0 :           std::string s1; Tools::convert(i,s1);
+     207           0 :           std::string error = "PROJ_ARG" + s1 + ": label " + proj_arg[k] + " is not among the arguments given in ARG";
+     208           0 :           plumed_merror(error);
+     209             :         }
+     210             :       }
+     211             :       //
+     212          16 :       projection_args_.push_back(proj_arg);
+     213          16 :     }
+     214          90 :   }
+     215             : 
+     216         180 :   if(keywords.exists("CALC_REWEIGHT_FACTOR")) {
+     217           0 :     parseFlag("CALC_REWEIGHT_FACTOR",calc_reweightfactor_);
+     218           0 :     if(calc_reweightfactor_) {
+     219           0 :       addComponent("rct"); componentIsNotPeriodic("rct");
+     220           0 :       updateReweightFactor();
+     221             :     }
+     222             :   }
+     223             : 
+     224         180 :   if(keywords.exists("OPTIMIZATION_THRESHOLD")) {
+     225          90 :     parse("OPTIMIZATION_THRESHOLD",optimization_threshold_);
+     226          90 :     if(optimization_threshold_ < 0.0) {
+     227           0 :       plumed_merror("OPTIMIZATION_THRESHOLD should be a postive value");
+     228             :     }
+     229          90 :     if(optimization_threshold_!=0.0) {
+     230           1 :       log.printf("  Employing a threshold value of %e for optimization of localized basis functions.\n",optimization_threshold_);
+     231             :     }
+     232             :   }
+     233             : 
+     234          90 : }
+     235             : 
+     236             : 
+     237          90 : VesBias::~VesBias() {
+     238         180 : }
+     239             : 
+     240             : 
+     241          91 : void VesBias::registerKeywords( Keywords& keys ) {
+     242          91 :   Bias::registerKeywords(keys);
+     243         182 :   keys.add("optional","TEMP","the system temperature - this is needed if the MD code does not pass the temperature to PLUMED.");
+     244             :   //
+     245         182 :   keys.reserve("optional","COEFFS","read in the coefficients from files.");
+     246             :   //
+     247         273 :   keys.reserve("optional","TARGET_DISTRIBUTION","the label of the target distribution to be used.");
+     248         273 :   keys.reserve("optional","TARGET_DISTRIBUTIONS","the label of the target distribution to be used. Here you are allows to use multiple labels.");
+     249             :   //
+     250         182 :   keys.reserve("optional","GRID_BINS","the number of bins used for the grid. The default value is 100 bins per dimension.");
+     251         182 :   keys.reserve("optional","GRID_MIN","the lower bounds used for the grid.");
+     252         182 :   keys.reserve("optional","GRID_MAX","the upper bounds used for the grid.");
+     253             :   //
+     254         182 :   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.");
+     255         182 :   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.");
+     256         182 :   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.");
+     257             :   //
+     258             :   // keys.add("optional","BIAS_FILE_FMT","the format of the bias files, by default it is %14.9f.");
+     259             :   // keys.add("optional","FES_FILE_FMT","the format of the FES files, by default it is %14.9f.");
+     260             :   // keys.add("optional","TARGETDIST_FILE_FMT","the format of the target distribution files, by default it is %14.9f.");
+     261             :   // 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.");
+     262             :   //
+     263         182 :   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.");
+     264         273 :   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.");
+     265             :   //
+     266         182 :   keys.reserve("numbered","PROJ_ARG","arguments for doing projections of the FES or the target distribution.");
+     267             :   //
+     268         182 :   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.");
+     269         273 :   keys.add("optional","OPTIMIZATION_THRESHOLD","Threshold value to turn off optimization of localized basis functions.");
+     270             : 
+     271          91 : }
+     272             : 
+     273             : 
+     274          91 : void VesBias::useInitialCoeffsKeywords(Keywords& keys) {
+     275          91 :   keys.use("COEFFS");
+     276          91 : }
+     277             : 
+     278             : 
+     279          91 : void VesBias::useTargetDistributionKeywords(Keywords& keys) {
+     280         182 :   plumed_massert(!keys.exists("TARGET_DISTRIBUTIONS"),"you cannot use both useTargetDistributionKeywords and useMultipleTargetDistributionKeywords");
+     281          91 :   keys.use("TARGET_DISTRIBUTION");
+     282          91 : }
+     283             : 
+     284             : 
+     285           0 : void VesBias::useMultipleTargetDistributionKeywords(Keywords& keys) {
+     286           0 :   plumed_massert(!keys.exists("TARGET_DISTRIBUTION"),"you cannot use both useTargetDistributionKeywords and useMultipleTargetDistributionKeywords");
+     287           0 :   keys.use("TARGET_DISTRIBUTIONS");
+     288           0 : }
+     289             : 
+     290             : 
+     291          91 : void VesBias::useGridBinKeywords(Keywords& keys) {
+     292          91 :   keys.use("GRID_BINS");
+     293          91 : }
+     294             : 
+     295             : 
+     296           0 : void VesBias::useGridLimitsKeywords(Keywords& keys) {
+     297           0 :   keys.use("GRID_MIN");
+     298           0 :   keys.use("GRID_MAX");
+     299           0 : }
+     300             : 
+     301             : 
+     302          91 : void VesBias::useBiasCutoffKeywords(Keywords& keys) {
+     303          91 :   keys.use("BIAS_CUTOFF");
+     304          91 :   keys.use("BIAS_CUTOFF_FERMI_LAMBDA");
+     305          91 : }
+     306             : 
+     307             : 
+     308          91 : void VesBias::useProjectionArgKeywords(Keywords& keys) {
+     309          91 :   keys.use("PROJ_ARG");
+     310          91 : }
+     311             : 
+     312             : 
+     313           0 : void VesBias::useReweightFactorKeywords(Keywords& keys) {
+     314           0 :   keys.use("CALC_REWEIGHT_FACTOR");
+     315           0 :   keys.addOutputComponent("rct","CALC_REWEIGHT_FACTOR","the reweight factor c(t).");
+     316           0 : }
+     317             : 
+     318             : 
+     319           0 : void VesBias::addCoeffsSet(const std::vector<std::string>& dimension_labels,const std::vector<unsigned int>& indices_shape) {
+     320           0 :   auto coeffs_pntr_tmp = Tools::make_unique<CoeffsVector>("coeffs",dimension_labels,indices_shape,comm,true);
+     321           0 :   initializeCoeffs(std::move(coeffs_pntr_tmp));
+     322           0 : }
+     323             : 
+     324             : 
+     325          90 : void VesBias::addCoeffsSet(std::vector<Value*>& args,std::vector<BasisFunctions*>& basisf) {
+     326          90 :   auto coeffs_pntr_tmp = Tools::make_unique<CoeffsVector>("coeffs",args,basisf,comm,true);
+     327          90 :   initializeCoeffs(std::move(coeffs_pntr_tmp));
+     328          90 : }
+     329             : 
+     330             : 
+     331           0 : void VesBias::addCoeffsSet(std::unique_ptr<CoeffsVector> coeffs_pntr_in) {
+     332           0 :   initializeCoeffs(std::move(coeffs_pntr_in));
+     333           0 : }
+     334             : 
+     335             : 
+     336          90 : void VesBias::initializeCoeffs(std::unique_ptr<CoeffsVector> coeffs_pntr_in) {
+     337             :   //
+     338          90 :   coeffs_pntr_in->linkVesBias(this);
+     339             :   //
+     340             :   std::string label;
+     341          90 :   if(!use_multiple_coeffssets_ && ncoeffssets_==1) {
+     342           0 :     plumed_merror("you are not allowed to use multiple coefficient sets");
+     343             :   }
+     344             :   //
+     345         180 :   label = getCoeffsSetLabelString("coeffs",ncoeffssets_);
+     346          90 :   coeffs_pntr_in->setLabels(label);
+     347             : 
+     348          90 :   coeffs_pntrs_.emplace_back(std::move(coeffs_pntr_in));
+     349          90 :   auto aver_ps_tmp = Tools::make_unique<CoeffsVector>(*coeffs_pntrs_.back());
+     350         270 :   label = getCoeffsSetLabelString("targetdist_averages",ncoeffssets_);
+     351          90 :   aver_ps_tmp->setLabels(label);
+     352          90 :   aver_ps_tmp->setValues(0.0);
+     353          90 :   targetdist_averages_pntrs_.emplace_back(std::move(aver_ps_tmp));
+     354             :   //
+     355          90 :   auto gradient_tmp = Tools::make_unique<CoeffsVector>(*coeffs_pntrs_.back());
+     356         180 :   label = getCoeffsSetLabelString("gradient",ncoeffssets_);
+     357          90 :   gradient_tmp->setLabels(label);
+     358          90 :   gradient_pntrs_.emplace_back(std::move(gradient_tmp));
+     359             :   //
+     360         180 :   label = getCoeffsSetLabelString("hessian",ncoeffssets_);
+     361          90 :   auto hessian_tmp = Tools::make_unique<CoeffsMatrix>(label,coeffs_pntrs_.back().get(),comm,diagonal_hessian_);
+     362             : 
+     363          90 :   hessian_pntrs_.emplace_back(std::move(hessian_tmp));
+     364             :   //
+     365             :   std::vector<double> aver_sampled_tmp;
+     366          90 :   aver_sampled_tmp.assign(coeffs_pntrs_.back()->numberOfCoeffs(),0.0);
+     367          90 :   sampled_averages.push_back(aver_sampled_tmp);
+     368             :   //
+     369             :   std::vector<double> cross_aver_sampled_tmp;
+     370          90 :   cross_aver_sampled_tmp.assign(hessian_pntrs_.back()->getSize(),0.0);
+     371          90 :   sampled_cross_averages.push_back(cross_aver_sampled_tmp);
+     372             :   //
+     373          90 :   aver_counters.push_back(0);
+     374             :   //
+     375          90 :   ncoeffssets_++;
+     376         180 : }
+     377             : 
+     378             : 
+     379          90 : bool VesBias::readCoeffsFromFiles() {
+     380          90 :   plumed_assert(ncoeffssets_>0);
+     381         180 :   plumed_massert(keywords.exists("COEFFS"),"you are not allowed to use this function as the COEFFS keyword is not enabled");
+     382             :   bool read_coeffs = false;
+     383          90 :   if(coeffs_fnames.size()>0) {
+     384           4 :     plumed_massert(coeffs_fnames.size()==ncoeffssets_,"COEFFS keyword is of the wrong size");
+     385           4 :     if(ncoeffssets_==1) {
+     386           4 :       log.printf("  Read in coefficients from file ");
+     387             :     }
+     388             :     else {
+     389           0 :       log.printf("  Read in coefficients from files:\n");
+     390             :     }
+     391           8 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     392           4 :       IFile ifile;
+     393           4 :       ifile.link(*this);
+     394           4 :       ifile.open(coeffs_fnames[i]);
+     395           8 :       if(!ifile.FieldExist(coeffs_pntrs_[i]->getDataLabel())) {
+     396           0 :         std::string error_msg = "Problem with reading coefficients from file " + ifile.getPath() + ": no field with name " + coeffs_pntrs_[i]->getDataLabel() + "\n";
+     397           0 :         plumed_merror(error_msg);
+     398             :       }
+     399           4 :       size_t ncoeffs_read = coeffs_pntrs_[i]->readFromFile(ifile,false,false);
+     400           4 :       coeffs_pntrs_[i]->setIterationCounterAndTime(0,getTime());
+     401           4 :       if(ncoeffssets_==1) {
+     402           8 :         log.printf("%s (read %zu of %zu values)\n", ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+     403             :       }
+     404             :       else {
+     405           0 :         log.printf("   coefficient %u: %s (read %zu of %zu values)\n",i,ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+     406             :       }
+     407           4 :       ifile.close();
+     408           4 :     }
+     409             :     read_coeffs = true;
+     410             :   }
+     411          90 :   return read_coeffs;
+     412             : }
+     413             : 
+     414             : 
+     415       22810 : void VesBias::updateGradientAndHessian(const bool use_mwalkers_mpi) {
+     416       45620 :   for(unsigned int k=0; k<ncoeffssets_; k++) {
+     417             :     //
+     418       22810 :     comm.Sum(sampled_averages[k]);
+     419       22810 :     comm.Sum(sampled_cross_averages[k]);
+     420       22810 :     if(use_mwalkers_mpi) {
+     421             :       double walker_weight=1.0;
+     422         120 :       if(aver_counters[k]==0) {walker_weight=0.0;}
+     423         120 :       multiSimSumAverages(k,walker_weight);
+     424             :     }
+     425             :     // NOTE: this assumes that all walkers have the same TargetDist, might change later on!!
+     426       22810 :     Gradient(k).setValues( TargetDistAverages(k) - sampled_averages[k] );
+     427       22810 :     Hessian(k) = computeCovarianceFromAverages(k);
+     428       22810 :     Hessian(k) *= getBeta();
+     429             : 
+     430       22810 :     if(optimization_threshold_ != 0.0) {
+     431         390 :       for(size_t c_id=0; c_id < sampled_averages[k].size(); ++c_id) {
+     432         380 :         if(fabs(sampled_averages[k][c_id]) < optimization_threshold_) {
+     433         219 :           Gradient(k).setValue(c_id, 0.0);
+     434         219 :           Hessian(k).setValue(c_id, c_id, 0.0);
+     435             :         }
+     436             :       }
+     437             :     }
+     438             :     //
+     439             :     Gradient(k).activate();
+     440             :     Hessian(k).activate();
+     441             :     //
+     442             :     // Check the total number of samples (from all walkers) and deactivate the Gradient and Hessian if it
+     443             :     // is zero
+     444       22810 :     unsigned int total_samples = aver_counters[k];
+     445       22810 :     if(use_mwalkers_mpi) {
+     446         120 :       if(comm.Get_rank()==0) {multi_sim_comm.Sum(total_samples);}
+     447         120 :       comm.Bcast(total_samples,0);
+     448             :     }
+     449       22810 :     if(total_samples==0) {
+     450             :       Gradient(k).deactivate();
+     451          95 :       Gradient(k).clear();
+     452             :       Hessian(k).deactivate();
+     453          95 :       Hessian(k).clear();
+     454             :     }
+     455             :     //
+     456             :     std::fill(sampled_averages[k].begin(), sampled_averages[k].end(), 0.0);
+     457             :     std::fill(sampled_cross_averages[k].begin(), sampled_cross_averages[k].end(), 0.0);
+     458       22810 :     aver_counters[k]=0;
+     459             :   }
+     460       22810 : }
+     461             : 
+     462             : 
+     463         120 : void VesBias::multiSimSumAverages(const unsigned int c_id, const double walker_weight) {
+     464         120 :   plumed_massert(walker_weight>=0.0,"the weight of the walker cannot be negative!");
+     465         120 :   if(walker_weight!=1.0) {
+     466        7860 :     for(size_t i=0; i<sampled_averages[c_id].size(); i++) {
+     467        7800 :       sampled_averages[c_id][i] *= walker_weight;
+     468             :     }
+     469        7860 :     for(size_t i=0; i<sampled_cross_averages[c_id].size(); i++) {
+     470        7800 :       sampled_cross_averages[c_id][i] *= walker_weight;
+     471             :     }
+     472             :   }
+     473             :   //
+     474         120 :   if(comm.Get_rank()==0) {
+     475         120 :     multi_sim_comm.Sum(sampled_averages[c_id]);
+     476         120 :     multi_sim_comm.Sum(sampled_cross_averages[c_id]);
+     477         120 :     double norm_weights = walker_weight;
+     478         120 :     multi_sim_comm.Sum(norm_weights);
+     479         120 :     if(norm_weights>0.0) {norm_weights=1.0/norm_weights;}
+     480        8580 :     for(size_t i=0; i<sampled_averages[c_id].size(); i++) {
+     481        8460 :       sampled_averages[c_id][i] *= norm_weights;
+     482             :     }
+     483        8580 :     for(size_t i=0; i<sampled_cross_averages[c_id].size(); i++) {
+     484        8460 :       sampled_cross_averages[c_id][i] *= norm_weights;
+     485             :     }
+     486             :   }
+     487         120 :   comm.Bcast(sampled_averages[c_id],0);
+     488         120 :   comm.Bcast(sampled_cross_averages[c_id],0);
+     489         120 : }
+     490             : 
+     491             : 
+     492       23556 : void VesBias::addToSampledAverages(const std::vector<double>& values, const unsigned int c_id) {
+     493             :   /*
+     494             :   use the following online equation to calculate the average and covariance
+     495             :   (see https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Covariance)
+     496             :       xm[n+1] = xm[n] + (x[n+1]-xm[n])/(n+1)
+     497             :   */
+     498       23556 :   double counter_dbl = static_cast<double>(aver_counters[c_id]);
+     499             :   size_t ncoeffs = numberOfCoeffs(c_id);
+     500       23556 :   std::vector<double> deltas(ncoeffs,0.0);
+     501       23556 :   size_t stride = comm.Get_size();
+     502       23556 :   size_t rank = comm.Get_rank();
+     503             :   // update average and diagonal part of Hessian
+     504     1830228 :   for(size_t i=rank; i<ncoeffs; i+=stride) {
+     505             :     size_t midx = getHessianIndex(i,i,c_id);
+     506     1806672 :     deltas[i] = (values[i]-sampled_averages[c_id][i])/(counter_dbl+1); // (x[n+1]-xm[n])/(n+1)
+     507     1806672 :     sampled_averages[c_id][i] += deltas[i];
+     508     1806672 :     sampled_cross_averages[c_id][midx] += (values[i]*values[i]-sampled_cross_averages[c_id][midx])/(counter_dbl+1);
+     509             :   }
+     510       23556 :   comm.Sum(deltas);
+     511             :   // update off-diagonal part of the Hessian
+     512       23556 :   if(!diagonal_hessian_) {
+     513           0 :     for(size_t i=rank; i<ncoeffs; i+=stride) {
+     514           0 :       for(size_t j=(i+1); j<ncoeffs; j++) {
+     515             :         size_t midx = getHessianIndex(i,j,c_id);
+     516           0 :         sampled_cross_averages[c_id][midx] += (values[i]*values[j]-sampled_cross_averages[c_id][midx])/(counter_dbl+1);
+     517             :       }
+     518             :     }
+     519             :   }
+     520             :   // NOTE: the MPI sum for sampled_averages and sampled_cross_averages is done later
+     521       23556 :   aver_counters[c_id] += 1;
+     522       23556 : }
+     523             : 
+     524             : 
+     525           0 : void VesBias::setTargetDistAverages(const std::vector<double>& coeffderivs_aver_ps, const unsigned int coeffs_id) {
+     526           0 :   TargetDistAverages(coeffs_id) = coeffderivs_aver_ps;
+     527           0 :   TargetDistAverages(coeffs_id).setIterationCounterAndTime(this->getIterationCounter(),this->getTime());
+     528           0 : }
+     529             : 
+     530             : 
+     531         453 : void VesBias::setTargetDistAverages(const CoeffsVector& coeffderivs_aver_ps, const unsigned int coeffs_id) {
+     532         453 :   TargetDistAverages(coeffs_id).setValues( coeffderivs_aver_ps );
+     533         453 :   TargetDistAverages(coeffs_id).setIterationCounterAndTime(this->getIterationCounter(),this->getTime());
+     534         453 : }
+     535             : 
+     536             : 
+     537           0 : void VesBias::setTargetDistAveragesToZero(const unsigned int coeffs_id) {
+     538           0 :   TargetDistAverages(coeffs_id).setAllValuesToZero();
+     539           0 :   TargetDistAverages(coeffs_id).setIterationCounterAndTime(this->getIterationCounter(),this->getTime());
+     540           0 : }
+     541             : 
+     542             : 
+     543         175 : void VesBias::checkThatTemperatureIsGiven() {
+     544         175 :   if(kbt_==0.0) {
+     545           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.";
+     546           0 :     plumed_merror(err_msg);
+     547             :   }
+     548         175 : }
+     549             : 
+     550             : 
+     551        1005 : unsigned int VesBias::getIterationCounter() const {
+     552             :   unsigned int iteration = 0;
+     553        1005 :   if(optimizeCoeffs()) {
+     554             :     iteration = getOptimizerPntr()->getIterationCounter();
+     555             :   }
+     556             :   else {
+     557         226 :     iteration = getCoeffsPntrs()[0]->getIterationCounter();
+     558             :   }
+     559        1005 :   return iteration;
+     560             : }
+     561             : 
+     562             : 
+     563          85 : void VesBias::linkOptimizer(Optimizer* optimizer_pntr_in) {
+     564             :   //
+     565          85 :   if(optimizer_pntr_==NULL) {
+     566          85 :     optimizer_pntr_ = optimizer_pntr_in;
+     567             :   }
+     568             :   else {
+     569           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.";
+     570           0 :     plumed_merror(err_msg);
+     571             :   }
+     572          85 :   checkThatTemperatureIsGiven();
+     573          85 :   optimize_coeffs_ = true;
+     574          85 :   filenames_have_iteration_number_ = true;
+     575          85 : }
+     576             : 
+     577             : 
+     578          82 : void VesBias::enableHessian(const bool diagonal_hessian) {
+     579          82 :   compute_hessian_=true;
+     580          82 :   diagonal_hessian_=diagonal_hessian;
+     581          82 :   sampled_cross_averages.clear();
+     582         164 :   for (unsigned int i=0; i<ncoeffssets_; i++) {
+     583          82 :     std::string label = getCoeffsSetLabelString("hessian",i);
+     584         164 :     hessian_pntrs_[i] = Tools::make_unique<CoeffsMatrix>(label,coeffs_pntrs_[i].get(),comm,diagonal_hessian_);
+     585             :     //
+     586             :     std::vector<double> cross_aver_sampled_tmp;
+     587          82 :     cross_aver_sampled_tmp.assign(hessian_pntrs_[i]->getSize(),0.0);
+     588          82 :     sampled_cross_averages.push_back(cross_aver_sampled_tmp);
+     589             :   }
+     590          82 : }
+     591             : 
+     592             : 
+     593           0 : void VesBias::disableHessian() {
+     594           0 :   compute_hessian_=false;
+     595           0 :   diagonal_hessian_=true;
+     596           0 :   sampled_cross_averages.clear();
+     597           0 :   for (unsigned int i=0; i<ncoeffssets_; i++) {
+     598           0 :     std::string label = getCoeffsSetLabelString("hessian",i);
+     599           0 :     hessian_pntrs_[i] = Tools::make_unique<CoeffsMatrix>(label,coeffs_pntrs_[i].get(),comm,diagonal_hessian_);
+     600             :     //
+     601             :     std::vector<double> cross_aver_sampled_tmp;
+     602           0 :     cross_aver_sampled_tmp.assign(hessian_pntrs_[i]->getSize(),0.0);
+     603           0 :     sampled_cross_averages.push_back(cross_aver_sampled_tmp);
+     604             :   }
+     605           0 : }
+     606             : 
+     607             : 
+     608         442 : std::string VesBias::getCoeffsSetLabelString(const std::string& type, const unsigned int coeffs_id) const {
+     609         442 :   std::string label_prefix = getLabel() + ".";
+     610         442 :   std::string label_postfix = "";
+     611         442 :   if(use_multiple_coeffssets_) {
+     612           0 :     Tools::convert(coeffs_id,label_postfix);
+     613           0 :     label_postfix = "-" + label_postfix;
+     614             :   }
+     615        1326 :   return label_prefix+type+label_postfix;
+     616             : }
+     617             : 
+     618             : 
+     619         567 : std::unique_ptr<OFile> VesBias::getOFile(const std::string& filepath, const bool multi_sim_single_file, const bool enforce_backup) {
+     620         567 :   auto ofile_pntr = Tools::make_unique<OFile>();
+     621         567 :   std::string fp = filepath;
+     622         567 :   ofile_pntr->link(*static_cast<Action*>(this));
+     623         567 :   if(enforce_backup) {ofile_pntr->enforceBackup();}
+     624         567 :   if(multi_sim_single_file) {
+     625          56 :     unsigned int r=0;
+     626          56 :     if(comm.Get_rank()==0) {r=multi_sim_comm.Get_rank();}
+     627          56 :     comm.Bcast(r,0);
+     628          56 :     if(r>0) {fp="/dev/null";}
+     629         112 :     ofile_pntr->enforceSuffix("");
+     630             :   }
+     631         567 :   ofile_pntr->open(fp);
+     632         567 :   return ofile_pntr;
+     633           0 : }
+     634             : 
+     635             : 
+     636           0 : void VesBias::setGridBins(const std::vector<unsigned int>& grid_bins_in) {
+     637           0 :   plumed_massert(grid_bins_in.size()==getNumberOfArguments(),"the number of grid bins given doesn't match the number of arguments");
+     638           0 :   grid_bins_=grid_bins_in;
+     639           0 : }
+     640             : 
+     641             : 
+     642           0 : void VesBias::setGridBins(const unsigned int nbins) {
+     643           0 :   std::vector<unsigned int> grid_bins_in(getNumberOfArguments(),nbins);
+     644           0 :   grid_bins_=grid_bins_in;
+     645           0 : }
+     646             : 
+     647             : 
+     648           0 : void VesBias::setGridMin(const std::vector<double>& grid_min_in) {
+     649           0 :   plumed_massert(grid_min_in.size()==getNumberOfArguments(),"the number of lower bounds given for the grid doesn't match the number of arguments");
+     650           0 :   grid_min_=grid_min_in;
+     651           0 : }
+     652             : 
+     653             : 
+     654           0 : void VesBias::setGridMax(const std::vector<double>& grid_max_in) {
+     655           0 :   plumed_massert(grid_max_in.size()==getNumberOfArguments(),"the number of upper bounds given for the grid doesn't match the number of arguments");
+     656           0 :   grid_max_=grid_max_in;
+     657           0 : }
+     658             : 
+     659             : 
+     660         383 : std::string VesBias::getCurrentOutputFilename(const std::string& base_filename, const std::string& suffix) const {
+     661         383 :   std::string filename = base_filename;
+     662         383 :   if(suffix.size()>0) {
+     663          82 :     filename = FileBase::appendSuffix(filename,"."+suffix);
+     664             :   }
+     665         383 :   if(filenamesIncludeIterationNumber()) {
+     666         756 :     filename = FileBase::appendSuffix(filename,"."+getIterationFilenameSuffix());
+     667             :   }
+     668         383 :   return filename;
+     669             : }
+     670             : 
+     671             : 
+     672         192 : std::string VesBias::getCurrentTargetDistOutputFilename(const std::string& suffix) const {
+     673         192 :   std::string filename = targetdist_filename_;
+     674         192 :   if(suffix.size()>0) {
+     675         204 :     filename = FileBase::appendSuffix(filename,"."+suffix);
+     676             :   }
+     677         192 :   if(filenamesIncludeIterationNumber() && dynamicTargetDistribution()) {
+     678         348 :     filename = FileBase::appendSuffix(filename,"."+getIterationFilenameSuffix());
+     679             :   }
+     680         192 :   return filename;
+     681             : }
+     682             : 
+     683             : 
+     684         552 : std::string VesBias::getIterationFilenameSuffix() const {
+     685             :   std::string iter_str;
+     686         552 :   Tools::convert(getIterationCounter(),iter_str);
+     687         552 :   iter_str = "iter-" + iter_str;
+     688         552 :   return iter_str;
+     689             : }
+     690             : 
+     691             : 
+     692           0 : std::string VesBias::getCoeffsSetFilenameSuffix(const unsigned int coeffs_id) const {
+     693           0 :   std::string suffix = "";
+     694           0 :   if(use_multiple_coeffssets_) {
+     695           0 :     Tools::convert(coeffs_id,suffix);
+     696           0 :     suffix = coeffs_id_prefix_ + suffix;
+     697             :   }
+     698           0 :   return suffix;
+     699             : }
+     700             : 
+     701             : 
+     702           3 : void VesBias::setupBiasCutoff(const double bias_cutoff_value, const double fermi_lambda) {
+     703             :   //
+     704             :   double fermi_exp_max = 100.0;
+     705             :   //
+     706             :   std::string str_bias_cutoff_value; VesTools::convertDbl2Str(bias_cutoff_value,str_bias_cutoff_value);
+     707             :   std::string str_fermi_lambda; VesTools::convertDbl2Str(fermi_lambda,str_fermi_lambda);
+     708             :   std::string str_fermi_exp_max; VesTools::convertDbl2Str(fermi_exp_max,str_fermi_exp_max);
+     709           6 :   std::string swfunc_keywords = "FERMI R_0=" + str_bias_cutoff_value + " FERMI_LAMBDA=" + str_fermi_lambda + " FERMI_EXP_MAX=" + str_fermi_exp_max;
+     710             :   //
+     711           3 :   std::string swfunc_errors="";
+     712           6 :   bias_cutoff_swfunc_pntr_ = Tools::make_unique<FermiSwitchingFunction>();
+     713           3 :   bias_cutoff_swfunc_pntr_->set(swfunc_keywords,swfunc_errors);
+     714           3 :   if(swfunc_errors.size()>0) {
+     715           0 :     plumed_merror("problem with setting up Fermi switching function: " + swfunc_errors);
+     716             :   }
+     717             :   //
+     718           3 :   bias_cutoff_value_=bias_cutoff_value;
+     719           3 :   bias_cutoff_active_=true;
+     720             :   enableDynamicTargetDistribution();
+     721           3 : }
+     722             : 
+     723             : 
+     724        3263 : double VesBias::getBiasCutoffSwitchingFunction(const double bias, double& deriv_factor) const {
+     725        3263 :   plumed_massert(bias_cutoff_active_,"The bias cutoff is not active so you cannot call this function");
+     726        3263 :   double arg = -(bias-bias_current_max_value);
+     727        3263 :   double deriv=0.0;
+     728        3263 :   double value = bias_cutoff_swfunc_pntr_->calculate(arg,deriv);
+     729             :   // as FermiSwitchingFunction class has different behavior from normal SwitchingFunction class
+     730             :   // I was having problems with NaN as it was dividing with zero
+     731             :   // deriv *= arg;
+     732        3263 :   deriv_factor = value-bias*deriv;
+     733        3263 :   return value;
+     734             : }
+     735             : 
+     736             : 
+     737         567 : bool VesBias::useMultipleWalkers() const {
+     738             :   bool use_mwalkers_mpi=false;
+     739         567 :   if(optimizeCoeffs() && getOptimizerPntr()->useMultipleWalkers()) {
+     740             :     use_mwalkers_mpi=true;
+     741             :   }
+     742         567 :   return use_mwalkers_mpi;
+     743             : }
+     744             : 
+     745             : 
+     746           0 : void VesBias::updateReweightFactor() {
+     747           0 :   if(calc_reweightfactor_) {
+     748           0 :     double value = calculateReweightFactor();
+     749           0 :     getPntrToComponent("rct")->set(value);
+     750             :   }
+     751           0 : }
+     752             : 
+     753             : 
+     754           0 : double VesBias::calculateReweightFactor() const {
+     755           0 :   plumed_merror(getName()+" with label "+getLabel()+": calculation of the reweight factor c(t) has not been implemented for this type of VES bias");
+     756             :   return 0.0;
+     757             : }
+     758             : 
+     759             : 
+     760             : }
+     761             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..99f67c60ff --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/VesBias.h.func.html b/coverage/ves/VesBias.h.func.html new file mode 100644 index 0000000000..4fd171d660 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/VesBias.h.gcov.html b/coverage/ves/VesBias.h.gcov.html new file mode 100644 index 0000000000..14445d1965 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..b3db08e1b7 --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + 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:34635697.2 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9VesDeltaFC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe1786createERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaFC1ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaF16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves9VesDeltaF12update_alphaEv16
_ZN4PLMD3ves9VesDeltaF17update_tg_and_rctEv16
_ZN4PLMD3ves9VesDeltaF6updateEv804
_ZN4PLMD3ves9VesDeltaF9calculateEv804
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe178C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe178D2Ev3473
_ZNK4PLMD3ves9VesDeltaF9get_indexEjj4632
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.func.html b/coverage/ves/VesDeltaF.cpp.func.html new file mode 100644 index 0000000000..09d67b2baa --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + 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:34635697.2 %
Date:2024-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe1786createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe178C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe178D2Ev3473
_ZN4PLMD3ves9VesDeltaF12update_alphaEv16
_ZN4PLMD3ves9VesDeltaF16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves9VesDeltaF17update_tg_and_rctEv16
_ZN4PLMD3ves9VesDeltaF6updateEv804
_ZN4PLMD3ves9VesDeltaF9calculateEv804
_ZN4PLMD3ves9VesDeltaFC1ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaFC2ERKNS_13ActionOptionsE0
_ZNK4PLMD3ves9VesDeltaF9get_indexEjj4632
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.gcov.html b/coverage/ves/VesDeltaF.cpp.gcov.html new file mode 100644 index 0000000000..d4a766ed1a --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.gcov.html @@ -0,0 +1,796 @@ + + + + + + + + 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:34635697.2 %
Date:2024-06-10 08:19:14Functions:101190.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 "bias/Bias.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/Atoms.h"
+      27             : #include "tools/Communicator.h"
+      28             : #include "tools/Grid.h"
+      29             : #include "tools/File.h"
+      30             : //#include <algorithm> //std::fill
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : //+PLUMEDOC VES_BIAS VES_DELTA_F
+      36             : /*
+      37             : Implementation of VES\f$\Delta F\f$ method \cite Invernizzi2019vesdeltaf (step two only).
+      38             : 
+      39             : \warning
+      40             :   Notice that this is a stand-alone bias Action, it does not need any of the other VES module components
+      41             : 
+      42             : First you should create some estimate of the local free energy basins of your system,
+      43             : using e.g. multiple \ref METAD short runs, and combining them with the \ref sum_hills utility.
+      44             : Once you have them, you can use this bias Action to perform the VES optimization part of the method.
+      45             : 
+      46             : These \f$N+1\f$ local basins are used to model the global free energy.
+      47             : In particular, given the conditional probabilities \f$P(\mathbf{s}|i)\propto e^{-\beta F_i(\mathbf{s})}\f$
+      48             : and the probabilities of being in a given basin \f$P_i\f$, we can write:
+      49             : \f[
+      50             :   e^{-\beta F(\mathbf{s})}\propto P(\mathbf{s})=\sum_{i=0}^N P(\mathbf{s}|i)P_i \, .
+      51             : \f]
+      52             : We use this free energy model and the chosen bias factor \f$\gamma\f$ to build the bias potential:
+      53             : \f$V(\mathbf{s})=-(1-1/\gamma)F(\mathbf{s})\f$.
+      54             : Or, more explicitly:
+      55             : \f[
+      56             :   V(\mathbf{s})=(1-1/\gamma)\frac{1}{\beta}\log\left[e^{-\beta F_0(\mathbf{s})}
+      57             :   +\sum_{i=1}^{N} e^{-\beta F_i(\mathbf{s})} e^{-\beta \alpha_i}\right] \, ,
+      58             : \f]
+      59             : where the parameters \f$\boldsymbol{\alpha}\f$ are the \f$N\f$ free energy differences (see below) from the \f$F_0\f$ basin.
+      60             : 
+      61             : 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$.
+      62             : In this case the optimization parameters \f$\alpha_i\f$ are the difference in height between the minima of the basins.
+      63             : Using the keyword `NORMALIZE`, you can also decide to normalize the local free energies so that
+      64             : \f$\int d\mathbf{s}\, e^{-\beta F_i(\mathbf{s})}=1\f$.
+      65             : In this case the parameters will represent not the difference in height (which depends on the chosen CVs),
+      66             : but the actual free energy difference, \f$\alpha_i=\Delta F_i\f$.
+      67             : 
+      68             : However, as discussed in Ref. \cite Invernizzi2019vesdeltaf, a better estimate of \f$\Delta F_i\f$ should be obtained through the reweighting procedure.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : The following performs the optimization of the free energy difference between two metastable basins:
+      73             : 
+      74             : \plumedfile
+      75             : cv: DISTANCE ATOMS=1,2
+      76             : ves: VES_DELTA_F ...
+      77             :   ARG=cv
+      78             :   TEMP=300
+      79             :   FILE_F0=fesA.data
+      80             :   FILE_F1=fesB.data
+      81             :   BIASFACTOR=10.0
+      82             :   M_STEP=0.1
+      83             :   AV_STRIDE=500
+      84             :   PRINT_STRIDE=100
+      85             : ...
+      86             : PRINT FMT=%g STRIDE=500 FILE=Colvar.data ARG=cv,ves.bias,ves.rct
+      87             : \endplumedfile
+      88             : 
+      89             : The local FES files can be obtained as described in Sec. 4.2 of Ref. \cite Invernizzi2019vesdeltaf, i.e. for example:
+      90             : - 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)
+      91             : - \verbatim cat HILLS* > all_HILLS \endverbatim
+      92             : - \verbatim plumed sum_hills --hills all_HILLS --outfile all_fesA.dat --mintozero --min 0 --max 1 --bin 100 \endverbatim
+      93             : - \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
+      94             : 
+      95             : The header of both FES files must be identical, and should be similar to the following:
+      96             : 
+      97             : \auxfile{fesA.data}
+      98             : #! FIELDS cv file.free der_cv
+      99             : #! SET min_cv 0
+     100             : #! SET max_cv 1
+     101             : #! SET nbins_cv  100
+     102             : #! SET periodic_cv false
+     103             : 0 0 0
+     104             : \endauxfile
+     105             : \auxfile{fesB.data}
+     106             : #! FIELDS cv file.free der_cv
+     107             : #! SET min_cv 0
+     108             : #! SET max_cv 1
+     109             : #! SET nbins_cv  100
+     110             : #! SET periodic_cv false
+     111             : 0 0 0
+     112             : \endauxfile
+     113             : 
+     114             : */
+     115             : //+ENDPLUMEDOC
+     116             : 
+     117             : class VesDeltaF : public bias::Bias {
+     118             : 
+     119             : private:
+     120             :   double beta_;
+     121             :   unsigned NumParallel_;
+     122             :   unsigned rank_;
+     123             :   unsigned NumWalkers_;
+     124             :   bool isFirstStep_;
+     125             :   bool afterCalculate_;
+     126             : 
+     127             : //prob
+     128             :   double tot_prob_;
+     129             :   std::vector<double> prob_;
+     130             :   std::vector< std::vector<double> > der_prob_;
+     131             : 
+     132             : //local basins
+     133             :   std::vector< std::unique_ptr<Grid> > grid_p_; //pointers because of GridBase::create
+     134             :   std::vector<double> norm_;
+     135             : 
+     136             : //optimizer-related stuff
+     137             :   long unsigned mean_counter_;
+     138             :   unsigned mean_weight_tau_;
+     139             :   unsigned alpha_size_;
+     140             :   unsigned sym_alpha_size_;
+     141             :   std::vector<double> mean_alpha_;
+     142             :   std::vector<double> inst_alpha_;
+     143             :   std::vector<double> past_increment2_;
+     144             :   double minimization_step_;
+     145             :   bool damping_off_;
+     146             : //'tg' -> 'target distribution'
+     147             :   double inv_gamma_;
+     148             :   unsigned tg_counter_;
+     149             :   unsigned tg_stride_;
+     150             :   std::vector<double> tg_dV_dAlpha_;
+     151             :   std::vector<double> tg_d2V_dAlpha2_;
+     152             : //'av' -> 'ensemble average'
+     153             :   unsigned av_counter_;
+     154             :   unsigned av_stride_;
+     155             :   std::vector<double> av_dV_dAlpha_;
+     156             :   std::vector<double> av_dV_dAlpha_prod_;
+     157             :   std::vector<double> av_d2V_dAlpha2_;
+     158             : //printing
+     159             :   unsigned print_stride_;
+     160             :   OFile alphaOfile_;
+     161             : //other
+     162             :   std::vector<double> exp_alpha_;
+     163             :   std::vector<double> prev_exp_alpha_;
+     164             :   double work_;
+     165             : 
+     166             : //functions
+     167             :   void update_alpha();
+     168             :   void update_tg_and_rct();
+     169             :   inline unsigned get_index(const unsigned, const unsigned) const;
+     170             : 
+     171             : public:
+     172             :   explicit VesDeltaF(const ActionOptions&);
+     173             :   void calculate() override;
+     174             :   void update() override;
+     175             :   static void registerKeywords(Keywords& keys);
+     176             : };
+     177             : 
+     178       10427 : PLUMED_REGISTER_ACTION(VesDeltaF,"VES_DELTA_F")
+     179             : 
+     180           5 : void VesDeltaF::registerKeywords(Keywords& keys) {
+     181           5 :   Bias::registerKeywords(keys);
+     182           5 :   keys.use("ARG");
+     183          10 :   keys.add("optional","TEMP","temperature is compulsory, but it can be sometimes fetched from the MD engine");
+     184             : //local free energies
+     185          10 :   keys.add("numbered","FILE_F","names of files containing local free energies and derivatives. "
+     186             :            "The first one, FILE_F0, is used as reference for all the free energy differences.");
+     187          10 :   keys.reset_style("FILE_F","compulsory");
+     188          10 :   keys.addFlag("NORMALIZE",false,"normalize all local free energies so that alpha will be (approx) \\f$\\Delta F\\f$");
+     189          10 :   keys.addFlag("NO_MINTOZERO",false,"leave local free energies as provided, without shifting them to zero min");
+     190             : //target distribution
+     191          10 :   keys.add("compulsory","BIASFACTOR","0","the \\f$\\gamma\\f$ bias factor used for well-tempered target \\f$p(\\mathbf{s})\\f$."
+     192             :            " Set to 0 for non-tempered flat target");
+     193          10 :   keys.add("optional","TG_STRIDE","( default=1 ) number of AV_STRIDE between updates"
+     194             :            " of target \\f$p(\\mathbf{s})\\f$ and reweighing factor \\f$c(t)\\f$");
+     195             : //optimization
+     196          10 :   keys.add("compulsory","M_STEP","1.0","the \\f$\\mu\\f$ step used for the \\f$\\Omega\\f$ functional minimization");
+     197          10 :   keys.add("compulsory","AV_STRIDE","500","number of simulation steps between alpha updates");
+     198          10 :   keys.add("optional","TAU_MEAN","exponentially decaying average for alpha (rescaled using AV_STRIDE)."
+     199             :            " Should be used only in very specific cases");
+     200          10 :   keys.add("optional","INITIAL_ALPHA","( default=0 ) an initial guess for the bias potential parameter alpha");
+     201          10 :   keys.addFlag("DAMPING_OFF",false,"do not use an AdaGrad-like term to rescale M_STEP");
+     202             : //output parameters file
+     203          10 :   keys.add("compulsory","ALPHA_FILE","ALPHA","file name for output minimization parameters");
+     204          10 :   keys.add("optional","PRINT_STRIDE","( default=10 ) stride for printing to ALPHA_FILE");
+     205          10 :   keys.add("optional","FMT","specify format for ALPHA_FILE");
+     206             : //debug flags
+     207          10 :   keys.addFlag("SERIAL",false,"perform the calculation in serial even if multiple tasks are available");
+     208          10 :   keys.addFlag("MULTIPLE_WALKERS",false,"use multiple walkers connected via MPI for the optimization");
+     209           5 :   keys.use("RESTART");
+     210             : 
+     211             : //output components
+     212           5 :   componentsAreNotOptional(keys);
+     213          10 :   keys.addOutputComponent("rct","default","the reweighting factor \\f$c(t)\\f$");
+     214          10 :   keys.addOutputComponent("work","default","the work done by the bias in one AV_STRIDE");
+     215           5 : }
+     216             : 
+     217           4 : VesDeltaF::VesDeltaF(const ActionOptions&ao)
+     218             :   : PLUMED_BIAS_INIT(ao)
+     219           4 :   , isFirstStep_(true)
+     220           4 :   , afterCalculate_(false)
+     221           4 :   , mean_counter_(0)
+     222           4 :   , av_counter_(0)
+     223           4 :   , work_(0)
+     224             : {
+     225             : //set beta
+     226           4 :   const double Kb=plumed.getAtoms().getKBoltzmann();
+     227           4 :   double temp=0;
+     228           4 :   parse("TEMP",temp);
+     229           4 :   double KbT=Kb*temp;
+     230           4 :   if(KbT==0)
+     231             :   {
+     232           0 :     KbT=plumed.getAtoms().getKbT();
+     233           0 :     plumed_massert(KbT>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     234             :   }
+     235           4 :   beta_=1.0/KbT;
+     236             : 
+     237             : //initialize probability grids using local free energies
+     238             :   bool spline=true;
+     239             :   bool sparsegrid=false;
+     240           4 :   std::string funcl="file.free"; //typical name given by sum_hills
+     241             : 
+     242             :   std::vector<std::string> fes_names;
+     243           8 :   for(unsigned n=0;; n++)//NB: here we start from FILE_F0 not from FILE_F1
+     244             :   {
+     245             :     std::string filename;
+     246          24 :     if(!parseNumbered("FILE_F",n,filename))
+     247             :       break;
+     248           8 :     fes_names.push_back(filename);
+     249           8 :     IFile gridfile;
+     250           8 :     gridfile.open(filename);
+     251           8 :     auto g=GridBase::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     252             : // we assume this cannot be sparse. in case we want it to be sparse, some of the methods
+     253             : // that are available only in Grid should be ported to GridBase
+     254           8 :     auto gg=dynamic_cast<Grid*>(g.get());
+     255             : // if this throws, g is deleted
+     256           8 :     plumed_assert(gg);
+     257             : // release ownership in order to transfer it to emplaced pointer
+     258             :     g.release();
+     259           8 :     grid_p_.emplace_back(gg);
+     260          16 :   }
+     261           4 :   plumed_massert(grid_p_.size()>1,"at least 2 basins must be defined, starting from FILE_F0");
+     262           4 :   alpha_size_=grid_p_.size()-1;
+     263           4 :   sym_alpha_size_=alpha_size_*(alpha_size_+1)/2; //useful for symmetric matrix [alpha_size_]x[alpha_size_]
+     264             :   //check for consistency with first local free energy
+     265           8 :   for(unsigned n=1; n<grid_p_.size(); n++)
+     266             :   {
+     267           8 :     std::string error_tag="FILE_F"+std::to_string(n)+" '"+fes_names[n]+"' not compatible with reference one, FILE_F0";
+     268           4 :     plumed_massert(grid_p_[n]->getSize()==grid_p_[0]->getSize(),error_tag);
+     269           4 :     plumed_massert(grid_p_[n]->getMin()==grid_p_[0]->getMin(),error_tag);
+     270           4 :     plumed_massert(grid_p_[n]->getMax()==grid_p_[0]->getMax(),error_tag);
+     271           4 :     plumed_massert(grid_p_[n]->getBinVolume()==grid_p_[0]->getBinVolume(),error_tag);
+     272             :   }
+     273             : 
+     274           4 :   bool no_mintozero=false;
+     275           4 :   parseFlag("NO_MINTOZERO",no_mintozero);
+     276           4 :   if(!no_mintozero)
+     277             :   {
+     278           6 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     279           4 :       grid_p_[n]->setMinToZero();
+     280             :   }
+     281           4 :   bool normalize=false;
+     282           4 :   parseFlag("NORMALIZE",normalize);
+     283           4 :   norm_.resize(grid_p_.size(),0);
+     284           4 :   std::vector<double> c_norm(grid_p_.size());
+     285             :   //convert the FESs to probability distributions
+     286             :   //NB: the spline interpolation will be done on the probability distributions, not on the given FESs
+     287             :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     288          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     289             :   {
+     290         808 :     for(Grid::index_t t=0; t<grid_p_[n]->getSize(); t++)
+     291             :     {
+     292         800 :       std::vector<double> der(ncv);
+     293         800 :       const double val=std::exp(-beta_*grid_p_[n]->getValueAndDerivatives(t,der));
+     294        1600 :       for(unsigned s=0; s<ncv; s++)
+     295         800 :         der[s]*=-beta_*val;
+     296         800 :       grid_p_[n]->setValueAndDerivatives(t,val,der);
+     297         800 :       norm_[n]+=val;
+     298             :     }
+     299           8 :     c_norm[n]=1./beta_*std::log(norm_[n]);
+     300           8 :     if(normalize)
+     301             :     {
+     302           4 :       grid_p_[n]->scaleAllValuesAndDerivatives(1./norm_[n]);
+     303           4 :       norm_[n]=1;
+     304             :     }
+     305             :   }
+     306             : 
+     307             : //get target
+     308           4 :   double biasfactor=0;
+     309           4 :   parse("BIASFACTOR",biasfactor);
+     310           4 :   plumed_massert(biasfactor==0 || biasfactor>1,"BIASFACTOR must be zero (for uniform target) or greater than one");
+     311           4 :   if(biasfactor==0)
+     312           2 :     inv_gamma_=0;
+     313             :   else
+     314           2 :     inv_gamma_=1./biasfactor;
+     315           4 :   tg_counter_=0;
+     316           4 :   tg_stride_=1;
+     317           4 :   parse("TG_STRIDE",tg_stride_);
+     318           4 :   tg_dV_dAlpha_.resize(alpha_size_,0);
+     319           4 :   tg_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     320             : 
+     321             : //setup optimization stuff
+     322           4 :   minimization_step_=1;
+     323           4 :   parse("M_STEP",minimization_step_);
+     324             : 
+     325           4 :   av_stride_=500;
+     326           4 :   parse("AV_STRIDE",av_stride_);
+     327           4 :   av_dV_dAlpha_.resize(alpha_size_,0);
+     328           4 :   av_dV_dAlpha_prod_.resize(sym_alpha_size_,0);
+     329           4 :   av_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     330             : 
+     331           4 :   mean_weight_tau_=0;
+     332           4 :   parse("TAU_MEAN",mean_weight_tau_);
+     333           4 :   if(mean_weight_tau_!=1) //set it to 1 for basic SGD
+     334             :   {
+     335           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");
+     336           4 :     mean_weight_tau_/=av_stride_; //this way you can look at the number of simulation steps to choose TAU_MEAN
+     337             :   }
+     338             : 
+     339           8 :   parseVector("INITIAL_ALPHA",mean_alpha_);
+     340           4 :   if(mean_alpha_.size()>0)
+     341             :   {
+     342           2 :     plumed_massert(mean_alpha_.size()==alpha_size_,"provide one INITIAL_ALPHA for each basin beyond the first one");
+     343             :   }
+     344             :   else
+     345           2 :     mean_alpha_.resize(alpha_size_,0);
+     346           4 :   inst_alpha_=mean_alpha_;
+     347           4 :   exp_alpha_.resize(alpha_size_);
+     348           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     349           4 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     350           4 :   prev_exp_alpha_=exp_alpha_;
+     351             : 
+     352           4 :   damping_off_=false;
+     353           4 :   parseFlag("DAMPING_OFF",damping_off_);
+     354           4 :   if(damping_off_)
+     355           2 :     past_increment2_.resize(alpha_size_,1);
+     356             :   else
+     357           2 :     past_increment2_.resize(alpha_size_,0);
+     358             : 
+     359             : //file printing options
+     360           4 :   std::string alphaFileName("ALPHA");
+     361           4 :   parse("ALPHA_FILE",alphaFileName);
+     362           4 :   print_stride_=10;
+     363           8 :   parse("PRINT_STRIDE",print_stride_);
+     364             :   std::string fmt;
+     365           4 :   parse("FMT",fmt);
+     366             : 
+     367             : //other flags, mainly for debugging
+     368           4 :   NumParallel_=comm.Get_size();
+     369           4 :   rank_=comm.Get_rank();
+     370           4 :   bool serial=false;
+     371           4 :   parseFlag("SERIAL",serial);
+     372           4 :   if(serial)
+     373             :   {
+     374           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     375           2 :     NumParallel_=1;
+     376           2 :     rank_=0;
+     377             :   }
+     378             : 
+     379           4 :   bool multiple_walkers=false;
+     380           4 :   parseFlag("MULTIPLE_WALKERS",multiple_walkers);
+     381           4 :   if(!multiple_walkers)
+     382           2 :     NumWalkers_=1;
+     383             :   else
+     384             :   {
+     385           2 :     if(comm.Get_rank()==0)//multi_sim_comm works well on first rank only
+     386           2 :       NumWalkers_=multi_sim_comm.Get_size();
+     387           2 :     if(comm.Get_size()>1) //if each walker has more than one processor update them all
+     388           0 :       comm.Bcast(NumWalkers_,0);
+     389             :   }
+     390             : 
+     391           4 :   checkRead();
+     392             : 
+     393             : //restart if needed
+     394           4 :   if(getRestart())
+     395             :   {
+     396           2 :     IFile ifile;
+     397           2 :     ifile.link(*this);
+     398           2 :     if(NumWalkers_>1)
+     399           4 :       ifile.enforceSuffix("");
+     400           2 :     if(ifile.FileExist(alphaFileName))
+     401             :     {
+     402           2 :       log.printf("  Restarting from: %s\n",alphaFileName.c_str());
+     403           2 :       log.printf("    all options (also PRINT_STRIDE) must be consistent!\n");
+     404           2 :       log.printf("    any INITIAL_ALPHA will be overwritten\n");
+     405           2 :       ifile.open(alphaFileName);
+     406             :       double time;
+     407           2 :       std::vector<double> damping(alpha_size_);
+     408          20 :       while(ifile.scanField("time",time)) //room for improvements: only last line is important
+     409             :       {
+     410          16 :         for(unsigned i=0; i<alpha_size_; i++)
+     411             :         {
+     412           8 :           const std::string index(std::to_string(i+1));
+     413           8 :           prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     414          16 :           ifile.scanField("alpha_"+index,mean_alpha_[i]);
+     415          16 :           ifile.scanField("auxiliary_"+index,inst_alpha_[i]);
+     416          16 :           ifile.scanField("damping_"+index,damping[i]);
+     417             :         }
+     418           8 :         ifile.scanField();
+     419           8 :         mean_counter_+=print_stride_;
+     420             :       }
+     421           4 :       for(unsigned i=0; i<alpha_size_; i++)
+     422             :       {
+     423           2 :         exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     424           2 :         past_increment2_[i]=damping[i]*damping[i];
+     425             :       }
+     426             :       //sync all walkers and treads. Not sure is mandatory but is no harm
+     427           2 :       comm.Barrier();
+     428           2 :       if(comm.Get_rank()==0)
+     429           2 :         multi_sim_comm.Barrier();
+     430             :     }
+     431             :     else
+     432           0 :       log.printf("  -- WARNING: restart requested, but no '%s' file found!\n",alphaFileName.c_str());
+     433           2 :   }
+     434             : 
+     435             : //setup output file with Alpha values
+     436           4 :   alphaOfile_.link(*this);
+     437           4 :   if(NumWalkers_>1)
+     438             :   {
+     439           2 :     if(comm.Get_rank()==0 && multi_sim_comm.Get_rank()>0)
+     440             :       alphaFileName="/dev/null"; //only first walker writes on file
+     441           4 :     alphaOfile_.enforceSuffix("");
+     442             :   }
+     443           4 :   alphaOfile_.open(alphaFileName);
+     444           4 :   if(fmt.length()>0)
+     445           8 :     alphaOfile_.fmtField(" "+fmt);
+     446             : 
+     447             : //add other output components
+     448           8 :   addComponent("rct"); componentIsNotPeriodic("rct");
+     449           8 :   addComponent("work"); componentIsNotPeriodic("work");
+     450             : 
+     451             : //print some info
+     452           4 :   log.printf("  Temperature T: %g\n",1./(Kb*beta_));
+     453           4 :   log.printf("  Beta (1/Kb*T): %g\n",beta_);
+     454           4 :   log.printf("  Local free energy basins files and normalization constants:\n");
+     455          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     456           8 :     log.printf("    F_%d filename: %s  c_%d=%g\n",n,fes_names[n].c_str(),n,c_norm[n]);
+     457           4 :   if(no_mintozero)
+     458           2 :     log.printf(" -- NO_MINTOZERO: local free energies are not shifted to be zero at minimum\n");
+     459           4 :   if(normalize)
+     460           2 :     log.printf(" -- NORMALIZE: F_n+=c_n, alpha=DeltaF\n");
+     461           4 :   log.printf("  Using target distribution with 1/gamma = %g\n",inv_gamma_);
+     462           4 :   log.printf("    and updated with stride %d\n",tg_stride_);
+     463           4 :   log.printf("  Step for the minimization algorithm: %g\n",minimization_step_);
+     464           4 :   log.printf("  Stride for the ensemble average: %d\n",av_stride_);
+     465           4 :   if(mean_weight_tau_>1)
+     466           2 :     log.printf("  Exponentially decaying average with weight=tau/av_stride=%d\n",mean_weight_tau_);
+     467           4 :   if(mean_weight_tau_==1)
+     468           0 :     log.printf(" +++ WARNING +++ setting TAU_MEAN=1 is equivalent to use simple SGD, without mean alpha nor hessian contribution\n");
+     469           4 :   log.printf("  Initial guess for alpha:\n");
+     470           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     471           4 :     log.printf("    alpha_%d = %g\n",i+1,mean_alpha_[i]);
+     472           4 :   if(damping_off_)
+     473           2 :     log.printf(" -- DAMPING_OFF: the minimization step will NOT become smaller as the simulation goes on\n");
+     474           4 :   log.printf("  Printing on file %s with stride %d\n",alphaFileName.c_str(),print_stride_);
+     475           4 :   if(serial)
+     476           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     477           4 :   if(NumParallel_>1)
+     478           2 :     log.printf("  Using multiple threads per simulation: %d\n",NumParallel_);
+     479           4 :   if(multiple_walkers)
+     480             :   {
+     481           2 :     log.printf(" -- MULTIPLE_WALKERS: multiple simulations will combine statistics for the optimization\n");
+     482           2 :     if(NumWalkers_>1)
+     483             :     {
+     484           2 :       log.printf("    number of walkers: %d\n",NumWalkers_);
+     485           2 :       log.printf("    walker rank: %d\n",multi_sim_comm.Get_rank()); //only comm.Get_rank()=0 prints, so this is fine
+     486             :     }
+     487             :     else
+     488           0 :       log.printf(" +++ WARNING +++ only one replica found: are you sure you are running MPI-connected simulations?\n");
+     489             :   }
+     490           4 :   log.printf(" Bibliography ");
+     491           8 :   log<<plumed.cite("Invernizzi and Parrinello, J. Chem. Theory Comput. 15, 2187-2194 (2019)");
+     492           8 :   log<<plumed.cite("Valsson and Parrinello, Phys. Rev. Lett. 113, 090601 (2014)");
+     493           4 :   if(inv_gamma_>0)
+     494           6 :     log<<plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     495             : 
+     496             : //last initializations
+     497           4 :   prob_.resize(grid_p_.size());
+     498           4 :   der_prob_.resize(grid_p_.size(),std::vector<double>(getNumberOfArguments()));
+     499           4 :   update_tg_and_rct();
+     500           8 : }
+     501             : 
+     502         804 : void VesDeltaF::calculate()
+     503             : {
+     504             : //get CVs
+     505         804 :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     506         804 :   std::vector<double> cv(ncv);
+     507        1608 :   for(unsigned s=0; s<ncv; s++)
+     508         804 :     cv[s]=getArgument(s);
+     509             : //get probabilities for each basin, and total one
+     510        2412 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     511        1608 :     prob_[n]=grid_p_[n]->getValueAndDerivatives(cv,der_prob_[n]);
+     512         804 :   tot_prob_=prob_[0];
+     513        1608 :   for(unsigned i=0; i<alpha_size_; i++)
+     514         804 :     tot_prob_+=prob_[i+1]*exp_alpha_[i];
+     515             : 
+     516             : //update bias and forces: V=-(1-inv_gamma_)*fes
+     517         804 :   setBias((1-inv_gamma_)/beta_*std::log(tot_prob_));
+     518        1608 :   for(unsigned s=0; s<ncv; s++)
+     519             :   {
+     520         804 :     double dProb_dCV_s=der_prob_[0][s];
+     521        1608 :     for(unsigned i=0; i<alpha_size_; i++)
+     522         804 :       dProb_dCV_s+=der_prob_[i+1][s]*exp_alpha_[i];
+     523         804 :     setOutputForce(s,-(1-inv_gamma_)/beta_/tot_prob_*dProb_dCV_s);
+     524             :   }
+     525         804 :   afterCalculate_=true;
+     526         804 : }
+     527             : 
+     528         804 : void VesDeltaF::update()
+     529             : {
+     530             : //skip first step to sync getTime() and av_counter_, as in METAD
+     531         804 :   if(isFirstStep_)
+     532             :   {
+     533           4 :     isFirstStep_=false;
+     534           4 :     return;
+     535             :   }
+     536         800 :   plumed_massert(afterCalculate_,"VesDeltaF::update() must be called after VesDeltaF::calculate() to work properly");
+     537         800 :   afterCalculate_=false;
+     538             : 
+     539             : //calculate derivatives for ensemble averages
+     540         800 :   std::vector<double> dV_dAlpha(alpha_size_);
+     541         800 :   std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     542        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     543         800 :     dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob_*prob_[i+1]*exp_alpha_[i];
+     544        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     545             :   {
+     546         800 :     d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     547        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     548         800 :       d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     549             :   }
+     550             : //update ensemble averages
+     551         800 :   av_counter_++;
+     552        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     553             :   {
+     554         800 :     av_dV_dAlpha_[i]+=(dV_dAlpha[i]-av_dV_dAlpha_[i])/av_counter_;
+     555        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     556             :     {
+     557         800 :       const unsigned ij=get_index(i,j);
+     558         800 :       av_dV_dAlpha_prod_[ij]+=(dV_dAlpha[i]*dV_dAlpha[j]-av_dV_dAlpha_prod_[ij])/av_counter_;
+     559         800 :       av_d2V_dAlpha2_[ij]+=(d2V_dAlpha2[ij]-av_d2V_dAlpha2_[ij])/av_counter_;
+     560             :     }
+     561             :   }
+     562             : //update work
+     563         800 :   double prev_tot_prob=prob_[0];
+     564        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     565         800 :     prev_tot_prob+=prob_[i+1]*prev_exp_alpha_[i];
+     566         800 :   work_+=(1-inv_gamma_)/beta_*std::log(tot_prob_/prev_tot_prob);
+     567             : 
+     568             : //update coefficients
+     569         800 :   if(av_counter_==av_stride_)
+     570             :   {
+     571          16 :     update_alpha();
+     572          16 :     tg_counter_++;
+     573          16 :     if(tg_counter_==tg_stride_)
+     574             :     {
+     575          12 :       update_tg_and_rct();
+     576          12 :       tg_counter_=0;
+     577             :     }
+     578             :     //reset the ensemble averages
+     579          16 :     av_counter_=0;
+     580             :     std::fill(av_dV_dAlpha_.begin(),av_dV_dAlpha_.end(),0);
+     581             :     std::fill(av_dV_dAlpha_prod_.begin(),av_dV_dAlpha_prod_.end(),0);
+     582             :     std::fill(av_d2V_dAlpha2_.begin(),av_d2V_dAlpha2_.end(),0);
+     583             :   }
+     584             : }
+     585             : 
+     586          16 : void VesDeltaF::update_tg_and_rct()
+     587             : {
+     588             : //calculate target averages
+     589          16 :   double Z_0=norm_[0];
+     590          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     591          16 :     Z_0+=norm_[i+1]*exp_alpha_[i];
+     592          16 :   double Z_tg=0;
+     593             :   std::fill(tg_dV_dAlpha_.begin(),tg_dV_dAlpha_.end(),0);
+     594             :   std::fill(tg_d2V_dAlpha2_.begin(),tg_d2V_dAlpha2_.end(),0);
+     595        1116 :   for(Grid::index_t t=rank_; t<grid_p_[0]->getSize(); t+=NumParallel_)
+     596             :   { //TODO can we recycle some code?
+     597        1100 :     std::vector<double> prob(grid_p_.size());
+     598        3300 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     599        2200 :       prob[n]=grid_p_[n]->getValue(t);
+     600        1100 :     double tot_prob=prob[0];
+     601        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     602        1100 :       tot_prob+=prob[i+1]*exp_alpha_[i];
+     603        1100 :     std::vector<double> dV_dAlpha(alpha_size_);
+     604        1100 :     std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     605        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     606        1100 :       dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob*prob[i+1]*exp_alpha_[i];
+     607        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     608             :     {
+     609        1100 :       d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     610        2200 :       for(unsigned j=i; j<alpha_size_; j++)
+     611        1100 :         d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     612             :     }
+     613        1100 :     const double unnorm_tg_p=std::pow(tot_prob,inv_gamma_);
+     614        1100 :     Z_tg+=unnorm_tg_p;
+     615        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     616        1100 :       tg_dV_dAlpha_[i]+=unnorm_tg_p*dV_dAlpha[i];
+     617        2200 :     for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     618        1100 :       tg_d2V_dAlpha2_[ij]+=unnorm_tg_p*d2V_dAlpha2[ij];
+     619             :   }
+     620          16 :   if(NumParallel_>1)
+     621             :   {
+     622          10 :     comm.Sum(Z_tg);
+     623          10 :     comm.Sum(tg_dV_dAlpha_);
+     624          10 :     comm.Sum(tg_d2V_dAlpha2_);
+     625             :   }
+     626          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     627          16 :     tg_dV_dAlpha_[i]/=Z_tg;
+     628          32 :   for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     629          16 :     tg_d2V_dAlpha2_[ij]/=Z_tg;
+     630          16 :   getPntrToComponent("rct")->set(-1./beta_*std::log(Z_tg/Z_0)); //Z_tg is the best available estimate of Z_V
+     631          16 : }
+     632             : 
+     633          16 : void VesDeltaF::update_alpha()
+     634             : {
+     635             : //combining the averages of multiple walkers
+     636          16 :   if(NumWalkers_>1)
+     637             :   {
+     638           8 :     if(comm.Get_rank()==0) //sum only once: in the first rank of each walker
+     639             :     {
+     640           8 :       multi_sim_comm.Sum(av_dV_dAlpha_);
+     641           8 :       multi_sim_comm.Sum(av_dV_dAlpha_prod_);
+     642           8 :       multi_sim_comm.Sum(av_d2V_dAlpha2_);
+     643          16 :       for(unsigned i=0; i<alpha_size_; i++)
+     644           8 :         av_dV_dAlpha_[i]/=NumWalkers_;
+     645          16 :       for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     646             :       {
+     647           8 :         av_dV_dAlpha_prod_[ij]/=NumWalkers_;
+     648           8 :         av_d2V_dAlpha2_[ij]/=NumWalkers_;
+     649             :       }
+     650             :     }
+     651           8 :     if(comm.Get_size()>1)//if there are more ranks for each walker, everybody has to know
+     652             :     {
+     653           0 :       comm.Bcast(av_dV_dAlpha_,0);
+     654           0 :       comm.Bcast(av_dV_dAlpha_prod_,0);
+     655           0 :       comm.Bcast(av_d2V_dAlpha2_,0);
+     656             :     }
+     657             :   }
+     658             :   //set work and reset it
+     659          16 :   getPntrToComponent("work")->set(work_);
+     660          16 :   work_=0;
+     661             : 
+     662             : //build the gradient and the Hessian of the functional
+     663          16 :   std::vector<double> grad_omega(alpha_size_);
+     664          16 :   std::vector<double> hess_omega(sym_alpha_size_);
+     665          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     666             :   {
+     667          16 :     grad_omega[i]=tg_dV_dAlpha_[i]-av_dV_dAlpha_[i];
+     668          32 :     for(unsigned j=i; j<alpha_size_; j++)
+     669             :     {
+     670          16 :       const unsigned ij=get_index(i,j);
+     671          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];
+     672             :     }
+     673             :   }
+     674             : //calculate the increment and update alpha
+     675          16 :   mean_counter_++;
+     676             :   long unsigned mean_weight=mean_counter_;
+     677          16 :   if(mean_weight_tau_>0 && mean_weight_tau_<mean_counter_)
+     678             :     mean_weight=mean_weight_tau_;
+     679          16 :   std::vector<double> damping(alpha_size_);
+     680          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     681             :   {
+     682          16 :     double increment_i=grad_omega[i];
+     683          32 :     for(unsigned j=0; j<alpha_size_; j++)
+     684          16 :       increment_i+=hess_omega[get_index(i,j)]*(inst_alpha_[j]-mean_alpha_[j]);
+     685          16 :     if(!damping_off_)
+     686           8 :       past_increment2_[i]+=increment_i*increment_i;
+     687          16 :     damping[i]=std::sqrt(past_increment2_[i]);
+     688          16 :     prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     689          16 :     inst_alpha_[i]-=minimization_step_/damping[i]*increment_i;
+     690          16 :     mean_alpha_[i]+=(inst_alpha_[i]-mean_alpha_[i])/mean_weight;
+     691          16 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     692             :   }
+     693             : 
+     694             : //update the Alpha file
+     695          16 :   if(mean_counter_%print_stride_==0)
+     696             :   {
+     697          16 :     alphaOfile_.printField("time",getTime());
+     698          32 :     for(unsigned i=0; i<alpha_size_; i++)
+     699             :     {
+     700          16 :       const std::string index(std::to_string(i+1));
+     701          32 :       alphaOfile_.printField("alpha_"+index,mean_alpha_[i]);
+     702          32 :       alphaOfile_.printField("auxiliary_"+index,inst_alpha_[i]);
+     703          32 :       alphaOfile_.printField("damping_"+index,damping[i]);
+     704             :     }
+     705          16 :     alphaOfile_.printField();
+     706             :   }
+     707          16 : }
+     708             : 
+     709             : //mapping of a [alpha_size_]x[alpha_size_] symmetric matrix into a vector of size sym_alpha_size_, useful for the communicator
+     710        4632 : inline unsigned VesDeltaF::get_index(const unsigned i, const unsigned j) const
+     711             : {
+     712        4632 :   if(i<=j)
+     713        4632 :     return j+i*(alpha_size_-1)-i*(i-1)/2;
+     714             :   else
+     715           0 :     return get_index(j,i);
+     716             : }
+     717             : 
+     718             : }
+     719             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..ae9721bd76 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html @@ -0,0 +1,169 @@ + + + + + + + + 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:14014596.6 %
Date:2024-06-10 08:19:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18VesLinearExpansionC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves18VesLinearExpansionD2Ev0
_ZNK4PLMD3ves18VesLinearExpansion23calculateReweightFactorEv0
_ZN4PLMD3ves18VesLinearExpansion26restartTargetDistributionsEv8
_ZN4PLMD3ves18VesLinearExpansion25writeTargetDistProjToFileEv13
_ZN4PLMD3ves18VesLinearExpansion22setupFesProjFileOutputEv17
_ZN4PLMD3ves18VesLinearExpansion18resetFesFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion18writeFesProjToFileEv36
_ZN4PLMD3ves18VesLinearExpansion19resetBiasFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion21writeTargetDistToFileEv82
_ZN4PLMD3ves18VesLinearExpansion18setupFesFileOutputEv83
_ZN4PLMD3ves18VesLinearExpansion19setupBiasFileOutputEv87
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe3206createERKNS_13ActionOptionsE90
_ZN4PLMD3ves18VesLinearExpansionC1ERKNS_13ActionOptionsE90
_ZN4PLMD3ves18VesLinearExpansionD0Ev90
_ZN4PLMD3ves18VesLinearExpansionD1Ev90
_ZN4PLMD3ves18VesLinearExpansion16registerKeywordsERNS_8KeywordsE91
_ZN4PLMD3ves18VesLinearExpansion14writeFesToFileEv169
_ZN4PLMD3ves18VesLinearExpansion15writeBiasToFileEv173
_ZN4PLMD3ves18VesLinearExpansion25updateTargetDistributionsEv355
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe320C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe320D2Ev3473
_ZN4PLMD3ves18VesLinearExpansion6updateEv23750
_ZN4PLMD3ves18VesLinearExpansion9calculateEv23750
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.func.html b/coverage/ves/VesLinearExpansion.cpp.func.html new file mode 100644 index 0000000000..9327d74a66 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func.html @@ -0,0 +1,169 @@ + + + + + + + + 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:14014596.6 %
Date:2024-06-10 08:19:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe3206createERKNS_13ActionOptionsE90
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe320C2Ev3473
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe320D2Ev3473
_ZN4PLMD3ves18VesLinearExpansion14writeFesToFileEv169
_ZN4PLMD3ves18VesLinearExpansion15writeBiasToFileEv173
_ZN4PLMD3ves18VesLinearExpansion16registerKeywordsERNS_8KeywordsE91
_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.15
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.gcov.html b/coverage/ves/VesLinearExpansion.cpp.gcov.html new file mode 100644 index 0000000000..574682aef9 --- /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:14014596.6 %
Date:2024-06-10 08:19:14Functions:212487.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 "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       10599 : PLUMED_REGISTER_ACTION(VesLinearExpansion,"VES_LINEAR_EXPANSION")
+     321             : 
+     322          91 : void VesLinearExpansion::registerKeywords( Keywords& keys ) {
+     323          91 :   VesBias::registerKeywords(keys);
+     324             :   //
+     325          91 :   VesBias::useInitialCoeffsKeywords(keys);
+     326          91 :   VesBias::useTargetDistributionKeywords(keys);
+     327          91 :   VesBias::useBiasCutoffKeywords(keys);
+     328          91 :   VesBias::useGridBinKeywords(keys);
+     329          91 :   VesBias::useProjectionArgKeywords(keys);
+     330             :   //
+     331          91 :   keys.use("ARG");
+     332         182 :   keys.add("compulsory","BASIS_FUNCTIONS","the label of the one dimensional basis functions that should be used.");
+     333         182 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential.");
+     334          91 : }
+     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         135 :     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.15
+
+ + + 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 0000000000..8e2e1f62d2 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/VesTools.cpp.func.html b/coverage/ves/VesTools.cpp.func.html new file mode 100644 index 0000000000..3a9f00658d --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/VesTools.cpp.gcov.html b/coverage/ves/VesTools.cpp.gcov.html new file mode 100644 index 0000000000..20866876e0 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..eed58498cb --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/VesTools.h.func.html b/coverage/ves/VesTools.h.func.html new file mode 100644 index 0000000000..10e14eaa93 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/VesTools.h.gcov.html b/coverage/ves/VesTools.h.gcov.html new file mode 100644 index 0000000000..5e238587e6 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..9a2bb45115 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid21getFilterCoefficientsEjbNS1_4TypeE49
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.func.html b/coverage/ves/WaveletCoeffs.cpp.func.html new file mode 100644 index 0000000000..de3a5b62b7 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid21getFilterCoefficientsEjbNS1_4TypeE49
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.gcov.html b/coverage/ves/WaveletCoeffs.cpp.gcov.html new file mode 100644 index 0000000000..56606a7071 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..65042805a5 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.func.html b/coverage/ves/WaveletGrid.cpp.func.html new file mode 100644 index 0000000000..8c3f0e230b --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.gcov.html b/coverage/ves/WaveletGrid.cpp.gcov.html new file mode 100644 index 0000000000..bee721d341 --- /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-06-10 08:19:14Functions: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         564 :   {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        3944 :         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.15
+
+ + + diff --git a/coverage/ves/index-sort-f.html b/coverage/ves/index-sort-f.html new file mode 100644 index 0000000000..c98ad2e121 --- /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:5939723282.1 %
Date:2024-06-10 08:19:14Functions:55578870.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
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
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
TD_ProductDistribution.cpp +
63.6%63.6%
+
63.6 %49 / 7753.8 %7 / 13
GridLinearInterpolation.cpp +
55.0%55.0%
+
55.0 %66 / 12055.6 %5 / 9
VesBias.cpp +
76.4%76.4%
+
76.4 %330 / 43260.0 %27 / 45
OutputFesBias.cpp +
88.4%88.4%
+
88.4 %61 / 6962.5 %5 / 8
TD_ProductCombination.cpp +
73.7%73.7%
+
73.7 %56 / 7669.2 %9 / 13
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7769.2 %9 / 13
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %84 / 9071.4 %5 / 7
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %109 / 11171.4 %5 / 7
BasisFunctions.h +
96.7%96.7%
+
96.7 %59 / 6175.0 %6 / 8
TD_WellTempered.cpp +
90.6%90.6%
+
90.6 %29 / 3277.8 %7 / 9
BasisFunctions.cpp +
87.8%87.8%
+
87.8 %224 / 25581.0 %17 / 21
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
Optimizer.cpp +
89.4%89.4%
+
89.4 %682 / 76384.4 %27 / 32
TargetDistribution.cpp +
87.2%87.2%
+
87.2 %190 / 21884.6 %22 / 26
Opt_Dummy.cpp +
95.5%95.5%
+
95.5 %21 / 2285.7 %6 / 7
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %60 / 6385.7 %6 / 7
Opt_Adam.cpp +
93.2%93.2%
+
93.2 %68 / 7385.7 %6 / 7
Opt_RobbinsMonroSGD.cpp +
96.0%96.0%
+
96.0 %24 / 2585.7 %6 / 7
VesLinearExpansion.cpp +
96.6%96.6%
+
96.6 %140 / 14587.5 %21 / 24
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %148 / 15288.9 %8 / 9
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %198 / 20588.9 %8 / 9
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
TD_Custom.cpp +
86.7%86.7%
+
86.7 %78 / 9090.0 %9 / 10
VesDeltaF.cpp +
97.2%97.2%
+
97.2 %346 / 35690.9 %10 / 11
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-0 / 0
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
WaveletCoeffs.cpp +
96.7%96.7%
+
96.7 %145 / 150100.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
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
VesTools.h +
65.6%65.6%
+
65.6 %21 / 32100.0 %5 / 5
TD_ChiSquared.cpp +
100.0%
+
100.0 %41 / 41100.0 %6 / 6
TD_Exponential.cpp +
100.0%
+
100.0 %27 / 27100.0 %6 / 6
TD_Chi.cpp +
100.0%
+
100.0 %41 / 41100.0 %6 / 6
TD_Grid.cpp +
94.9%94.9%
+
94.9 %56 / 59100.0 %6 / 6
BF_Powers.cpp +
100.0%
+
100.0 %36 / 36100.0 %7 / 7
TD_GeneralizedNormal.cpp +
91.4%91.4%
+
91.4 %64 / 70100.0 %7 / 7
BF_Chebyshev.cpp +
100.0%
+
100.0 %36 / 36100.0 %7 / 7
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %39 / 39100.0 %7 / 7
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %55 / 56100.0 %7 / 7
BF_Gaussians.cpp +
100.0%
+
100.0 %53 / 53100.0 %7 / 7
BF_Legendre.cpp +
100.0%
+
100.0 %43 / 43100.0 %7 / 7
TD_ExponentiallyModifiedGaussian.cpp +
90.6%90.6%
+
90.6 %58 / 64100.0 %7 / 7
BF_CubicBsplines.cpp +
100.0%
+
100.0 %59 / 59100.0 %7 / 7
BF_Fourier.cpp +
100.0%
+
100.0 %39 / 39100.0 %8 / 8
BF_Sine.cpp +
100.0%
+
100.0 %36 / 36100.0 %8 / 8
WaveletGrid.cpp +
99.0%99.0%
+
99.0 %104 / 105100.0 %8 / 8
TD_Gaussian.cpp +
90.6%90.6%
+
90.6 %77 / 85100.0 %8 / 8
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %75 / 76100.0 %8 / 8
BF_Wavelets.cpp +
100.0%
+
100.0 %119 / 119100.0 %8 / 8
BF_Custom.cpp +
82.4%82.4%
+
82.4 %126 / 153100.0 %8 / 8
BF_Combined.cpp +
97.0%97.0%
+
97.0 %64 / 66100.0 %8 / 8
BF_Cosine.cpp +
100.0%
+
100.0 %36 / 36100.0 %8 / 8
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %326 / 336100.0 %9 / 9
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/index-sort-l.html b/coverage/ves/index-sort-l.html new file mode 100644 index 0000000000..b0cee1527a --- /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:5939723282.1 %
Date:2024-06-10 08:19:14Functions:55578870.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.6%63.6%
+
63.6 %49 / 7753.8 %7 / 13
VesTools.h +
65.6%65.6%
+
65.6 %21 / 32100.0 %5 / 5
TD_ProductCombination.cpp +
73.7%73.7%
+
73.7 %56 / 7669.2 %9 / 13
VesBias.h +
74.2%74.2%
+
74.2 %66 / 8936.0 %9 / 25
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7769.2 %9 / 13
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
VesBias.cpp +
76.4%76.4%
+
76.4 %330 / 43260.0 %27 / 45
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
BF_Custom.cpp +
82.4%82.4%
+
82.4 %126 / 153100.0 %8 / 8
TD_Custom.cpp +
86.7%86.7%
+
86.7 %78 / 9090.0 %9 / 10
TargetDistribution.cpp +
87.2%87.2%
+
87.2 %190 / 21884.6 %22 / 26
BasisFunctions.cpp +
87.8%87.8%
+
87.8 %224 / 25581.0 %17 / 21
OutputFesBias.cpp +
88.4%88.4%
+
88.4 %61 / 6962.5 %5 / 8
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
Optimizer.cpp +
89.4%89.4%
+
89.4 %682 / 76384.4 %27 / 32
TD_Gaussian.cpp +
90.6%90.6%
+
90.6 %77 / 85100.0 %8 / 8
TD_WellTempered.cpp +
90.6%90.6%
+
90.6 %29 / 3277.8 %7 / 9
TD_ExponentiallyModifiedGaussian.cpp +
90.6%90.6%
+
90.6 %58 / 64100.0 %7 / 7
TD_GeneralizedNormal.cpp +
91.4%91.4%
+
91.4 %64 / 70100.0 %7 / 7
VesTools.cpp +
92.1%92.1%
+
92.1 %35 / 38100.0 %2 / 2
Opt_Adam.cpp +
93.2%93.2%
+
93.2 %68 / 7385.7 %6 / 7
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %84 / 9071.4 %5 / 7
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
TD_Grid.cpp +
94.9%94.9%
+
94.9 %56 / 59100.0 %6 / 6
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %60 / 6385.7 %6 / 7
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
Opt_Dummy.cpp +
95.5%95.5%
+
95.5 %21 / 2285.7 %6 / 7
Opt_RobbinsMonroSGD.cpp +
96.0%96.0%
+
96.0 %24 / 2585.7 %6 / 7
VesLinearExpansion.cpp +
96.6%96.6%
+
96.6 %140 / 14587.5 %21 / 24
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %198 / 20588.9 %8 / 9
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 +
97.0%97.0%
+
97.0 %64 / 66100.0 %8 / 8
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %326 / 336100.0 %9 / 9
VesDeltaF.cpp +
97.2%97.2%
+
97.2 %346 / 35690.9 %10 / 11
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %148 / 15288.9 %8 / 9
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %109 / 11171.4 %5 / 7
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %55 / 56100.0 %7 / 7
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %75 / 76100.0 %8 / 8
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 %27 / 27100.0 %6 / 6
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
BF_Sine.cpp +
100.0%
+
100.0 %36 / 36100.0 %8 / 8
BF_Powers.cpp +
100.0%
+
100.0 %36 / 36100.0 %7 / 7
BF_Chebyshev.cpp +
100.0%
+
100.0 %36 / 36100.0 %7 / 7
BF_Cosine.cpp +
100.0%
+
100.0 %36 / 36100.0 %8 / 8
BF_Fourier.cpp +
100.0%
+
100.0 %39 / 39100.0 %8 / 8
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %39 / 39100.0 %7 / 7
TD_ChiSquared.cpp +
100.0%
+
100.0 %41 / 41100.0 %6 / 6
TD_Chi.cpp +
100.0%
+
100.0 %41 / 41100.0 %6 / 6
BF_Legendre.cpp +
100.0%
+
100.0 %43 / 43100.0 %7 / 7
BF_Gaussians.cpp +
100.0%
+
100.0 %53 / 53100.0 %7 / 7
BF_CubicBsplines.cpp +
100.0%
+
100.0 %59 / 59100.0 %7 / 7
BF_Wavelets.cpp +
100.0%
+
100.0 %119 / 119100.0 %8 / 8
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/ves/index.html b/coverage/ves/index.html new file mode 100644 index 0000000000..4d7992932f --- /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:5939723282.1 %
Date:2024-06-10 08:19:14Functions:55578870.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
BF_Chebyshev.cpp +
100.0%
+
100.0 %36 / 36100.0 %7 / 7
BF_Combined.cpp +
97.0%97.0%
+
97.0 %64 / 66100.0 %8 / 8
BF_Cosine.cpp +
100.0%
+
100.0 %36 / 36100.0 %8 / 8
BF_CubicBsplines.cpp +
100.0%
+
100.0 %59 / 59100.0 %7 / 7
BF_Custom.cpp +
82.4%82.4%
+
82.4 %126 / 153100.0 %8 / 8
BF_Fourier.cpp +
100.0%
+
100.0 %39 / 39100.0 %8 / 8
BF_Gaussians.cpp +
100.0%
+
100.0 %53 / 53100.0 %7 / 7
BF_Legendre.cpp +
100.0%
+
100.0 %43 / 43100.0 %7 / 7
BF_Powers.cpp +
100.0%
+
100.0 %36 / 36100.0 %7 / 7
BF_Sine.cpp +
100.0%
+
100.0 %36 / 36100.0 %8 / 8
BF_Wavelets.cpp +
100.0%
+
100.0 %119 / 119100.0 %8 / 8
BasisFunctions.cpp +
87.8%87.8%
+
87.8 %224 / 25581.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 %326 / 336100.0 %9 / 9
Opt_Adam.cpp +
93.2%93.2%
+
93.2 %68 / 7385.7 %6 / 7
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %60 / 6385.7 %6 / 7
Opt_Dummy.cpp +
95.5%95.5%
+
95.5 %21 / 2285.7 %6 / 7
Opt_RobbinsMonroSGD.cpp +
96.0%96.0%
+
96.0 %24 / 2585.7 %6 / 7
Optimizer.cpp +
89.4%89.4%
+
89.4 %682 / 76384.4 %27 / 32
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %109 / 11171.4 %5 / 7
OutputFesBias.cpp +
88.4%88.4%
+
88.4 %61 / 6962.5 %5 / 8
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %84 / 9071.4 %5 / 7
TD_Chi.cpp +
100.0%
+
100.0 %41 / 41100.0 %6 / 6
TD_ChiSquared.cpp +
100.0%
+
100.0 %41 / 41100.0 %6 / 6
TD_Custom.cpp +
86.7%86.7%
+
86.7 %78 / 9090.0 %9 / 10
TD_Exponential.cpp +
100.0%
+
100.0 %27 / 27100.0 %6 / 6
TD_ExponentiallyModifiedGaussian.cpp +
90.6%90.6%
+
90.6 %58 / 64100.0 %7 / 7
TD_Gaussian.cpp +
90.6%90.6%
+
90.6 %77 / 85100.0 %8 / 8
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %39 / 39100.0 %7 / 7
TD_GeneralizedNormal.cpp +
91.4%91.4%
+
91.4 %64 / 70100.0 %7 / 7
TD_Grid.cpp +
94.9%94.9%
+
94.9 %56 / 59100.0 %6 / 6
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7769.2 %9 / 13
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %198 / 20588.9 %8 / 9
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %148 / 15288.9 %8 / 9
TD_ProductCombination.cpp +
73.7%73.7%
+
73.7 %56 / 7669.2 %9 / 13
TD_ProductDistribution.cpp +
63.6%63.6%
+
63.6 %49 / 7753.8 %7 / 13
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %55 / 56100.0 %7 / 7
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %75 / 76100.0 %8 / 8
TD_WellTempered.cpp +
90.6%90.6%
+
90.6 %29 / 3277.8 %7 / 9
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
TargetDistribution.cpp +
87.2%87.2%
+
87.2 %190 / 21884.6 %22 / 26
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
VesBias.cpp +
76.4%76.4%
+
76.4 %330 / 43260.0 %27 / 45
VesBias.h +
74.2%74.2%
+
74.2 %66 / 8936.0 %9 / 25
VesDeltaF.cpp +
97.2%97.2%
+
97.2 %346 / 35690.9 %10 / 11
VesLinearExpansion.cpp +
96.6%96.6%
+
96.6 %140 / 14587.5 %21 / 24
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.15
+
+ + + 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 0000000000..9bc8b1bef5 --- /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:10210795.3 %
Date:2024-06-10 08:19:14Functions: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_8KeywordsE83
_ZN4PLMD10vesselbase19ActionWithAveraging12clearAverageEv102
_ZNK4PLMD10vesselbase19ActionWithAveraging21getNumberOfQuantitiesEv374
_ZN4PLMD10vesselbase19ActionWithAveraging12lockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging14unlockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging6updateEv1258
_ZNK4PLMD10vesselbase19ActionWithAveraging11performTaskERKjS3_RNS_10MultiValueE60010
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.cpp.func.html b/coverage/vesselbase/ActionWithAveraging.cpp.func.html new file mode 100644 index 0000000000..efb8d2c1b4 --- /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:10210795.3 %
Date:2024-06-10 08:19:14Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase19ActionWithAveraging12clearAverageEv102
_ZN4PLMD10vesselbase19ActionWithAveraging12lockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging12runFinalJobsEv58
_ZN4PLMD10vesselbase19ActionWithAveraging14unlockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging16registerKeywordsERNS_8KeywordsE83
_ZN4PLMD10vesselbase19ActionWithAveraging17performOperationsERKb0
_ZN4PLMD10vesselbase19ActionWithAveraging18setAveragingActionESt10unique_ptrINS0_15AveragingVesselESt14default_deleteIS3_EERKb68
_ZN4PLMD10vesselbase19ActionWithAveraging29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD10vesselbase19ActionWithAveraging6updateEv1258
_ZN4PLMD10vesselbase19ActionWithAveragingC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase19ActionWithAveragingC2ERKNS_13ActionOptionsE73
_ZNK4PLMD10vesselbase19ActionWithAveraging11performTaskERKjS3_RNS_10MultiValueE60010
_ZNK4PLMD10vesselbase19ActionWithAveraging19ignoreNormalizationEv53
_ZNK4PLMD10vesselbase19ActionWithAveraging21getNumberOfQuantitiesEv374
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.cpp.gcov.html b/coverage/vesselbase/ActionWithAveraging.cpp.gcov.html new file mode 100644 index 0000000000..0bdb92ab43 --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.cpp.gcov.html @@ -0,0 +1,277 @@ + + + + + + + + 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:10210795.3 %
Date:2024-06-10 08:19:14Functions: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          83 : void ActionWithAveraging::registerKeywords( Keywords& keys ) {
+      33          83 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys ); ActionAtomistic::registerKeywords( keys );
+      34          83 :   ActionWithArguments::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithVessel::registerKeywords( keys );
+      35         166 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be collected and added to the quantity being averaged");
+      36         166 :   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         166 :   keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages");
+      39         166 :   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          83 :   keys.remove("NUMERICAL_DERIVATIVES");
+      41          83 : }
+      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          68 :   myaverage=av_vessel.get();
+     110          68 :   addVessel( std::move(av_vessel) );
+     111          68 :   useRunAllTasks=usetasks; resizeFunctions();
+     112          68 : }
+     113             : 
+     114        1240 : void ActionWithAveraging::lockRequests() {
+     115             :   ActionAtomistic::lockRequests();
+     116             :   ActionWithArguments::lockRequests();
+     117             : }
+     118             : 
+     119        1240 : void ActionWithAveraging::unlockRequests() {
+     120             :   ActionAtomistic::unlockRequests();
+     121             :   ActionWithArguments::unlockRequests();
+     122             : }
+     123             : 
+     124         374 : unsigned ActionWithAveraging::getNumberOfQuantities() const {
+     125         374 :   if( my_analysis_object ) return getNumberOfArguments()+2;
+     126             :   return 2;
+     127             : }
+     128             : 
+     129           0 : void ActionWithAveraging::calculateNumericalDerivatives(PLMD::ActionWithValue*) {
+     130           0 :   error("not possible to compute numerical derivatives for this action");
+     131             : }
+     132             : 
+     133        1258 : void ActionWithAveraging::update() {
+     134        1258 :   if( (clearstride!=1 && getStep()==0) || (!onStep() && !my_analysis_object) ) return;
+     135        1177 :   if( my_analysis_object ) {
+     136           7 :     analysis::ReadAnalysisFrames* myfram = dynamic_cast<analysis::ReadAnalysisFrames*>( my_analysis_object );
+     137           7 :     if( !activated && !myfram && !onStep() ) return ;
+     138           7 :     else if( !activated && !my_analysis_object->onStep() ) return ;
+     139             :   }
+     140             : 
+     141             :   // Clear if it is time to reset
+     142        1177 :   if( myaverage ) {
+     143        1176 :     if( myaverage->wasreset() ) clearAverage();
+     144             :   }
+     145             :   // Calculate the weight for all reweighting
+     146        1177 :   if ( weights.size()>0 && !my_analysis_object ) {
+     147        3018 :     double sum=0; for(unsigned i=0; i<weights.size(); ++i) sum+=weights[i]->get();
+     148        1009 :     lweight=sum; cweight = exp( sum );
+     149             :   } else {
+     150         168 :     lweight=0; cweight=1.0;
+     151             :   }
+     152             :   // Prepare the task list for averaging
+     153        1177 :   if( my_analysis_object ) {
+     154        2115 :     for(unsigned i=getFullNumberOfTasks(); i<my_analysis_object->getNumberOfDataPoints(); ++i) addTaskToList(i);
+     155           7 :     deactivateAllTasks(); cweight=0;
+     156        2115 :     for(unsigned i=0; i<my_analysis_object->getNumberOfDataPoints(); ++i) {
+     157        2108 :       taskFlags[i]=1; cweight += my_analysis_object->getWeight(i);
+     158             :     }
+     159           7 :     lockContributors();
+     160             :   }
+     161             :   // Prepare to do the averaging
+     162        1177 :   prepareForAveraging();
+     163             :   // Run all the tasks (if required
+     164        1177 :   if( my_analysis_object || useRunAllTasks ) runAllTasks();
+     165             :   // This the averaging if it is not done using task list
+     166        1032 :   else performOperations( true );
+     167             :   // Update the norm
+     168        1177 :   double normt = cweight; if( !my_analysis_object && normalization==ndata ) normt = 1;
+     169        1177 :   if( myaverage && my_analysis_object ) myaverage->setNorm( normt );
+     170        1170 :   else if( myaverage ) myaverage->setNorm( normt + myaverage->getNorm() );
+     171             :   // Finish the averaging
+     172        1177 :   finishAveraging();
+     173             :   // By resetting here we are ensuring that the grid will be cleared at the start of the next step
+     174        1177 :   if( myaverage ) {
+     175        1176 :     if( getStride()==0 || (clearstride>0 && getStep()%clearstride==0) ) myaverage->reset();
+     176             :   }
+     177             : }
+     178             : 
+     179       60010 : void ActionWithAveraging::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     180       60010 :   if( my_analysis_object ) {
+     181        2108 :     analysis::DataCollectionObject& mystore=my_analysis_object->getStoredData( current, false );
+     182        4216 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) myvals.setValue( 1+i, mystore.getArgumentValue( ActionWithArguments::getArguments()[i]->getName() ) );
+     183        2108 :     myvals.setValue( 0, my_analysis_object->getWeight(current) );
+     184        2108 :     if( normalization==f ) myvals.setValue( 1+getNumberOfArguments(), 1.0 ); else myvals.setValue( 1+getNumberOfArguments(), 1.0 / cweight );
+     185        2108 :     accumulateAverage( myvals );
+     186             :   } else {
+     187       57902 :     runTask( current, myvals );
+     188             :   }
+     189       60010 : }
+     190             : 
+     191         102 : void ActionWithAveraging::clearAverage() { plumed_assert( myaverage->wasreset() ); myaverage->clear(); }
+     192             : 
+     193           0 : void ActionWithAveraging::performOperations( const bool& from_update ) { plumed_error(); }
+     194             : 
+     195          58 : void ActionWithAveraging::runFinalJobs() {
+     196          58 :   if( my_analysis_object && getStride()==0 ) { activated=true; update(); }
+     197          58 : }
+     198             : 
+     199             : }
+     200             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..43fa8f3934 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.h.func.html b/coverage/vesselbase/ActionWithAveraging.h.func.html new file mode 100644 index 0000000000..8d15c41261 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.h.gcov.html b/coverage/vesselbase/ActionWithAveraging.h.gcov.html new file mode 100644 index 0000000000..023e3556e2 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..f2ce634163 --- /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-06-10 08:19:14Functions: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_8KeywordsE27
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.cpp.func.html b/coverage/vesselbase/ActionWithInputVessel.cpp.func.html new file mode 100644 index 0000000000..a537927719 --- /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-06-10 08:19:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel12readArgumentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE24
_ZN4PLMD10vesselbase21ActionWithInputVessel16registerKeywordsERNS_8KeywordsE27
_ZN4PLMD10vesselbase21ActionWithInputVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD10vesselbase21ActionWithInputVessel29calculateNumericalDerivativesEPNS_15ActionWithValueE5
_ZN4PLMD10vesselbase21ActionWithInputVesselC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase21ActionWithInputVesselC2ERKNS_13ActionOptionsE24
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.cpp.gcov.html b/coverage/vesselbase/ActionWithInputVessel.cpp.gcov.html new file mode 100644 index 0000000000..79cfb812f2 --- /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-06-10 08:19:14Functions: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          27 : void ActionWithInputVessel::registerKeywords(Keywords& keys) {
+      32          54 :   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          54 :   keys.reserve("compulsory","GRID","the action that creates the input grid you would like to use");
+      36          27 : }
+      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.15
+
+ + + 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 0000000000..3559c8eb3a --- /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-06-10 08:19:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel15addBridgeForcesERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.h.func.html b/coverage/vesselbase/ActionWithInputVessel.h.func.html new file mode 100644 index 0000000000..3dd1a40db9 --- /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-06-10 08:19:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel15addBridgeForcesERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.h.gcov.html b/coverage/vesselbase/ActionWithInputVessel.h.gcov.html new file mode 100644 index 0000000000..9d76181a96 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..e562cb85b7 --- /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:18820193.5 %
Date:2024-06-10 08:19:14Functions: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_i357
_ZN4PLMD10vesselbase16ActionWithVessel18readVesselKeywordsEv416
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselESt10unique_ptrINS0_6VesselESt14default_deleteIS3_EE553
_ZN4PLMD10vesselbase16ActionWithVesselC2ERKNS_13ActionOptionsE569
_ZN4PLMD10vesselbase16ActionWithVesselD2Ev569
_ZN4PLMD10vesselbase16ActionWithVessel16registerKeywordsERNS_8KeywordsE682
_ZN4PLMD10vesselbase16ActionWithVessel16needsDerivativesEv812
_ZN4PLMD10vesselbase16ActionWithVessel15resizeFunctionsEv1374
_ZN4PLMD10vesselbase16ActionWithVessel16lockContributorsEv3315
_ZN4PLMD10vesselbase16ActionWithVessel18deactivateAllTasksEv3315
_ZN4PLMD10vesselbase16ActionWithVessel20getForcesFromVesselsERSt6vectorIdSaIdEE7221
_ZN4PLMD10vesselbase16ActionWithVessel11runAllTasksEv19965
_ZN4PLMD10vesselbase16ActionWithVessel18finishComputationsERKSt6vectorIdSaIdEE22990
_ZN4PLMD10vesselbase16ActionWithVessel28doJobsRequiredBeforeTaskListEv22990
_ZN4PLMD10vesselbase16ActionWithVessel15getSizeOfBufferERj23503
_ZNK4PLMD10vesselbase16ActionWithVessel21taskIsCurrentlyActiveERKj213721
_ZN4PLMD10vesselbase16ActionWithVessel19calculateAllVesselsERKjRNS_10MultiValueES5_RSt6vectorIdSaIdEERS6_IjSaIjEE467098
_ZN4PLMD10vesselbase16ActionWithVessel13addTaskToListERKj12661273
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.cpp.func.html b/coverage/vesselbase/ActionWithVessel.cpp.func.html new file mode 100644 index 0000000000..90068cd116 --- /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:18820193.5 %
Date:2024-06-10 08:19:14Functions:202676.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel11runAllTasksEv19965
_ZN4PLMD10vesselbase16ActionWithVessel13addTaskToListERKj12661273
_ZN4PLMD10vesselbase16ActionWithVessel14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_0
_ZN4PLMD10vesselbase16ActionWithVessel15getSizeOfBufferERj23503
_ZN4PLMD10vesselbase16ActionWithVessel15resizeFunctionsEv1374
_ZN4PLMD10vesselbase16ActionWithVessel16buildDataStashesEPS1_192
_ZN4PLMD10vesselbase16ActionWithVessel16lockContributorsEv3315
_ZN4PLMD10vesselbase16ActionWithVessel16needsDerivativesEv812
_ZN4PLMD10vesselbase16ActionWithVessel16registerKeywordsERNS_8KeywordsE682
_ZN4PLMD10vesselbase16ActionWithVessel17addBridgingVesselEPS1_46
_ZN4PLMD10vesselbase16ActionWithVessel17getVesselWithNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD10vesselbase16ActionWithVessel18deactivateAllTasksEv3315
_ZN4PLMD10vesselbase16ActionWithVessel18finishComputationsERKSt6vectorIdSaIdEE22990
_ZN4PLMD10vesselbase16ActionWithVessel18readVesselKeywordsEv416
_ZN4PLMD10vesselbase16ActionWithVessel19calculateAllVesselsERKjRNS_10MultiValueES5_RSt6vectorIdSaIdEERS6_IjSaIjEE467098
_ZN4PLMD10vesselbase16ActionWithVessel20getForcesFromVesselsERSt6vectorIdSaIdEE7221
_ZN4PLMD10vesselbase16ActionWithVessel28doJobsRequiredBeforeTaskListEv22990
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_i357
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselESt10unique_ptrINS0_6VesselESt14default_deleteIS3_EE553
_ZN4PLMD10vesselbase16ActionWithVesselC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase16ActionWithVesselC2ERKNS_13ActionOptionsE569
_ZN4PLMD10vesselbase16ActionWithVesselD0Ev0
_ZN4PLMD10vesselbase16ActionWithVesselD1Ev0
_ZN4PLMD10vesselbase16ActionWithVesselD2Ev569
_ZNK4PLMD10vesselbase16ActionWithVessel21taskIsCurrentlyActiveERKj213721
_ZNK4PLMD10vesselbase16ActionWithVessel27transformBridgedDerivativesERKjRNS_10MultiValueES5_0
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.cpp.gcov.html b/coverage/vesselbase/ActionWithVessel.cpp.gcov.html new file mode 100644 index 0000000000..1e351fcf39 --- /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:18820193.5 %
Date:2024-06-10 08:19:14Functions: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         682 : void ActionWithVessel::registerKeywords(Keywords& keys) {
+      38        1364 :   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        1364 :   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        1364 :   keys.addFlag("SERIAL",false,"do the calculation in serial.  Do not use MPI");
+      45        1364 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+      46        1364 :   keys.addFlag("TIMINGS",false,"output information on the timings of the various parts of the calculation");
+      47        1364 :   keys.reserveFlag("HIGHMEM",false,"use a more memory intensive version of this collective variable");
+      48         682 :   keys.add( vesselRegister().getKeywords() );
+      49         682 : }
+      50             : 
+      51         569 : ActionWithVessel::ActionWithVessel(const ActionOptions&ao):
+      52             :   Action(ao),
+      53         569 :   serial(false),
+      54         569 :   lowmem(false),
+      55         569 :   noderiv(true),
+      56         569 :   actionIsBridged(false),
+      57         569 :   nactive_tasks(0),
+      58         569 :   dertime_can_be_off(false),
+      59         569 :   dertime(true),
+      60         569 :   contributorsAreUnlocked(false),
+      61         569 :   weightHasDerivatives(false),
+      62         569 :   mydata(NULL)
+      63             : {
+      64         569 :   maxderivatives=309; parse("MAXDERIVATIVES",maxderivatives);
+      65        1674 :   if( keywords.exists("SERIAL") ) parseFlag("SERIAL",serial);
+      66          33 :   else serial=true;
+      67         569 :   if(serial)log.printf("  doing calculation in serial\n");
+      68        1138 :   if( keywords.exists("LOWMEM") ) {
+      69        1074 :     plumed_assert( !keywords.exists("HIGHMEM") );
+      70         537 :     parseFlag("LOWMEM",lowmem);
+      71         537 :     if(lowmem) {
+      72          29 :       log.printf("  lowering memory requirements\n");
+      73          29 :       dertime_can_be_off=true;
+      74             :     }
+      75             :   }
+      76        1138 :   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         569 :   tolerance=nl_tolerance=epsilon;
+      83        1596 :   if( keywords.exists("TOL") ) parse("TOL",tolerance);
+      84         569 :   if( tolerance>epsilon) {
+      85           6 :     log.printf(" Ignoring contributions less than %f \n",tolerance);
+      86             :   }
+      87         569 :   parseFlag("TIMINGS",timers);
+      88         569 :   stopwatch.start(); stopwatch.pause();
+      89         569 : }
+      90             : 
+      91         569 : ActionWithVessel::~ActionWithVessel() {
+      92         569 :   stopwatch.start(); stopwatch.stop();
+      93         569 :   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         569 : }
+      98             : 
+      99         357 : void ActionWithVessel::addVessel( const std::string& name, const std::string& input, const int numlab ) {
+     100         357 :   VesselOptions da(name,"",numlab,input,this);
+     101         714 :   auto vv=vesselRegister().create(name,da);
+     102         357 :   FunctionVessel* fv=dynamic_cast<FunctionVessel*>(vv.get());
+     103         357 :   if( fv ) {
+     104         327 :     std::string mylabel=Vessel::transformName( name );
+     105         327 :     plumed_massert( keywords.outputComponentExists(mylabel,false), "a description of the value calculated by vessel " + name + " has not been added to the manual");
+     106             :   }
+     107         357 :   addVessel(std::move(vv));
+     108         357 : }
+     109             : 
+     110         553 : 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         553 :   if(dynamic_cast<ShortcutVessel*>(vv_ptr.get())) return;
+     116             : 
+     117         542 :   vv_ptr->checkRead();
+     118             : 
+     119         542 :   StoreDataVessel* mm=dynamic_cast<StoreDataVessel*>( vv_ptr.get() );
+     120         542 :   if( mydata && mm ) error("cannot have more than one StoreDataVessel in one action");
+     121         542 :   else if( mm ) mydata=mm;
+     122         411 :   else dertime_can_be_off=false;
+     123             : 
+     124             : // Ownership is transferred to functions
+     125         542 :   functions.emplace_back(std::move(vv_ptr));
+     126             : }
+     127             : 
+     128          46 : BridgeVessel* ActionWithVessel::addBridgingVessel( ActionWithVessel* tome ) {
+     129          92 :   VesselOptions da("","",0,"",this);
+     130          46 :   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         105 :   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    12661273 : void ActionWithVessel::addTaskToList( const unsigned& taskCode ) {
+     160    12661273 :   fullTaskList.push_back( taskCode ); taskFlags.push_back(0);
+     161    12661273 :   plumed_assert( fullTaskList.size()==taskFlags.size() );
+     162    12661273 : }
+     163             : 
+     164         416 : void ActionWithVessel::readVesselKeywords() {
+     165             :   // Set maxderivatives if it is too big
+     166         416 :   if( maxderivatives>getNumberOfDerivatives() ) maxderivatives=getNumberOfDerivatives();
+     167             : 
+     168             :   // Loop over all keywords find the vessels and create appropriate functions
+     169        9678 :   for(unsigned i=0; i<keywords.size(); ++i) {
+     170        9262 :     std::string thiskey,input; thiskey=keywords.getKeyword(i);
+     171             :     // Check if this is a key for a vessel
+     172       18524 :     if( vesselRegister().check(thiskey) ) {
+     173        5504 :       plumed_assert( keywords.style(thiskey,"vessel") );
+     174        2752 :       bool dothis=false; parseFlag(thiskey,dothis);
+     175        2752 :       if(dothis) addVessel( thiskey, input );
+     176             : 
+     177        2752 :       parse(thiskey,input);
+     178        2752 :       if(input.size()!=0) {
+     179         124 :         addVessel( thiskey, input );
+     180             :       } else {
+     181        2628 :         for(unsigned i=1;; ++i) {
+     182        2653 :           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         416 :   if( functions.size()>0 ) resizeFunctions();
+     193         416 : }
+     194             : 
+     195        1374 : void ActionWithVessel::resizeFunctions() {
+     196        3545 :   for(unsigned i=0; i<functions.size(); ++i) functions[i]->resize();
+     197        1374 : }
+     198             : 
+     199         812 : void ActionWithVessel::needsDerivatives() {
+     200             :   // Turn on the derivatives and resize
+     201         812 :   noderiv=false; resizeFunctions();
+     202             :   // Setting contributors unlocked here ensures that link cells are ignored
+     203         812 :   contributorsAreUnlocked=true; contributorsAreUnlocked=false;
+     204             :   // And turn on the derivatives in all actions on which we are dependent
+     205        1110 :   for(unsigned i=0; i<getDependencies().size(); ++i) {
+     206         298 :     ActionWithVessel* vv=dynamic_cast<ActionWithVessel*>( getDependencies()[i] );
+     207         298 :     if(vv) vv->needsDerivatives();
+     208             :   }
+     209         812 : }
+     210             : 
+     211        3315 : void ActionWithVessel::lockContributors() {
+     212        3315 :   nactive_tasks = 0;
+     213    18492694 :   for(unsigned i=0; i<fullTaskList.size(); ++i) {
+     214    18489379 :     if( taskFlags[i]>0 ) nactive_tasks++;
+     215             :   }
+     216             : 
+     217             :   unsigned n=0;
+     218        3315 :   partialTaskList.resize( nactive_tasks );
+     219        3315 :   indexOfTaskInFullList.resize( nactive_tasks );
+     220    18492694 :   for(unsigned i=0; i<fullTaskList.size(); ++i) {
+     221             :     // Deactivate sets inactive tasks to number not equal to zero
+     222    18489379 :     if( taskFlags[i]>0 ) {
+     223     5482378 :       partialTaskList[n] = fullTaskList[i];
+     224     5482378 :       indexOfTaskInFullList[n]=i;
+     225     5482378 :       n++;
+     226             :     }
+     227             :   }
+     228             :   plumed_dbg_assert( n==nactive_tasks );
+     229        8193 :   for(unsigned i=0; i<functions.size(); ++i) {
+     230        4878 :     BridgeVessel* bb = dynamic_cast<BridgeVessel*>( functions[i].get() );
+     231        4878 :     if( bb ) bb->copyTaskFlags();
+     232             :   }
+     233             :   // Resize mydata to accommodate all active tasks
+     234        3315 :   if( mydata ) mydata->resize();
+     235        3315 :   contributorsAreUnlocked=false;
+     236        3315 : }
+     237             : 
+     238        3315 : void ActionWithVessel::deactivateAllTasks() {
+     239        3315 :   contributorsAreUnlocked=true; nactive_tasks = 0;
+     240        3315 :   taskFlags.assign(taskFlags.size(),0);
+     241        3315 : }
+     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       22990 : void ActionWithVessel::doJobsRequiredBeforeTaskList() {
+     248             :   // Do any preparatory stuff for functions
+     249       58257 :   for(unsigned j=0; j<functions.size(); ++j) functions[j]->prepare();
+     250       22990 : }
+     251             : 
+     252       23503 : unsigned ActionWithVessel::getSizeOfBuffer( unsigned& bufsize ) {
+     253       59446 :   for(unsigned i=0; i<functions.size(); ++i) functions[i]->setBufferStart( bufsize );
+     254       23503 :   if( buffer.size()!=bufsize ) buffer.resize( bufsize );
+     255       23503 :   if( mydata ) {
+     256             :     unsigned dsize=mydata->getSizeOfDerivativeList();
+     257        2554 :     if( der_list.size()!=dsize ) der_list.resize( dsize );
+     258             :   }
+     259       23503 :   return bufsize;
+     260             : }
+     261             : 
+     262       19965 : void ActionWithVessel::runAllTasks() {
+     263       19965 :   plumed_massert( !contributorsAreUnlocked && functions.size()>0, "you must have a call to readVesselKeywords somewhere" );
+     264       19965 :   unsigned stride=comm.Get_size();
+     265       19965 :   unsigned rank=comm.Get_rank();
+     266       19965 :   if(serial) { stride=1; rank=0; }
+     267             : 
+     268             :   // Make sure jobs are done
+     269       19965 :   if(timers) stopwatch.start("1 Prepare Tasks");
+     270       19965 :   doJobsRequiredBeforeTaskList();
+     271       19965 :   if(timers) stopwatch.stop("1 Prepare Tasks");
+     272             : 
+     273             :   // Get number of threads for OpenMP
+     274       19965 :   unsigned nt=OpenMP::getNumThreads();
+     275       19965 :   if( nt*stride*2>nactive_tasks || !threadSafe()) nt=1;
+     276             : 
+     277             :   // Get size for buffer
+     278       19965 :   unsigned bsize=0, bufsize=getSizeOfBuffer( bsize );
+     279             :   // Clear buffer
+     280       19965 :   buffer.assign( buffer.size(), 0.0 );
+     281             :   // Switch off calculation of derivatives in main loop
+     282       19965 :   if( dertime_can_be_off ) dertime=false;
+     283             : 
+     284       19965 :   if(timers) stopwatch.start("2 Loop over tasks");
+     285       19965 :   #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       19965 :   if(timers) stopwatch.stop("2 Loop over tasks");
+     323             :   // Turn back on derivative calculation
+     324       19965 :   dertime=true;
+     325             : 
+     326       19965 :   if(timers) stopwatch.start("3 MPI gather");
+     327             :   // MPI Gather everything
+     328       19965 :   if( !serial && buffer.size()>0 ) comm.Sum( buffer );
+     329             :   // MPI Gather index stores
+     330       19965 :   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       19965 :   if(timers) stopwatch.stop("3 MPI gather");
+     336             : 
+     337       19965 :   if(timers) stopwatch.start("4 Finishing computations");
+     338       19965 :   finishComputations( buffer );
+     339       19965 :   if(timers) stopwatch.stop("4 Finishing computations");
+     340       19965 : }
+     341             : 
+     342           0 : void ActionWithVessel::transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const {
+     343           0 :   plumed_error();
+     344             : }
+     345             : 
+     346      467098 : void ActionWithVessel::calculateAllVessels( const unsigned& taskCode, MultiValue& myvals, MultiValue& bvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) {
+     347     1078808 :   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      611710 :     functions[j]->calculate( taskCode, functions[j]->transformDerivatives(taskCode, myvals, bvals), buffer, der_list );
+     351      611710 :     if( !actionIsBridged ) bvals.clearAll();
+     352             :   }
+     353      467098 :   return;
+     354             : }
+     355             : 
+     356       22990 : void ActionWithVessel::finishComputations( const std::vector<double>& buffer ) {
+     357             :   // Set the final value of the function
+     358       58257 :   for(unsigned j=0; j<functions.size(); ++j) functions[j]->finish( buffer );
+     359       22990 : }
+     360             : 
+     361        7221 : bool ActionWithVessel::getForcesFromVessels( std::vector<double>& forcesToApply ) {
+     362             : #ifndef NDEBUG
+     363             :   if( forcesToApply.size()>0 ) plumed_dbg_assert( forcesToApply.size()==getNumberOfDerivatives() );
+     364             : #endif
+     365        7221 :   if(tmpforces.size()!=forcesToApply.size() ) tmpforces.resize( forcesToApply.size() );
+     366             : 
+     367        7221 :   forcesToApply.assign( forcesToApply.size(),0.0 );
+     368             :   bool wasforced=false;
+     369       21107 :   for(unsigned i=0; i<getNumberOfVessels(); ++i) {
+     370       13886 :     if( (functions[i]->applyForce( tmpforces )) ) {
+     371             :       wasforced=true;
+     372      524255 :       for(unsigned j=0; j<forcesToApply.size(); ++j) forcesToApply[j]+=tmpforces[j];
+     373             :     }
+     374             :   }
+     375        7221 :   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.15
+
+ + + 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 0000000000..3d51b7e595 --- /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-06-10 08:19:14Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel26normalizeVectorDerivativesERNS_10MultiValueE0
_ZNK4PLMD10vesselbase16ActionWithVessel10threadSafeEv5214
_ZNK4PLMD10vesselbase16ActionWithVessel21getNumberOfQuantitiesEv196787
_ZNK4PLMD10vesselbase16ActionWithVessel28getPositionInCurrentTaskListERKj224556
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.h.func.html b/coverage/vesselbase/ActionWithVessel.h.func.html new file mode 100644 index 0000000000..40b236faf6 --- /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-06-10 08:19:14Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel10threadSafeEv5214
_ZNK4PLMD10vesselbase16ActionWithVessel15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel21getNumberOfQuantitiesEv196787
_ZNK4PLMD10vesselbase16ActionWithVessel26normalizeVectorDerivativesERNS_10MultiValueE0
_ZNK4PLMD10vesselbase16ActionWithVessel28getPositionInCurrentTaskListERKj224556
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.h.gcov.html b/coverage/vesselbase/ActionWithVessel.h.gcov.html new file mode 100644 index 0000000000..1a3d2cd319 --- /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-06-10 08:19:14Functions: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      698630 :   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    12537362 :   return functions.size();
+     213             : }
+     214             : 
+     215             : inline
+     216      196787 : unsigned ActionWithVessel::getNumberOfQuantities() const {
+     217      196787 :   return 2;
+     218             : }
+     219             : 
+     220             : inline
+     221             : Vessel* ActionWithVessel::getPntrToVessel( const unsigned& i ) {
+     222             :   plumed_dbg_assert( i<functions.size() );
+     223        2501 :   return functions[i].get();
+     224             : }
+     225             : 
+     226             : inline
+     227             : unsigned ActionWithVessel::getFullNumberOfTasks() const {
+     228    15830229 :   return fullTaskList.size();
+     229             : }
+     230             : 
+     231             : inline
+     232             : unsigned ActionWithVessel::getTaskCode( const unsigned& ii ) const {
+     233             :   plumed_dbg_assert( ii<fullTaskList.size() );
+     234     3509797 :   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      714510 :   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.15
+
+ + + 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 0000000000..0b6a3aedbd --- /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-06-10 08:19:14Functions: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_116AltMinRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeD2Ev3473
_ZN4PLMD10vesselbase6AltMin14reserveKeywordERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/AltMin.cpp.func.html b/coverage/vesselbase/AltMin.cpp.func.html new file mode 100644 index 0000000000..b6bd2492f8 --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMe6createERKNS0_13VesselOptionsE2
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeD2Ev3473
_ZN4PLMD10vesselbase6AltMin14finalTransformERKdRd5
_ZN4PLMD10vesselbase6AltMin14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase6AltMin16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD10vesselbase6AltMin16value_descriptorB5cxx11Ev2
_ZN4PLMD10vesselbase6AltMinC2ERKNS0_13VesselOptionsE2
_ZNK4PLMD10vesselbase6AltMin13calcTransformERKdRd10
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/AltMin.cpp.gcov.html b/coverage/vesselbase/AltMin.cpp.gcov.html new file mode 100644 index 0000000000..6fc76eb5dc --- /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-06-10 08:19:14Functions: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       10421 : 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        3473 : void AltMin::reserveKeyword( Keywords& keys ) {
+      48        6946 :   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        6946 :   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        3473 : }
+      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.15
+
+ + + 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 0000000000..36f4f6c0cc --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.cpp.func.html b/coverage/vesselbase/AveragingVessel.cpp.func.html new file mode 100644 index 0000000000..401ba72b6c --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.cpp.gcov.html b/coverage/vesselbase/AveragingVessel.cpp.gcov.html new file mode 100644 index 0000000000..8890f153b7 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..cd5dfe4345 --- /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-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15AveragingVessel10applyForceERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase15AveragingVessel14getDataElementERKj7999387
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.h.func.html b/coverage/vesselbase/AveragingVessel.h.func.html new file mode 100644 index 0000000000..b97f1cee6e --- /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-06-10 08:19:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15AveragingVessel10applyForceERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase15AveragingVessel14getDataElementERKj7999387
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.h.gcov.html b/coverage/vesselbase/AveragingVessel.h.gcov.html new file mode 100644 index 0000000000..39aa7b4122 --- /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-06-10 08:19:14Functions: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      361786 :   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     7999387 : double AveragingVessel::getDataElement( const unsigned& myelem ) const {
+      82             :   plumed_dbg_assert( myelem<data.size()-1 );
+      83     7999387 :   if( unormalised ) return data[1+myelem];
+      84     1851499 :   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.15
+
+ + + 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 0000000000..04782c64e9 --- /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-06-10 08:19:14Functions: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_117BetweenRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeD2Ev3473
_ZN4PLMD10vesselbase7Between14reserveKeywordERNS_8KeywordsE3473
_ZNK4PLMD10vesselbase7Between13calcTransformERKdRd8224
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Between.cpp.func.html b/coverage/vesselbase/Between.cpp.func.html new file mode 100644 index 0000000000..97e4a9957a --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMe6createERKNS0_13VesselOptionsE65
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeD2Ev3473
_ZN4PLMD10vesselbase7Between14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase7Between16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD10vesselbase7Between16value_descriptorB5cxx11Ev65
_ZN4PLMD10vesselbase7Between9getCutoffEv60
_ZN4PLMD10vesselbase7BetweenC2ERKNS0_13VesselOptionsE65
_ZNK4PLMD10vesselbase7Between13calcTransformERKdRd8224
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Between.cpp.gcov.html b/coverage/vesselbase/Between.cpp.gcov.html new file mode 100644 index 0000000000..422666286f --- /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-06-10 08:19:14Functions: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       10484 : 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        3473 : void Between::reserveKeyword( Keywords& keys ) {
+      38        6946 :   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        6946 :   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        3473 : }
+      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.15
+
+ + + 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 0000000000..4f82300509 --- /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-06-10 08:19:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12BridgeVessel11descriptionB5cxx11Ev0
_ZN4PLMD10vesselbase12BridgeVessel15setOutputActionEPNS0_16ActionWithVesselE46
_ZN4PLMD10vesselbase12BridgeVesselC2ERKNS0_13VesselOptionsE46
_ZN4PLMD10vesselbase12BridgeVessel28completeNumericalDerivativesEv65
_ZN4PLMD10vesselbase12BridgeVessel6resizeEv513
_ZN4PLMD10vesselbase12BridgeVessel10applyForceERSt6vectorIdSaIdEE795
_ZN4PLMD10vesselbase12BridgeVessel13copyTaskFlagsEv795
_ZN4PLMD10vesselbase12BridgeVessel14setBufferStartERj3025
_ZN4PLMD10vesselbase12BridgeVessel6finishERKSt6vectorIdSaIdEE3025
_ZN4PLMD10vesselbase12BridgeVessel7prepareEv3025
_ZN4PLMD10vesselbase12BridgeVessel20getTemporyMultiValueEv13042
_ZN4PLMD10vesselbase12BridgeVessel20transformDerivativesERKjRNS_10MultiValueES5_102743
_ZNK4PLMD10vesselbase12BridgeVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE102743
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.cpp.func.html b/coverage/vesselbase/BridgeVessel.cpp.func.html new file mode 100644 index 0000000000..e08356ee94 --- /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-06-10 08:19:14Functions: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
_ZN4PLMD10vesselbase12BridgeVessel6resizeEv513
_ZN4PLMD10vesselbase12BridgeVessel7prepareEv3025
_ZN4PLMD10vesselbase12BridgeVesselC2ERKNS0_13VesselOptionsE46
_ZNK4PLMD10vesselbase12BridgeVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE102743
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.cpp.gcov.html b/coverage/vesselbase/BridgeVessel.cpp.gcov.html new file mode 100644 index 0000000000..d2a6ab0fcf --- /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-06-10 08:19:14Functions: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         513 : void BridgeVessel::resize() {
+      41         513 :   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         513 :   if( myOutputAction->mydata ) {
+      49             :     unsigned dsize=(myOutputAction->mydata)->getSizeOfDerivativeList();
+      50          12 :     if( getAction()->der_list.size()!=dsize ) getAction()->der_list.resize( dsize );
+      51             :   }
+      52         513 :   unsigned tmp=0; resizeBuffer( myOutputAction->getSizeOfBuffer( tmp ) );
+      53         513 : }
+      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.15
+
+ + + 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 0000000000..106ff118f2 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.h.func.html b/coverage/vesselbase/BridgeVessel.h.func.html new file mode 100644 index 0000000000..e78cb81039 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.h.gcov.html b/coverage/vesselbase/BridgeVessel.h.gcov.html new file mode 100644 index 0000000000..cc3a0bf1b0 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..6be80f9a4b --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase14FunctionVessel13calcTransformERKdRd0
_ZN4PLMD10vesselbase14FunctionVessel16registerKeywordsERNS_8KeywordsE327
_ZN4PLMD10vesselbase14FunctionVesselC2ERKNS0_13VesselOptionsE327
_ZN4PLMD10vesselbase14FunctionVessel6resizeEv910
_ZN4PLMD10vesselbase14FunctionVessel14finalTransformERKdRd22776
_ZN4PLMD10vesselbase14FunctionVessel6finishERKSt6vectorIdSaIdEE26614
_ZNK4PLMD10vesselbase14FunctionVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE244640
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.cpp.func.html b/coverage/vesselbase/FunctionVessel.cpp.func.html new file mode 100644 index 0000000000..587d942f58 --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14FunctionVessel14finalTransformERKdRd22776
_ZN4PLMD10vesselbase14FunctionVessel16registerKeywordsERNS_8KeywordsE327
_ZN4PLMD10vesselbase14FunctionVessel6finishERKSt6vectorIdSaIdEE26614
_ZN4PLMD10vesselbase14FunctionVessel6resizeEv910
_ZN4PLMD10vesselbase14FunctionVesselC2ERKNS0_13VesselOptionsE327
_ZNK4PLMD10vesselbase14FunctionVessel13calcTransformERKdRd0
_ZNK4PLMD10vesselbase14FunctionVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE244640
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.cpp.gcov.html b/coverage/vesselbase/FunctionVessel.cpp.gcov.html new file mode 100644 index 0000000000..f64e968e91 --- /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-06-10 08:19:14Functions: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         327 : void FunctionVessel::registerKeywords( Keywords& keys ) {
+      29         327 :   ValueVessel::registerKeywords( keys );
+      30         327 : }
+      31             : 
+      32         327 : FunctionVessel::FunctionVessel( const VesselOptions& da ):
+      33             :   ValueVessel(da),
+      34         327 :   norm(false),
+      35         327 :   usetol(false)
+      36             : {
+      37         327 :   diffweight=getAction()->weightHasDerivatives;
+      38         327 : }
+      39             : 
+      40         910 : void FunctionVessel::resize() {
+      41         910 :   if( getAction()->derivativesAreRequired() ) {
+      42         540 :     unsigned nderivatives=getAction()->getNumberOfDerivatives();
+      43         540 :     getFinalValue()->resizeDerivatives( nderivatives );
+      44         540 :     resizeBuffer( (1+nderivatives)*2 );
+      45         540 :     diffweight=getAction()->weightHasDerivatives;
+      46             :   } else {
+      47             :     resizeBuffer(2);
+      48         370 :     diffweight=false;  // Don't need to worry about differentiable weights if no derivatives
+      49             :   }
+      50         910 : }
+      51             : 
+      52      244640 : void FunctionVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      53      244640 :   unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
+      54             :   double weight=myvals.get(0);
+      55             :   plumed_dbg_assert( weight>=getTolerance() );
+      56             : 
+      57             :   // This deals with the value
+      58      244640 :   double dval, f=calcTransform( myvals.get(mycomp), dval );
+      59             : 
+      60      244640 :   if( norm ) {
+      61       82812 :     if( usetol && weight<getTolerance() ) return;
+      62       82812 :     buffer[bufstart+1+nderivatives] += weight;
+      63       82812 :     if( getAction()->derivativesAreRequired() && diffweight ) myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer );
+      64             :   }
+      65             : 
+      66      244640 :   double contr=weight*f;
+      67      244640 :   if( usetol && contr<getTolerance() ) return;
+      68      239718 :   buffer[bufstart] += contr;
+      69             : 
+      70      239718 :   if( diffweight ) myvals.chainRule( 0, 0, 1, 0, f, bufstart, buffer );
+      71      239718 :   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       26614 : void FunctionVessel::finish( const std::vector<double>& buffer ) {
+      81       26614 :   unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
+      82       26614 :   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       26614 :   } else if( norm ) {
+      89        1226 :     double dv, val=finalTransform( buffer[bufstart], dv), weight=buffer[bufstart+1+nderivatives];
+      90        1226 :     getFinalValue()->set( val / weight );
+      91      156782 :     for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, buffer[bufstart+1+i]/weight );
+      92             :   } else {
+      93       20274 :     double dv, val=finalTransform( buffer[bufstart], dv); getFinalValue()->set( val );
+      94     1530086 :     for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, dv*buffer[bufstart+1+i] );
+      95             :   }
+      96       26614 : }
+      97             : 
+      98       22776 : double FunctionVessel::finalTransform( const double& val, double& dv ) {
+      99       22776 :   dv=1.0; return val;
+     100             : }
+     101             : 
+     102             : }
+     103             : }
+     104             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..8cc7198c65 --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.h.func.html b/coverage/vesselbase/FunctionVessel.h.func.html new file mode 100644 index 0000000000..876fefa08c --- /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-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.h.gcov.html b/coverage/vesselbase/FunctionVessel.h.gcov.html new file mode 100644 index 0000000000..ab36e42948 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..34d51461cc --- /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-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMe6createERKNS0_13VesselOptionsE5
_ZN4PLMD10vesselbase7Highest16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD10vesselbase7Highest16value_descriptorB5cxx11Ev5
_ZN4PLMD10vesselbase7HighestC2ERKNS0_13VesselOptionsE5
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeD2Ev3473
_ZN4PLMD10vesselbase7Highest14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase7Highest7compareERKdS3_4047
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Highest.cpp.func.html b/coverage/vesselbase/Highest.cpp.func.html new file mode 100644 index 0000000000..2901c9dfae --- /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-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMe6createERKNS0_13VesselOptionsE5
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeD2Ev3473
_ZN4PLMD10vesselbase7Highest14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase7Highest16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD10vesselbase7Highest16value_descriptorB5cxx11Ev5
_ZN4PLMD10vesselbase7Highest7compareERKdS3_4047
_ZN4PLMD10vesselbase7HighestC2ERKNS0_13VesselOptionsE5
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Highest.cpp.gcov.html b/coverage/vesselbase/Highest.cpp.gcov.html new file mode 100644 index 0000000000..67549eb4d6 --- /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-06-10 08:19:14Functions: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       10424 : PLUMED_REGISTER_VESSEL(Highest,"HIGHEST")
+      38             : 
+      39           5 : void Highest::registerKeywords( Keywords& keys ) {
+      40           5 :   OrderingVessel::registerKeywords( keys );
+      41           5 : }
+      42             : 
+      43        3473 : void Highest::reserveKeyword( Keywords& keys ) {
+      44        6946 :   keys.reserve("vessel","HIGHEST","this flag allows you to recover the highest of these variables.");
+      45        6946 :   keys.addOutputComponent("highest","HIGHEST","the highest of the quantities calculated by this action");
+      46        3473 : }
+      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.15
+
+ + + 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 0000000000..60c0e4275c --- /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-06-10 08:19:14Functions: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_119HistogramRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeD2Ev3473
_ZN4PLMD10vesselbase9Histogram14reserveKeywordERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Histogram.cpp.func.html b/coverage/vesselbase/Histogram.cpp.func.html new file mode 100644 index 0000000000..22a9b671fe --- /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-06-10 08:19:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMe6createERKNS0_13VesselOptionsE11
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeD2Ev3473
_ZN4PLMD10vesselbase9Histogram14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase9Histogram16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD10vesselbase9HistogramC2ERKNS0_13VesselOptionsE11
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Histogram.cpp.gcov.html b/coverage/vesselbase/Histogram.cpp.gcov.html new file mode 100644 index 0000000000..063d8dcf94 --- /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-06-10 08:19:14Functions: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       10430 : 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        3473 : void Histogram::reserveKeyword( Keywords& keys ) {
+      47        6946 :   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        3473 : }
+      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          75 :   for(unsigned i=0; i<bins.size(); ++i) addVessel("BETWEEN",bins[i] + normstr);
+      60          22 : }
+      61             : 
+      62             : }
+      63             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7fab39a49d --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase8LessThan9getCutoffEv16
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMe6createERKNS0_13VesselOptionsE59
_ZN4PLMD10vesselbase8LessThan16registerKeywordsERNS_8KeywordsE59
_ZN4PLMD10vesselbase8LessThan16value_descriptorB5cxx11Ev59
_ZN4PLMD10vesselbase8LessThanC2ERKNS0_13VesselOptionsE59
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeD2Ev3473
_ZN4PLMD10vesselbase8LessThan14reserveKeywordERNS_8KeywordsE3473
_ZNK4PLMD10vesselbase8LessThan13calcTransformERKdRd57355
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/LessThan.cpp.func.html b/coverage/vesselbase/LessThan.cpp.func.html new file mode 100644 index 0000000000..b3eedf80a2 --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMe6createERKNS0_13VesselOptionsE59
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeD2Ev3473
_ZN4PLMD10vesselbase8LessThan14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase8LessThan16registerKeywordsERNS_8KeywordsE59
_ZN4PLMD10vesselbase8LessThan16value_descriptorB5cxx11Ev59
_ZN4PLMD10vesselbase8LessThan9getCutoffEv16
_ZN4PLMD10vesselbase8LessThanC2ERKNS0_13VesselOptionsE59
_ZNK4PLMD10vesselbase8LessThan13calcTransformERKdRd57355
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/LessThan.cpp.gcov.html b/coverage/vesselbase/LessThan.cpp.gcov.html new file mode 100644 index 0000000000..18a333c319 --- /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-06-10 08:19:14Functions: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       10478 : PLUMED_REGISTER_VESSEL(LessThan,"LESS_THAN")
+      29             : 
+      30          59 : void LessThan::registerKeywords( Keywords& keys ) {
+      31          59 :   FunctionVessel::registerKeywords( keys );
+      32          59 :   SwitchingFunction::registerKeywords( keys );
+      33          59 : }
+      34             : 
+      35        3473 : void LessThan::reserveKeyword( Keywords& keys ) {
+      36        6946 :   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        6946 :   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        3473 : }
+      43             : 
+      44          59 : LessThan::LessThan( const VesselOptions& da ) :
+      45          59 :   FunctionVessel(da)
+      46             : {
+      47          59 :   usetol=true;
+      48          59 :   if( getAction()->isPeriodic() ) error("LESS_THAN is not a meaningful option for periodic variables");
+      49         118 :   std::string errormsg; sf.set( getAllInput(), errormsg );
+      50          59 :   if( errormsg.size()!=0 ) error( errormsg );
+      51          59 : }
+      52             : 
+      53          59 : std::string LessThan::value_descriptor() {
+      54         118 :   return "the number of values less than " + sf.description();
+      55             : }
+      56             : 
+      57       57355 : double LessThan::calcTransform( const double& val, double& dv ) const {
+      58       57355 :   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.15
+
+ + + 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 0000000000..59126300b7 --- /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-06-10 08:19:14Functions: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_116LowestRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeD2Ev3473
_ZN4PLMD10vesselbase6Lowest14reserveKeywordERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Lowest.cpp.func.html b/coverage/vesselbase/Lowest.cpp.func.html new file mode 100644 index 0000000000..f996bc837b --- /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-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeD2Ev3473
_ZN4PLMD10vesselbase6Lowest14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase6Lowest16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase6Lowest16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase6Lowest7compareERKdS3_68
_ZN4PLMD10vesselbase6LowestC2ERKNS0_13VesselOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Lowest.cpp.gcov.html b/coverage/vesselbase/Lowest.cpp.gcov.html new file mode 100644 index 0000000000..3e650a0637 --- /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-06-10 08:19:14Functions: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       10422 : PLUMED_REGISTER_VESSEL(Lowest,"LOWEST")
+      38             : 
+      39           3 : void Lowest::registerKeywords( Keywords& keys ) {
+      40           3 :   OrderingVessel::registerKeywords( keys );
+      41           3 : }
+      42             : 
+      43        3473 : void Lowest::reserveKeyword( Keywords& keys ) {
+      44        6946 :   keys.reserve("vessel","LOWEST","this flag allows you to recover the lowest of these variables.");
+      45        6946 :   keys.addOutputComponent("lowest","LOWEST","the lowest of the quantities calculated by this action");
+      46        3473 : }
+      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.15
+
+ + + 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 0000000000..2abd5d1dca --- /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-06-10 08:19:14Functions: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_113MaxRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeD2Ev3473
_ZN4PLMD10vesselbase3Max14reserveKeywordERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Max.cpp.func.html b/coverage/vesselbase/Max.cpp.func.html new file mode 100644 index 0000000000..5dbb925986 --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeD2Ev3473
_ZN4PLMD10vesselbase3Max14finalTransformERKdRd6
_ZN4PLMD10vesselbase3Max14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase3Max16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase3Max16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase3MaxC2ERKNS0_13VesselOptionsE3
_ZNK4PLMD10vesselbase3Max13calcTransformERKdRd13
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Max.cpp.gcov.html b/coverage/vesselbase/Max.cpp.gcov.html new file mode 100644 index 0000000000..1d2a8dfe89 --- /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-06-10 08:19:14Functions: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       10422 : 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        3473 : void Max::reserveKeyword( Keywords& keys ) {
+      49        6946 :   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        6946 :   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        3473 : }
+      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.15
+
+ + + 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 0000000000..80bccaa75e --- /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-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMe6createERKNS0_13VesselOptionsE83
_ZN4PLMD10vesselbase4Mean16registerKeywordsERNS_8KeywordsE83
_ZN4PLMD10vesselbase4Mean16value_descriptorB5cxx11Ev83
_ZN4PLMD10vesselbase4MeanC2ERKNS0_13VesselOptionsE83
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeD2Ev3473
_ZN4PLMD10vesselbase4Mean14reserveKeywordERNS_8KeywordsE3473
_ZNK4PLMD10vesselbase4Mean13calcTransformERKdRd80103
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Mean.cpp.func.html b/coverage/vesselbase/Mean.cpp.func.html new file mode 100644 index 0000000000..4412211c8f --- /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-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMe6createERKNS0_13VesselOptionsE83
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeD2Ev3473
_ZN4PLMD10vesselbase4Mean14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase4Mean16registerKeywordsERNS_8KeywordsE83
_ZN4PLMD10vesselbase4Mean16value_descriptorB5cxx11Ev83
_ZN4PLMD10vesselbase4MeanC2ERKNS0_13VesselOptionsE83
_ZNK4PLMD10vesselbase4Mean13calcTransformERKdRd80103
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Mean.cpp.gcov.html b/coverage/vesselbase/Mean.cpp.gcov.html new file mode 100644 index 0000000000..916aea050f --- /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-06-10 08:19:14Functions: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       10502 : PLUMED_REGISTER_VESSEL(Mean,"MEAN")
+      39             : 
+      40          83 : void Mean::registerKeywords( Keywords& keys ) {
+      41          83 :   FunctionVessel::registerKeywords(keys);
+      42          83 : }
+      43             : 
+      44        3473 : void Mean::reserveKeyword( Keywords& keys ) {
+      45        6946 :   keys.reserve("vessel","MEAN","take the mean of these variables.");
+      46        6946 :   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        3473 : }
+      49             : 
+      50          83 : Mean::Mean( const vesselbase::VesselOptions& da ) :
+      51          83 :   FunctionVessel(da)
+      52             : {
+      53          83 :   if( getAction()->isPeriodic() ) error("MEAN cannot be used with periodic variables");
+      54          83 :   norm=true;   // Makes sure we calculate the average
+      55          83 : }
+      56             : 
+      57          83 : std::string Mean::value_descriptor() {
+      58          83 :   return "the mean value";
+      59             : }
+      60             : 
+      61       80103 : double Mean::calcTransform( const double& val, double& dv ) const {
+      62       80103 :   dv=1.0; return val;
+      63             : }
+      64             : 
+      65             : }
+      66             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..7f2f9c07b7 --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMe6createERKNS0_13VesselOptionsE2
_ZN4PLMD10vesselbase3Min16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD10vesselbase3Min16value_descriptorB5cxx11Ev2
_ZN4PLMD10vesselbase3MinC2ERKNS0_13VesselOptionsE2
_ZN4PLMD10vesselbase3Min14finalTransformERKdRd5
_ZNK4PLMD10vesselbase3Min13calcTransformERKdRd10
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeD2Ev3473
_ZN4PLMD10vesselbase3Min14reserveKeywordERNS_8KeywordsE3473
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Min.cpp.func.html b/coverage/vesselbase/Min.cpp.func.html new file mode 100644 index 0000000000..90248453fe --- /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-06-10 08:19:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMe6createERKNS0_13VesselOptionsE2
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeD2Ev3473
_ZN4PLMD10vesselbase3Min14finalTransformERKdRd5
_ZN4PLMD10vesselbase3Min14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase3Min16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD10vesselbase3Min16value_descriptorB5cxx11Ev2
_ZN4PLMD10vesselbase3MinC2ERKNS0_13VesselOptionsE2
_ZNK4PLMD10vesselbase3Min13calcTransformERKdRd10
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Min.cpp.gcov.html b/coverage/vesselbase/Min.cpp.gcov.html new file mode 100644 index 0000000000..bd897c2169 --- /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-06-10 08:19:14Functions: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       10421 : PLUMED_REGISTER_VESSEL(Min,"MIN")
+      42             : 
+      43           2 : void Min::registerKeywords( Keywords& keys ) {
+      44           2 :   FunctionVessel::registerKeywords( keys );
+      45           4 :   keys.add("compulsory","BETA","the value of beta for the equation in the manual");
+      46           2 : }
+      47             : 
+      48        3473 : void Min::reserveKeyword( Keywords& keys ) {
+      49        6946 :   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        6946 :   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        3473 : }
+      56             : 
+      57           2 : Min::Min( const VesselOptions& da ) :
+      58           2 :   FunctionVessel(da)
+      59             : {
+      60           2 :   if( getAction()->isPeriodic() ) error("min is not a meaningful option for periodic variables");
+      61           2 :   parse("BETA",beta);
+      62             : 
+      63           2 :   if( diffweight ) error("can't calculate min if weight is differentiable");
+      64           2 : }
+      65             : 
+      66           2 : std::string Min::value_descriptor() {
+      67           2 :   std::string str_beta; Tools::convert( beta, str_beta );
+      68           4 :   return "the minimum value. Beta is equal to " + str_beta;
+      69             : }
+      70             : 
+      71          10 : double Min::calcTransform( const double& val, double& dv ) const {
+      72          10 :   double f = exp(beta/val); dv=f/(val*val);
+      73          10 :   return f;
+      74             : }
+      75             : 
+      76           5 : double Min::finalTransform( const double& val, double& dv ) {
+      77           5 :   double dist=beta/std::log( val );
+      78           5 :   dv = dist*dist/val; return dist;
+      79             : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..47da3e8dee --- /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-06-10 08:19:14Functions: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_117MomentsRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeD2Ev3473
_ZN4PLMD10vesselbase7Moments14reserveKeywordERNS_8KeywordsE3473
_ZNK4PLMD10vesselbase7Moments9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE6936
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Moments.cpp.func.html b/coverage/vesselbase/Moments.cpp.func.html new file mode 100644 index 0000000000..27ec5e3b22 --- /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-06-10 08:19:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMe6createERKNS0_13VesselOptionsE8
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeD2Ev3473
_ZN4PLMD10vesselbase7Moments10applyForceERSt6vectorIdSaIdEE432
_ZN4PLMD10vesselbase7Moments11descriptionB5cxx11Ev8
_ZN4PLMD10vesselbase7Moments14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase7Moments16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD10vesselbase7Moments6finishERKSt6vectorIdSaIdEE822
_ZN4PLMD10vesselbase7Moments6resizeEv28
_ZN4PLMD10vesselbase7MomentsC2ERKNS0_13VesselOptionsE8
_ZNK4PLMD10vesselbase7Moments9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE6936
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Moments.cpp.gcov.html b/coverage/vesselbase/Moments.cpp.gcov.html new file mode 100644 index 0000000000..86eec393bf --- /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-06-10 08:19:14Functions: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       10427 : 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        3473 : void Moments::reserveKeyword( Keywords& keys ) {
+      61        6946 :   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        6946 :   keys.reset_style("MOMENTS","vessel");
+      68        6946 :   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        3473 : }
+      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.15
+
+ + + 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 0000000000..dfa85821d1 --- /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-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMe6createERKNS0_13VesselOptionsE31
_ZN4PLMD10vesselbase8MoreThan16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD10vesselbase8MoreThan16value_descriptorB5cxx11Ev31
_ZN4PLMD10vesselbase8MoreThanC2ERKNS0_13VesselOptionsE31
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeD2Ev3473
_ZN4PLMD10vesselbase8MoreThan14reserveKeywordERNS_8KeywordsE3473
_ZNK4PLMD10vesselbase8MoreThan13calcTransformERKdRd18916
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/MoreThan.cpp.func.html b/coverage/vesselbase/MoreThan.cpp.func.html new file mode 100644 index 0000000000..785de874b5 --- /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-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMe6createERKNS0_13VesselOptionsE31
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeD2Ev3473
_ZN4PLMD10vesselbase8MoreThan14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase8MoreThan16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD10vesselbase8MoreThan16value_descriptorB5cxx11Ev31
_ZN4PLMD10vesselbase8MoreThanC2ERKNS0_13VesselOptionsE31
_ZNK4PLMD10vesselbase8MoreThan13calcTransformERKdRd18916
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/MoreThan.cpp.gcov.html b/coverage/vesselbase/MoreThan.cpp.gcov.html new file mode 100644 index 0000000000..1b34804068 --- /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-06-10 08:19:14Functions: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       10450 : PLUMED_REGISTER_VESSEL(MoreThan,"MORE_THAN")
+      43             : 
+      44          31 : void MoreThan::registerKeywords( Keywords& keys ) {
+      45          31 :   FunctionVessel::registerKeywords( keys );
+      46          31 :   SwitchingFunction::registerKeywords( keys );
+      47          31 : }
+      48             : 
+      49        3473 : void MoreThan::reserveKeyword( Keywords& keys ) {
+      50        6946 :   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        6946 :   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        3473 : }
+      57             : 
+      58          31 : MoreThan::MoreThan( const VesselOptions& da ) :
+      59          31 :   FunctionVessel(da)
+      60             : {
+      61          31 :   usetol=true;
+      62          31 :   if( getAction()->isPeriodic() ) error("more than is not a meaningful option for periodic variables");
+      63          62 :   std::string errormsg; sf.set( getAllInput(), errormsg );
+      64          31 :   if( errormsg.size()!=0 ) error( errormsg );
+      65          31 : }
+      66             : 
+      67          31 : std::string MoreThan::value_descriptor() {
+      68          62 :   return "the number of values more than " + sf.description();
+      69             : }
+      70             : 
+      71       18916 : double MoreThan::calcTransform( const double& val, double& dv ) const {
+      72       18916 :   double f = 1.0 - sf.calculate(val, dv); dv*=-val; return f;
+      73             : }
+      74             : 
+      75             : }
+      76             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..88674d8239 --- /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:262796.3 %
Date:2024-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14OrderingVessel16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD10vesselbase14OrderingVesselC2ERKNS0_13VesselOptionsE8
_ZN4PLMD10vesselbase14OrderingVessel6finishERKSt6vectorIdSaIdEE19
_ZN4PLMD10vesselbase14OrderingVessel6resizeEv34
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.cpp.func.html b/coverage/vesselbase/OrderingVessel.cpp.func.html new file mode 100644 index 0000000000..891f513f34 --- /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:262796.3 %
Date:2024-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14OrderingVessel16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD10vesselbase14OrderingVessel6finishERKSt6vectorIdSaIdEE19
_ZN4PLMD10vesselbase14OrderingVessel6resizeEv34
_ZN4PLMD10vesselbase14OrderingVesselC2ERKNS0_13VesselOptionsE8
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.cpp.gcov.html b/coverage/vesselbase/OrderingVessel.cpp.gcov.html new file mode 100644 index 0000000000..932ad931e4 --- /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:262796.3 %
Date:2024-06-10 08:19:14Functions: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             :   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.15
+
+ + + 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 0000000000..ef7b014bba --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase14OrderingVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE2118
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.h.func.html b/coverage/vesselbase/OrderingVessel.h.func.html new file mode 100644 index 0000000000..94edd7b8b1 --- /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-06-10 08:19:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase14OrderingVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE2118
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.h.gcov.html b/coverage/vesselbase/OrderingVessel.h.gcov.html new file mode 100644 index 0000000000..f79200f52e --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..9c2580a398 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.cpp.func.html b/coverage/vesselbase/ShortcutVessel.cpp.func.html new file mode 100644 index 0000000000..578263a91c --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.cpp.gcov.html b/coverage/vesselbase/ShortcutVessel.cpp.gcov.html new file mode 100644 index 0000000000..89968edd57 --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..fb8af3a27a --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.h.func.html b/coverage/vesselbase/ShortcutVessel.h.func.html new file mode 100644 index 0000000000..878bdadef6 --- /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-06-10 08:19:14Functions: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.15
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.h.gcov.html b/coverage/vesselbase/ShortcutVessel.h.gcov.html new file mode 100644 index 0000000000..c19ce9f38d --- /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-06-10 08:19:14Functions: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.15
+
+ + + 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 0000000000..4f82cf07fe --- /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-06-10 08:19:14Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15StoreDataVessel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD10vesselbase15StoreDataVessel17addActionThatUsesEPNS0_16ActionWithVesselE127
_ZN4PLMD10vesselbase15StoreDataVesselC2ERKNS0_13VesselOptionsE131
_ZN4PLMD10vesselbase15StoreDataVessel24resizeTemporyMultiValuesERKj143
_ZN4PLMD10vesselbase15StoreDataVessel27setActiveValsAndDerivativesERKSt6vectorIjSaIjEE690
_ZN4PLMD10vesselbase15StoreDataVessel6resizeEv1643
_ZN4PLMD10vesselbase15StoreDataVessel6finishERKSt6vectorIdSaIdEE2542
_ZNK4PLMD10vesselbase15StoreDataVessel16storeDerivativesERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE5321
_ZN4PLMD10vesselbase15StoreDataVessel20getTemporyMultiValueERKj55063
_ZNK4PLMD10vesselbase15StoreDataVessel11storeValuesERKjRNS_10MultiValueERSt6vectorIdSaIdEE148022
_ZNK4PLMD10vesselbase15StoreDataVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE148022
_ZN4PLMD10vesselbase15StoreDataVessel19retrieveDerivativesERKjRKbRNS_10MultiValueE157983
_ZNK4PLMD10vesselbase15StoreDataVessel23retrieveWeightWithIndexERKj330385
_ZNK4PLMD10vesselbase15StoreDataVessel22retrieveValueWithIndexERKjRKbRSt6vectorIdSaIdEE1148018
_ZNK4PLMD10vesselbase15StoreDataVessel23retrieveSequentialValueERKjRKbRSt6vectorIdSaIdEE1609805
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.cpp.func.html b/coverage/vesselbase/StoreDataVessel.cpp.func.html new file mode 100644 index 0000000000..bffd060659 --- /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-06-10 08:19:14Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15StoreDataVessel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD10vesselbase15StoreDataVessel17addActionThatUsesEPNS0_16ActionWithVesselE127
_ZN4PLMD10vesselbase15StoreDataVessel19retrieveDerivativesERKjRKbRNS_10MultiValueE157983
_ZN4PLMD10vesselbase15StoreDataVessel20getTemporyMultiValueERKj55063
_ZN4PLMD10vesselbase15StoreDataVessel24resizeTemporyMultiValuesERKj143
_ZN4PLMD10vesselbase15StoreDataVessel27setActiveValsAndDerivativesERKSt6vectorIjSaIjEE690
_ZN4PLMD10vesselbase15StoreDataVessel6finishERKSt6vectorIdSaIdEE2542
_ZN4PLMD10vesselbase15StoreDataVessel6resizeEv1643
_ZN4PLMD10vesselbase15StoreDataVesselC2ERKNS0_13VesselOptionsE131
_ZNK4PLMD10vesselbase15StoreDataVessel11storeValuesERKjRNS_10MultiValueERSt6vectorIdSaIdEE148022
_ZNK4PLMD10vesselbase15StoreDataVessel16storeDerivativesERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE5321
_ZNK4PLMD10vesselbase15StoreDataVessel22retrieveValueWithIndexERKjRKbRSt6vectorIdSaIdEE1148018
_ZNK4PLMD10vesselbase15StoreDataVessel23retrieveSequentialValueERKjRKbRSt6vectorIdSaIdEE1609805
_ZNK4PLMD10vesselbase15StoreDataVessel23retrieveWeightWithIndexERKj330385
_ZNK4PLMD10vesselbase15StoreDataVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE148022
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.cpp.gcov.html b/coverage/vesselbase/StoreDataVessel.cpp.gcov.html new file mode 100644 index 0000000000..f2918a51c9 --- /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-06-10 08:19:14Functions: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        1643 : void StoreDataVessel::resize() {
+      47        1643 :   if( getAction()->lowmem || !getAction()->derivativesAreRequired() ) {
+      48        1066 :     nspace = 1;
+      49        1066 :     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        1643 :   vecsize=getAction()->getNumberOfQuantities();
+      58             :   plumed_dbg_assert( vecsize>0 );
+      59        1643 :   resizeBuffer( getNumberOfStoredValues()*vecsize*nspace );
+      60        1643 :   local_buffer.resize( getNumberOfStoredValues()*vecsize*nspace );
+      61        1643 : }
+      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     1609805 : void StoreDataVessel::retrieveSequentialValue( const unsigned& jelem, const bool& normed, std::vector<double>& values ) const {
+     104             :   plumed_dbg_assert( values.size()==vecsize );
+     105     1609805 :   unsigned ibuf = jelem * vecsize * nspace;
+     106    11217468 :   for(unsigned i=0; i<vecsize; ++i) { values[i]=local_buffer[ibuf]; ibuf+=nspace; }
+     107     1609805 :   if( normed && values.size()>2 ) getAction()->normalizeVector( values );
+     108     1609805 : }
+     109             : 
+     110     1148018 : void StoreDataVessel::retrieveValueWithIndex( const unsigned& myelem, const bool& normed, std::vector<double>& values ) const {
+     111             :   plumed_dbg_assert( values.size()==vecsize );
+     112     1148018 :   unsigned jelem = getStoreIndex( myelem );
+     113     1148018 :   retrieveSequentialValue( jelem, normed, values );
+     114     1148018 : }
+     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      157983 : void StoreDataVessel::retrieveDerivatives( const unsigned& myelem, const bool& normed, MultiValue& myvals ) {
+     122             :   plumed_dbg_assert( myvals.getNumberOfValues()==vecsize && myvals.getNumberOfDerivatives()==getAction()->getNumberOfDerivatives() );
+     123             : 
+     124      157983 :   myvals.clearAll();
+     125      157983 :   if( getAction()->lowmem ) {
+     126      101678 :     recalculateStoredQuantity( myelem, myvals );
+     127      101678 :     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      157983 : }
+     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       55063 : MultiValue& StoreDataVessel::getTemporyMultiValue( const unsigned& ind ) {
+     175       55063 :   plumed_dbg_assert( ind<my_tmp_vals.size() ); return my_tmp_vals[ind];
+     176             : }
+     177             : 
+     178             : }
+     179             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..b2e0c67d27 --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15StoreDataVessel15activateIndicesEPNS0_16ActionWithVesselE0
_ZN4PLMD10vesselbase15StoreDataVessel11descriptionB5cxx11Ev128
_ZN4PLMD10vesselbase15StoreDataVessel10applyForceERSt6vectorIdSaIdEE958
_ZNK4PLMD10vesselbase15StoreDataVessel19storedValueIsActiveERKj65536
_ZN4PLMD10vesselbase15StoreDataVessel25recalculateStoredQuantityERKjRNS_10MultiValueE101678
_ZNK4PLMD10vesselbase15StoreDataVessel23getNumberOfStoredValuesEv632197
_ZNK4PLMD10vesselbase15StoreDataVessel13getStoreIndexERKj1557091
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.h.func.html b/coverage/vesselbase/StoreDataVessel.h.func.html new file mode 100644 index 0000000000..532d13b76d --- /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-06-10 08:19:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15StoreDataVessel10applyForceERSt6vectorIdSaIdEE958
_ZN4PLMD10vesselbase15StoreDataVessel11descriptionB5cxx11Ev128
_ZN4PLMD10vesselbase15StoreDataVessel15activateIndicesEPNS0_16ActionWithVesselE0
_ZN4PLMD10vesselbase15StoreDataVessel25recalculateStoredQuantityERKjRNS_10MultiValueE101678
_ZNK4PLMD10vesselbase15StoreDataVessel13getStoreIndexERKj1557091
_ZNK4PLMD10vesselbase15StoreDataVessel19storedValueIsActiveERKj65536
_ZNK4PLMD10vesselbase15StoreDataVessel23getNumberOfStoredValuesEv632197
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.h.gcov.html b/coverage/vesselbase/StoreDataVessel.h.gcov.html new file mode 100644 index 0000000000..9921ad1147 --- /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-06-10 08:19:14Functions: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      632197 : unsigned StoreDataVessel::getNumberOfStoredValues() const {
+     167      632197 :   return getAction()->nactive_tasks;
+     168             : }
+     169             : 
+     170             : inline
+     171     1557091 : unsigned StoreDataVessel::getStoreIndex( const unsigned& ind ) const {
+     172     1557091 :   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      101678 : void StoreDataVessel::recalculateStoredQuantity( const unsigned& myelem, MultiValue& myvals ) {
+     193      101678 :   getAction()->performTask( myelem, getAction()->getTaskCode(myelem), myvals );
+     194      101678 : }
+     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.15
+
+ + + 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 0000000000..a12a5edfc3 --- /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-06-10 08:19:14Functions: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_113SumRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeD2Ev3473
_ZN4PLMD10vesselbase3Sum14reserveKeywordERNS_8KeywordsE3473
_ZNK4PLMD10vesselbase3Sum13calcTransformERKdRd60444
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Sum.cpp.func.html b/coverage/vesselbase/Sum.cpp.func.html new file mode 100644 index 0000000000..d42dfc2263 --- /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-06-10 08:19:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMe6createERKNS0_13VesselOptionsE57
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeC2Ev3473
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeD2Ev3473
_ZN4PLMD10vesselbase3Sum14reserveKeywordERNS_8KeywordsE3473
_ZN4PLMD10vesselbase3Sum16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD10vesselbase3Sum16value_descriptorB5cxx11Ev57
_ZN4PLMD10vesselbase3SumC2ERKNS0_13VesselOptionsE57
_ZNK4PLMD10vesselbase3Sum13calcTransformERKdRd60444
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Sum.cpp.gcov.html b/coverage/vesselbase/Sum.cpp.gcov.html new file mode 100644 index 0000000000..0ff2c17fe6 --- /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-06-10 08:19:14Functions: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       10476 : PLUMED_REGISTER_VESSEL(Sum,"SUM")
+      38             : 
+      39          57 : void Sum::registerKeywords( Keywords& keys ) {
+      40          57 :   FunctionVessel::registerKeywords( keys );
+      41          57 : }
+      42             : 
+      43        3473 : void Sum::reserveKeyword( Keywords& keys ) {
+      44        6946 :   keys.reserve("vessel","SUM","calculate the sum of all the quantities.");
+      45        6946 :   keys.addOutputComponent("sum","SUM","the sum of values");
+      46        3473 : }
+      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.15
+
+ + + 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 0000000000..9ef32784c4 --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase11ValueVessel11descriptionB5cxx11Ev335
_ZN4PLMD10vesselbase11ValueVessel16registerKeywordsERNS_8KeywordsE335
_ZN4PLMD10vesselbase11ValueVesselC2ERKNS0_13VesselOptionsE335
_ZN4PLMD10vesselbase11ValueVessel10applyForceERSt6vectorIdSaIdEE11443
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.cpp.func.html b/coverage/vesselbase/ValueVessel.cpp.func.html new file mode 100644 index 0000000000..53bb78e83a --- /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-06-10 08:19:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase11ValueVessel10applyForceERSt6vectorIdSaIdEE11443
_ZN4PLMD10vesselbase11ValueVessel11descriptionB5cxx11Ev335
_ZN4PLMD10vesselbase11ValueVessel16registerKeywordsERNS_8KeywordsE335
_ZN4PLMD10vesselbase11ValueVesselC2ERKNS0_13VesselOptionsE335
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.cpp.gcov.html b/coverage/vesselbase/ValueVessel.cpp.gcov.html new file mode 100644 index 0000000000..b2a3967073 --- /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-06-10 08:19:14Functions: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         335 : void ValueVessel::registerKeywords( Keywords& keys ) {
+      28         335 :   Vessel::registerKeywords( keys );
+      29         670 :   keys.add("compulsory","COMPONENT","1","the component of the vector for which to calculate this quantity");
+      30         335 : }
+      31             : 
+      32         335 : ValueVessel::ValueVessel( const VesselOptions& da ):
+      33         335 :   Vessel(da)
+      34             : {
+      35         670 :   parse("COMPONENT",mycomp);
+      36         335 :   ActionWithValue* a=dynamic_cast<ActionWithValue*>( getAction() );
+      37         335 :   plumed_massert(a,"cannot create passable values as base action does not inherit from ActionWithValue");
+      38             :   int numval = getNumericalLabel();
+      39         335 :   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         299 :   } else if( numval<0 ) {
+      44           4 :     final_value_ptr=Tools::make_unique<Value>();
+      45           2 :     final_value=final_value_ptr.get();
+      46           2 :     final_value->setNotPeriodic();
+      47             :   } else {
+      48         594 :     plumed_massert( !a->exists(getAction()->getLabel() + "." + getLabel() ), "you can't create the name multiple times");
+      49         297 :     a->addComponentWithDerivatives( getLabel() );
+      50         594 :     a->componentIsNotPeriodic( getLabel() );
+      51         297 :     final_value=a->copyOutput( a->getNumberOfComponents()-1 );
+      52             :   }
+      53         335 : }
+      54             : 
+      55         335 : std::string ValueVessel::description() {
+      56         403 :   if( final_value->getName()==getAction()->getLabel() ) return "value " + getAction()->getLabel() + " contains " + value_descriptor();
+      57         299 :   std::string compstr; Tools::convert(mycomp,compstr);
+      58         814 :   return "value " + getAction()->getLabel() + "." + getLabel() + " is obtained by taking the " + compstr + "th component and finding " + value_descriptor();
+      59             : }
+      60             : 
+      61       11443 : bool ValueVessel::applyForce( std::vector<double>& forces ) {
+      62       11443 :   std::vector<double> tmpforce( forces.size() );
+      63       11443 :   forces.assign(forces.size(),0.0); bool wasforced=false;
+      64       11443 :   if( final_value->applyForce( tmpforce ) ) {
+      65             :     wasforced=true;
+      66      524318 :     for(unsigned j=0; j<forces.size(); ++j) forces[j]+=tmpforce[j];
+      67             :   }
+      68       11443 :   return wasforced;
+      69             : }
+      70             : 
+      71             : }
+      72             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..111c9595ed --- /dev/null +++ b/coverage/vesselbase/ValueVessel.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + 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:44100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.h.func.html b/coverage/vesselbase/ValueVessel.h.func.html new file mode 100644 index 0000000000..048162594c --- /dev/null +++ b/coverage/vesselbase/ValueVessel.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + 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:44100.0 %
Date:2024-06-10 08:19:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.h.gcov.html b/coverage/vesselbase/ValueVessel.h.gcov.html new file mode 100644 index 0000000000..213bcc4cd6 --- /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:44100.0 %
Date:2024-06-10 08:19:14Functions: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_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     2406221 :   return final_value;
+      60             : }
+      61             : 
+      62             : inline
+      63             : double ValueVessel::getOutputValue() const {
+      64        3389 :   return final_value->get();
+      65             : }
+      66             : 
+      67             : inline
+      68             : void ValueVessel::setOutputValue( const double& val ) {
+      69        2079 :   final_value->set( val );
+      70         251 : }
+      71             : 
+      72             : }
+      73             : }
+      74             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + 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 0000000000..5bf5ffd2ed --- /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-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase6Vessel5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD10vesselbase6Vessel7getNameB5cxx11Ev89
_ZN4PLMD10vesselbase6Vessel9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb122
_ZN4PLMD10vesselbase6Vessel11getAllInputB5cxx11Ev172
_ZN4PLMD10vesselbase13VesselOptionsC2ERKS1_RKNS_8KeywordsE449
_ZN4PLMD10vesselbase6Vessel16registerKeywordsERNS_8KeywordsE449
_ZN4PLMD10vesselbase6Vessel9checkReadEv542
_ZN4PLMD10vesselbase13VesselOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKjS9_PNS0_16ActionWithVesselE600
_ZN4PLMD10vesselbase6VesselC2ERKNS0_13VesselOptionsE601
_ZN4PLMD10vesselbase6Vessel13transformNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE796
_ZNK4PLMD10vesselbase6Vessel8getLabelB5cxx11Ev28581
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Vessel.cpp.func.html b/coverage/vesselbase/Vessel.cpp.func.html new file mode 100644 index 0000000000..1d083535d2 --- /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-06-10 08:19:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase13VesselOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKjS9_PNS0_16ActionWithVesselE600
_ZN4PLMD10vesselbase13VesselOptionsC2ERKS1_RKNS_8KeywordsE449
_ZN4PLMD10vesselbase6Vessel11getAllInputB5cxx11Ev172
_ZN4PLMD10vesselbase6Vessel13transformNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE796
_ZN4PLMD10vesselbase6Vessel16registerKeywordsERNS_8KeywordsE449
_ZN4PLMD10vesselbase6Vessel5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD10vesselbase6Vessel9checkReadEv542
_ZN4PLMD10vesselbase6Vessel9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb122
_ZN4PLMD10vesselbase6VesselC2ERKNS0_13VesselOptionsE601
_ZNK4PLMD10vesselbase6Vessel7getNameB5cxx11Ev89
_ZNK4PLMD10vesselbase6Vessel8getLabelB5cxx11Ev28581
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Vessel.cpp.gcov.html b/coverage/vesselbase/Vessel.cpp.gcov.html new file mode 100644 index 0000000000..93394e9873 --- /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-06-10 08:19:14Functions: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         600 : VesselOptions::VesselOptions(const std::string& thisname, const std::string& thislab, const unsigned& nlab, const std::string& params, ActionWithVessel* aa ):
+      34         600 :   myname(thisname),
+      35         600 :   mylabel(thislab),
+      36         600 :   numlab(nlab),
+      37         600 :   action(aa),
+      38         600 :   keywords(emptyKeys),
+      39         600 :   parameters(params)
+      40             : {
+      41         600 : }
+      42             : 
+      43         449 : VesselOptions::VesselOptions(const VesselOptions& da, const Keywords& keys ):
+      44         449 :   myname(da.myname),
+      45         449 :   mylabel(da.mylabel),
+      46         449 :   numlab(da.numlab),
+      47         449 :   action(da.action),
+      48         449 :   keywords(keys),
+      49         449 :   parameters(da.parameters)
+      50             : {
+      51         449 : }
+      52             : 
+      53         449 : void Vessel::registerKeywords( Keywords& keys ) {
+      54         449 :   plumed_assert( keys.size()==0 );
+      55         898 :   keys.add("optional","LABEL","the label used to reference this particular quantity");
+      56         449 : }
+      57             : 
+      58         796 : std::string Vessel::transformName( const std::string& name ) {
+      59         796 :   std::string tlabel=name;
+      60             :   // Convert to lower case
+      61        4607 :   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         978 :     std::size_t num=tlabel.find_first_of("_");
+      65         978 :     if( num==std::string::npos ) break;
+      66         182 :     tlabel.erase( tlabel.begin() + num, tlabel.begin() + num + 1 );
+      67         182 :   }
+      68         796 :   return tlabel;
+      69             : }
+      70             : 
+      71         601 : Vessel::Vessel( const VesselOptions& da ):
+      72         601 :   myname(da.myname),
+      73         601 :   numlab(da.numlab),
+      74         601 :   action(da.action),
+      75         601 :   line(Tools::getWords( da.parameters )),
+      76         601 :   keywords(da.keywords),
+      77         601 :   finished_read(false)
+      78             : {
+      79         601 :   if( da.mylabel.length()>0) {
+      80           0 :     mylabel=da.mylabel;
+      81             :   } else {
+      82        1607 :     if( keywords.exists("LABEL") ) parse("LABEL",mylabel);
+      83         601 :     if( mylabel.length()==0 && numlab>=0 ) {
+      84         938 :       mylabel=transformName( myname ); std::string nn;
+      85         522 :       if(numlab>0) { Tools::convert( numlab, nn ); mylabel =  mylabel + "-" + nn; }
+      86             :     }
+      87             :   }
+      88         601 : }
+      89             : 
+      90          89 : std::string Vessel::getName() const {
+      91          89 :   return myname;
+      92             : }
+      93             : 
+      94       28581 : std::string Vessel::getLabel() const {
+      95       28581 :   return mylabel;
+      96             : }
+      97             : 
+      98         172 : std::string Vessel::getAllInput() {
+      99             :   std::string fullstring;
+     100         731 :   for(unsigned i=0; i<line.size(); ++i) {
+     101        1118 :     fullstring = fullstring + " " + line[i];
+     102             :   }
+     103         172 :   line.clear(); line.resize(0);
+     104         172 :   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         198 :     } 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         542 : void Vessel::checkRead() {
+     126         542 :   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         542 :   finished_read=true;
+     135         542 :   std::string describe=description();
+     136         542 :   if( describe.length()>0 && action ) action->log.printf("  %s\n", describe.c_str() );
+     137         542 : }
+     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.15
+
+ + + 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 0000000000..a0d1c019ab --- /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-06-10 08:19:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase6VesselD0Ev0
_ZN4PLMD10vesselbase6Vessel5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_9
_ZN4PLMD10vesselbase6Vessel11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EE36
_ZN4PLMD10vesselbase6Vessel11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RSt6vectorIT_SaISC_EE209
_ZN4PLMD10vesselbase6Vessel5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_343
_ZN4PLMD10vesselbase6Vessel5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RT_526
_ZN4PLMD10vesselbase6VesselD2Ev601
_ZN4PLMD10vesselbase6Vessel7prepareEv26782
_ZN4PLMD10vesselbase6Vessel14setBufferStartERj32918
_ZN4PLMD10vesselbase6Vessel20transformDerivativesERKjRNS_10MultiValueES5_508967
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Vessel.h.func.html b/coverage/vesselbase/Vessel.h.func.html new file mode 100644 index 0000000000..16f77e83ad --- /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-06-10 08:19:14Functions: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
_ZN4PLMD10vesselbase6Vessel14setBufferStartERj32918
_ZN4PLMD10vesselbase6Vessel20transformDerivativesERKjRNS_10MultiValueES5_508967
_ZN4PLMD10vesselbase6Vessel5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RT_526
_ZN4PLMD10vesselbase6Vessel5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_9
_ZN4PLMD10vesselbase6Vessel5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_343
_ZN4PLMD10vesselbase6Vessel7prepareEv26782
_ZN4PLMD10vesselbase6VesselD0Ev0
_ZN4PLMD10vesselbase6VesselD2Ev601
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/Vessel.h.gcov.html b/coverage/vesselbase/Vessel.h.gcov.html new file mode 100644 index 0000000000..5826d07946 --- /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-06-10 08:19:14Functions: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         601 :   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       26782 :   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         878 : void Vessel::parse(const std::string&key, T&t ) {
+     158         878 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     159             : 
+     160             :   // Now try to read the keyword
+     161         878 :   bool found=Tools::parse(line,key,t); std::string def;
+     162        2005 :   if ( !found && keywords.style(key,"compulsory") ) {
+     163         726 :     if( keywords.getDefaultValue(key,def) ) {
+     164         363 :       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         878 : }
+     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         351 :   return numlab;
+     206             : }
+     207             : 
+     208             : inline
+     209       32918 : void Vessel::setBufferStart( unsigned& start ) {
+     210       32918 :   bufstart=start; start+=bufsize;
+     211       32918 : }
+     212             : 
+     213             : inline
+     214      508967 : MultiValue& Vessel::transformDerivatives( const unsigned& current, MultiValue& myvals, MultiValue& bvals ) {
+     215      508967 :   return myvals;
+     216             : }
+     217             : 
+     218             : inline
+     219             : void Vessel::resizeBuffer( const unsigned& n ) {
+     220        2828 :   bufsize=n;
+     221           0 : }
+     222             : 
+     223             : inline
+     224             : double Vessel::getTolerance() const {
+     225      134170 :   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     3906993 :   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.15
+
+ + + 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 0000000000..4acb88c6ff --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14VesselRegister6createENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_13VesselOptionsE357
_ZN4PLMD10vesselbase14VesselRegister11getKeywordsEv682
_ZN4PLMD10vesselbase14VesselRegisterD2Ev3473
_ZN4PLMD10vesselbase14VesselRegister5checkENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9619
_ZN4PLMD10vesselbase14VesselRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS9_EERKNS0_13VesselOptionsEEPFvRNS_8KeywordsEESL_62514
_ZN4PLMD10vesselbase14VesselRegister6removeEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS3_EERKNS0_13VesselOptionsEE62514
_ZN4PLMD10vesselbase14vesselRegisterEv135329
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/VesselRegister.cpp.func.html b/coverage/vesselbase/VesselRegister.cpp.func.html new file mode 100644 index 0000000000..30fb73d5d8 --- /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-06-10 08:19:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14VesselRegister11getKeywordsEv682
_ZN4PLMD10vesselbase14VesselRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS9_EERKNS0_13VesselOptionsEEPFvRNS_8KeywordsEESL_62514
_ZN4PLMD10vesselbase14VesselRegister5checkENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9619
_ZN4PLMD10vesselbase14VesselRegister6createENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_13VesselOptionsE357
_ZN4PLMD10vesselbase14VesselRegister6removeEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS3_EERKNS0_13VesselOptionsEE62514
_ZN4PLMD10vesselbase14VesselRegisterD2Ev3473
_ZN4PLMD10vesselbase14vesselRegisterEv135329
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/VesselRegister.cpp.gcov.html b/coverage/vesselbase/VesselRegister.cpp.gcov.html new file mode 100644 index 0000000000..a21839ef90 --- /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-06-10 08:19:14Functions: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        3473 : VesselRegister::~VesselRegister() {
+      30        3473 :   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        3473 : }
+      36             : 
+      37      135329 : VesselRegister& vesselRegister() {
+      38      135329 :   static VesselRegister ans;
+      39      135329 :   return ans;
+      40             : }
+      41             : 
+      42       62514 : void VesselRegister::remove(creator_pointer f) {
+      43      395922 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      44      395922 :     if((*p).second==f) {
+      45       62514 :       m.erase(p); break;
+      46             :     }
+      47             :   }
+      48       62514 : }
+      49             : 
+      50       62514 : 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       62514 :   m.insert(std::pair<std::string,creator_pointer>(keyword,f));
+      53       62514 :   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       62514 :   mk.insert(std::pair<std::string,keyword_pointer>(keyword,ik));
+      58       62514 : }
+      59             : 
+      60        9619 : bool VesselRegister::check(std::string key) {
+      61        3109 :   if( m.count(key)>0 ) return true;
+      62             :   return false;
+      63             : }
+      64             : 
+      65         357 : std::unique_ptr<Vessel> VesselRegister::create(std::string keyword, const VesselOptions&da) {
+      66         357 :   std::unique_ptr<Vessel> df;
+      67         714 :   if(check(keyword)) {
+      68         357 :     Keywords keys; mk[keyword](keys);
+      69         357 :     VesselOptions nda( da,keys );
+      70         714 :     df=m[keyword](nda);
+      71         357 :   }
+      72         357 :   return df;
+      73           0 : }
+      74             : 
+      75         682 : Keywords VesselRegister::getKeywords() {
+      76         682 :   return keywords;
+      77             : }
+      78             : 
+      79             : }
+      80             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/vesselbase/index-sort-f.html b/coverage/vesselbase/index-sort-f.html new file mode 100644 index 0000000000..f00ea54960 --- /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:1139122692.9 %
Date:2024-06-10 08:19:14Functions:23125889.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 %188 / 20176.9 %20 / 26
ActionWithAveraging.cpp +
95.3%95.3%
+
95.3 %102 / 10778.6 %11 / 14
StoreDataVessel.h +
92.3%92.3%
+
92.3 %24 / 2685.7 %6 / 7
ActionWithAveraging.h +
92.3%92.3%
+
92.3 %12 / 1385.7 %6 / 7
FunctionVessel.cpp +
95.7%95.7%
+
95.7 %44 / 4685.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
ValueVessel.h +
100.0%
+
100.0 %4 / 4-0 / 0
BridgeVessel.h +
100.0%
+
100.0 %1 / 1-0 / 0
FunctionVessel.h +
0.0%
+
0.0 %0 / 1-0 / 0
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.3%96.3%
+
96.3 %26 / 27100.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
VesselRegister.cpp +
84.8%84.8%
+
84.8 %28 / 33100.0 %7 / 7
AveragingVessel.cpp +
100.0%
+
100.0 %23 / 23100.0 %7 / 7
Highest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
MoreThan.cpp +
100.0%
+
100.0 %20 / 20100.0 %8 / 8
Mean.cpp +
100.0%
+
100.0 %17 / 17100.0 %8 / 8
Sum.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Lowest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Min.cpp +
100.0%
+
100.0 %24 / 24100.0 %9 / 9
AltMin.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
LessThan.cpp +
100.0%
+
100.0 %22 / 22100.0 %9 / 9
Between.cpp +
100.0%
+
100.0 %30 / 30100.0 %9 / 9
Max.cpp +
100.0%
+
100.0 %23 / 23100.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.15
+
+ + + diff --git a/coverage/vesselbase/index-sort-l.html b/coverage/vesselbase/index-sort-l.html new file mode 100644 index 0000000000..656a521958 --- /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:1139122692.9 %
Date:2024-06-10 08:19:14Functions:23125889.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 %188 / 20176.9 %20 / 26
ActionWithAveraging.cpp +
95.3%95.3%
+
95.3 %102 / 10778.6 %11 / 14
FunctionVessel.cpp +
95.7%95.7%
+
95.7 %44 / 4685.7 %6 / 7
OrderingVessel.cpp +
96.3%96.3%
+
96.3 %26 / 27100.0 %4 / 4
BridgeVessel.cpp +
97.0%97.0%
+
97.0 %96 / 9992.3 %12 / 13
BridgeVessel.h +
100.0%
+
100.0 %1 / 1-0 / 0
OrderingVessel.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
ValueVessel.h +
100.0%
+
100.0 %4 / 4-0 / 0
ShortcutVessel.cpp +
100.0%
+
100.0 %12 / 12100.0 %3 / 3
Highest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
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
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.15
+
+ + + diff --git a/coverage/vesselbase/index.html b/coverage/vesselbase/index.html new file mode 100644 index 0000000000..03f6dc62de --- /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:1139122692.9 %
Date:2024-06-10 08:19:14Functions:23125889.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionWithAveraging.cpp +
95.3%95.3%
+
95.3 %102 / 10778.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 %188 / 20176.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.3%96.3%
+
96.3 %26 / 27100.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 %4 / 4-0 / 0
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.15
+
+ + + 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 0000000000..23567ff051 --- /dev/null +++ b/coverage/wrapper/Plumed.h.func-sort-c.html @@ -0,0 +1,981 @@ + + + + + + + + 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:23643853.9 %
Date:2024-06-10 08:19:14Functions:14222762.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN12_GLOBAL__N_115plumed_cmd_safeE6plumedPKc14plumed_safeptr0
_ZN12_GLOBAL__N_118plumed_cmd_nothrowE6plumedPKcPKv22plumed_nothrow_handler0
_ZN4PLMD12_GLOBAL__N_16Plumed12std_bad_castC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed12std_bad_castD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed12std_bad_castD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_bad_allocC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_bad_allocD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_bad_allocD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_exceptionC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_exceptionD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_exceptionD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed14std_bad_typeidC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed14std_bad_typeidD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed14std_bad_typeidD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed15nothrow_handlerEPviPKcPKv0
_ZN4PLMD12_GLOBAL__N_16Plumed17std_bad_exceptionC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed17std_bad_exceptionD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed17std_bad_exceptionD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowERKNS1_14NothrowHandlerE0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowEv0
_ZN4PLMD12_GLOBAL__N_16Plumed9ExceptionC2EPKc0
_ZN4PLMD12_GLOBAL__N_1L27PlumedGetenvExceptionsDebugEv0
_ZN4PLMD6Plumed12std_bad_castC2EPKc0
_ZN4PLMD6Plumed12std_bad_castD0Ev0
_ZN4PLMD6Plumed12std_bad_castD2Ev0
_ZN4PLMD6Plumed13std_bad_allocC2EPKc0
_ZN4PLMD6Plumed13std_bad_allocD0Ev0
_ZN4PLMD6Plumed13std_bad_allocD2Ev0
_ZN4PLMD6Plumed13std_exceptionC2EPKc0
_ZN4PLMD6Plumed13std_exceptionD0Ev0
_ZN4PLMD6Plumed13std_exceptionD2Ev0
_ZN4PLMD6Plumed14std_bad_typeidC2EPKc0
_ZN4PLMD6Plumed14std_bad_typeidD0Ev0
_ZN4PLMD6Plumed14std_bad_typeidD2Ev0
_ZN4PLMD6Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD6Plumed15nothrow_handlerEPviPKcPKv0
_ZN4PLMD6Plumed17std_bad_exceptionC2EPKc0
_ZN4PLMD6Plumed17std_bad_exceptionD0Ev0
_ZN4PLMD6Plumed17std_bad_exceptionD2Ev0
_ZN4PLMD6Plumed7rethrowERKNS0_14NothrowHandlerE0
_ZN4PLMD6Plumed7rethrowEv0
_ZN4PLMD6Plumed9ExceptionC2EPKc0
_ZN4PLMDL27PlumedGetenvExceptionsDebugEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed12std_bad_cast4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13std_bad_alloc4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13std_exception4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed14std_bad_typeid4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed15LeptonException4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed17std_bad_exception4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed9Exception4whatEv0
_ZNK4PLMD6Plumed12std_bad_cast4whatEv0
_ZNK4PLMD6Plumed13std_bad_alloc4whatEv0
_ZNK4PLMD6Plumed13std_exception4whatEv0
_ZNK4PLMD6Plumed14std_bad_typeid4whatEv0
_ZNK4PLMD6Plumed15LeptonException4whatEv0
_ZNK4PLMD6Plumed17std_bad_exception4whatEv0
_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_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_safeptr_int5
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_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_kernel_register12
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_safeptr_char18
plumed_f_use_count_static18
plumed_f_global19
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_create_reference78
plumed_f_gcmd_static78
plumed_gcmd78
plumed_cmd_safe93
_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
_ZN12_GLOBAL__N_115plumed_finalizeE6plumed223
plumed_f_cmd_static279
_ZN4PLMD6Plumed14plumed_cmd_cxxIP19ompi_communicator_tEEv6plumedPKcPT_P12plumed_error336
plumed_cmd357
plumed_f2c373
_ZN4PLMD6Plumed14plumed_cmd_cxxIPcEEv6plumedPKcPT_P12plumed_error3441
_ZN4PLMD6Plumed14plumed_cmd_cxxIiEEv6plumedPKcPT_P12plumed_error6882
_ZN4PLMD6Plumed8cmd_privE6plumedPKcPNS0_7SafePtrEPKvP12plumed_error10659
plumed_cmd_safe_nothrow11781
plumed_symbol_table_reexport364781
plumed_retrieve_functions364791
plumed_finalize388302
plumed_create389155
plumed_malloc_pimpl390272
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/wrapper/Plumed.h.func.html b/coverage/wrapper/Plumed.h.func.html new file mode 100644 index 0000000000..bc5884b1a1 --- /dev/null +++ b/coverage/wrapper/Plumed.h.func.html @@ -0,0 +1,981 @@ + + + + + + + + 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:23643853.9 %
Date:2024-06-10 08:19:14Functions:14222762.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
_ZN12_GLOBAL__N_115plumed_cmd_safeE6plumedPKc14plumed_safeptr0
_ZN12_GLOBAL__N_115plumed_finalizeE6plumed223
_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_16Plumed12std_bad_castC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed12std_bad_castD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed12std_bad_castD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_bad_allocC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_bad_allocD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_bad_allocD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_exceptionC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_exceptionD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed13std_exceptionD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed14plumed_cmd_cxxI14plumed_safeptrEEv6plumedPKcT_P12plumed_error222
_ZN4PLMD12_GLOBAL__N_16Plumed14std_bad_typeidC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed14std_bad_typeidD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed14std_bad_typeidD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed15nothrow_handlerEPviPKcPKv0
_ZN4PLMD12_GLOBAL__N_16Plumed17std_bad_exceptionC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed17std_bad_exceptionD0Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed17std_bad_exceptionD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowERKNS1_14NothrowHandlerE0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowEv0
_ZN4PLMD12_GLOBAL__N_16Plumed8cmd_privE6plumedPKcPNS1_7SafePtrEPKvP12plumed_error222
_ZN4PLMD12_GLOBAL__N_16Plumed9ExceptionC2EPKc0
_ZN4PLMD12_GLOBAL__N_1L27PlumedGetenvExceptionsDebugEv0
_ZN4PLMD6Plumed12std_bad_castC2EPKc0
_ZN4PLMD6Plumed12std_bad_castD0Ev0
_ZN4PLMD6Plumed12std_bad_castD2Ev0
_ZN4PLMD6Plumed13std_bad_allocC2EPKc0
_ZN4PLMD6Plumed13std_bad_allocD0Ev0
_ZN4PLMD6Plumed13std_bad_allocD2Ev0
_ZN4PLMD6Plumed13std_exceptionC2EPKc0
_ZN4PLMD6Plumed13std_exceptionD0Ev0
_ZN4PLMD6Plumed13std_exceptionD2Ev0
_ZN4PLMD6Plumed14plumed_cmd_cxxIP19ompi_communicator_tEEv6plumedPKcPT_P12plumed_error336
_ZN4PLMD6Plumed14plumed_cmd_cxxIPcEEv6plumedPKcPT_P12plumed_error3441
_ZN4PLMD6Plumed14plumed_cmd_cxxIiEEv6plumedPKcPT_P12plumed_error6882
_ZN4PLMD6Plumed14std_bad_typeidC2EPKc0
_ZN4PLMD6Plumed14std_bad_typeidD0Ev0
_ZN4PLMD6Plumed14std_bad_typeidD2Ev0
_ZN4PLMD6Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD6Plumed15nothrow_handlerEPviPKcPKv0
_ZN4PLMD6Plumed17std_bad_exceptionC2EPKc0
_ZN4PLMD6Plumed17std_bad_exceptionD0Ev0
_ZN4PLMD6Plumed17std_bad_exceptionD2Ev0
_ZN4PLMD6Plumed7rethrowERKNS0_14NothrowHandlerE0
_ZN4PLMD6Plumed7rethrowEv0
_ZN4PLMD6Plumed8cmd_privE6plumedPKcPNS0_7SafePtrEPKvP12plumed_error10659
_ZN4PLMD6Plumed9ExceptionC2EPKc0
_ZN4PLMDL27PlumedGetenvExceptionsDebugEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed12std_bad_cast4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13std_bad_alloc4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13std_exception4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed14std_bad_typeid4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed15LeptonException4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed17std_bad_exception4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed9Exception4whatEv0
_ZNK4PLMD6Plumed12std_bad_cast4whatEv0
_ZNK4PLMD6Plumed13std_bad_alloc4whatEv0
_ZNK4PLMD6Plumed13std_exception4whatEv0
_ZNK4PLMD6Plumed14std_bad_typeid4whatEv0
_ZNK4PLMD6Plumed15LeptonException4whatEv0
_ZNK4PLMD6Plumed17std_bad_exception4whatEv0
_ZNK4PLMD6Plumed9Exception4whatEv0
plumed_attempt_dlopen8
plumed_c2f56
plumed_c2v2
plumed_cmd357
plumed_cmd_nothrow0
plumed_cmd_safe93
plumed_cmd_safe_nothrow11781
plumed_create389155
plumed_create_dlopen8
plumed_create_dlopen28
plumed_create_dlsym8
plumed_create_invalid2
plumed_create_reference78
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_char18
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_int5
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_finalize388302
plumed_gcmd78
plumed_gcmd_safe0
plumed_gcreate22
plumed_gfinalize22
plumed_ginitialized24
plumed_global41
plumed_gvalid8
plumed_installed9
plumed_kernel_register12
plumed_malloc_pimpl390272
plumed_retrieve_functions364791
plumed_search_symbols8
plumed_symbol_table_reexport364781
plumed_use_count42
plumed_v2c2
plumed_valid23
+
+
+ + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/wrapper/Plumed.h.gcov.html b/coverage/wrapper/Plumed.h.gcov.html new file mode 100644 index 0000000000..2cda33e023 --- /dev/null +++ b/coverage/wrapper/Plumed.h.gcov.html @@ -0,0 +1,4010 @@ + + + + + + + + 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:23643853.9 %
Date:2024-06-10 08:19:14Functions:14222762.6 %
+
+ + + + + + + + +

+
          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             :   The basic method to send a message to plumed is
+     102             : \verbatim
+     103             :   (C) plumed_cmd
+     104             :   (C++) PLMD::Plumed::cmd
+     105             :   (FORTRAN)  PLUMED_F_CMD
+     106             : \endverbatim
+     107             : 
+     108             :   To initialize a plumed object, use:
+     109             : \verbatim
+     110             :   (C)        plumed_create
+     111             :   (C++)      (constructor of PLMD::Plumed)
+     112             :   (FORTRAN)  PLUMED_F_CREATE
+     113             : \endverbatim
+     114             : 
+     115             :   As of PLUMED 2.5, you can also initialize a plumed object using the following functions,
+     116             :   that load a specific kernel. The function plumed_create_dlopen2 allows to specify options
+     117             :   for dlopen. The C++ version accepts an optional argument to this aim.
+     118             : \verbatim
+     119             :   (C)        plumed_create_dlopen or plumed_create_dlopen2
+     120             :   (C++)      PLMD::Plumed::dlopen
+     121             :   (FORTRAN)  PLUMED_F_CREATE_DLOPEN
+     122             : \endverbatim
+     123             : 
+     124             :   As of PLUMED 2.8, you can also initialize a plumed object using the following function,
+     125             :   that loads a kernel from an already loaded shared library. It accepts a handler
+     126             :   returned by `dlopen`:
+     127             : \verbatim
+     128             :   (C)        plumed_create_dlsym
+     129             :   (C++)      PLMD::Plumed::dlsym
+     130             :   (FORTRAN not allowed)
+     131             : \endverbatim
+     132             : 
+     133             :   To finalize a plumed object, use
+     134             : \verbatim
+     135             :   (C)        plumed_finalize
+     136             :   (C++)      (destructor of PLMD::Plumed)
+     137             :   (FORTRAN)  PLUMED_F_FINALIZE
+     138             : \endverbatim
+     139             : 
+     140             :   To access to the global-object, use
+     141             : \verbatim
+     142             :   (C)        plumed_gcreate, plumed_gfinalize, plumed_gcmd
+     143             :   (C++)      PLMD::Plumed::gcreate, PLMD::Plumed::gfinalize, PLMD::Plumed::gcmd
+     144             :   (FORTRAN)  PLUMED_F_GCREATE, PLUMED_F_GFINALIZE, PLUMED_F_GCMD
+     145             : \endverbatim
+     146             : 
+     147             :   To check if the global object has been initialized, use
+     148             : \verbatim
+     149             :   (C)        plumed_ginitialized
+     150             :   (C++)      PLMD::Plumed::ginitialized
+     151             :   (FORTRAN)  PLUMED_F_GINITIALIZED
+     152             : \endverbatim
+     153             : 
+     154             :   Notice that when using runtime binding the plumed library might be not available.
+     155             :   In this case, plumed_create (and plumed_gcreate) will still succeed, but a subsequent
+     156             :   call to plumed_cmd (or plumed_gcmd) would exit. In order to avoid this
+     157             :   unpleasant situation you have two options.
+     158             : 
+     159             :   First, you can check if plumed library is available before actually creating an object
+     160             :   using this function:
+     161             : \verbatim
+     162             :   (C)        plumed_installed
+     163             :   (C++)      PLMD::Plumed::installed
+     164             :   (FORTRAN)  PLUMED_F_INSTALLED
+     165             : \endverbatim
+     166             : 
+     167             :   Alternatively, as of PLUMED 2.5, you can interrogate the just created plumed
+     168             :   object using the following function:
+     169             : \verbatim
+     170             :   (C)        plumed_valid
+     171             :   (C++)      PLMD::Plumed::valid
+     172             :   (FORTRAN)  PLUMED_F_VALID
+     173             : \endverbatim
+     174             : 
+     175             :   If you want to create on purpose an invalid Plumed object (useful in C++ to postpone
+     176             :   the loading of the library) you can use `Plumed p(Plumed::makeInvalid());`.
+     177             : 
+     178             :   To know if the global object is valid instead you should use the following function:
+     179             : \verbatim
+     180             :   (C)        plumed_gvalid
+     181             :   (C++)      PLMD::Plumed::gvalid
+     182             :   (FORTRAN)  PLUMED_F_GVALID
+     183             : \endverbatim
+     184             : 
+     185             :   To convert handlers between different languages, use
+     186             : \verbatim
+     187             :   (C)        plumed_c2f                 (C to FORTRAN)
+     188             :   (C)        plumed_f2c                 (FORTRAN to C)
+     189             :   (C++)      Plumed(plumed) constructor (C to C++)
+     190             :   (C++)      operator plumed() cast     (C++ to C)
+     191             :   (C++)      Plumed(char*)  constructor (FORTRAN to C++)
+     192             :   (C++)      toFortran(char*)           (C++ to FORTRAN)
+     193             : \endverbatim
+     194             : 
+     195             :   As of PLUMED 2.5, when using C or C++ we allow a user to explicitly store a plumed object as
+     196             :   a void pointer (indeed: that's the only thing contained in a plumed object).
+     197             :   This might be useful in case you do not want to include the Plumed.h header in some
+     198             :   of your headers. In order to convert to/from void pointers you can use the following functions
+     199             : \verbatim
+     200             :   (C)        plumed_v2c                 (void* to C)
+     201             :   (C)        plumed_c2v                 (C to void*)
+     202             :   (C++)      Plumed(void*) constructor  (void* to C++)
+     203             :   (C++)      toVoid()                   (C++ to void*)
+     204             : \endverbatim
+     205             :   Using the functions above is much safer than accessing directly the pointer contained in the \ref plumed struct
+     206             :   since, when compiling with debug options, it will check if the void pointer actually points to a plumed object.
+     207             : 
+     208             :   As of PLUMED 2.5, we added a reference count. It is in practice possible
+     209             :   to create multiple `plumed` objects that refer to the same environment.
+     210             :   This is done using the following functions
+     211             : \verbatim
+     212             :   (C)        plumed_create_reference     (from a C object)
+     213             :   (C)        plumed_create_reference_f   (from a FORTRAN object)
+     214             :   (C)        plumed_create_reference_v   (from a void pointer)
+     215             :   (FORTRAN)  plumed_f_create_reference   (from a FORTRAN object)
+     216             : \endverbatim
+     217             :   In C++ references are managed automatically by constructors and destructor.
+     218             :   In addition, you can manually manage them (with care!) using incref() and decref().
+     219             : 
+     220             :   The interface of the FORTRAN functions is very similar to that of the C functions
+     221             :   and is listed below:
+     222             : 
+     223             : \verbatim
+     224             :   FORTRAN interface
+     225             :     SUBROUTINE PLUMED_F_CREATE(p)
+     226             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     227             :     SUBROUTINE PLUMED_F_CREATE_DLOPEN(p,path)
+     228             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     229             :       CHARACTER(LEN=*),  INTENT(IN)    :: path
+     230             :     SUBROUTINE PLUMED_F_CREATE_REFERENCE(p,r)
+     231             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     232             :       CHARACTER(LEN=32), INTENT(IN)    :: r
+     233             :     SUBROUTINE PLUMED_F_CREATE_INVALID(p)
+     234             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     235             :     SUBROUTINE PLUMED_F_CMD(p,key,val)
+     236             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     237             :       CHARACTER(LEN=*),  INTENT(IN)    :: key
+     238             :       UNSPECIFIED_TYPE,  INTENT(INOUT) :: val(*)
+     239             :     SUBROUTINE PLUMED_F_FINALIZE(p)
+     240             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     241             :     SUBROUTINE PLUMED_F_INSTALLED(i)
+     242             :       INTEGER,           INTENT(OUT)   :: i
+     243             :     SUBROUTINE PLUMED_F_VALID(p,i)
+     244             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     245             :       INTEGER,           INTENT(OUT)   :: i
+     246             :     SUBROUTINE PLUMED_F_USE_COUNT(p,i)
+     247             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     248             :       INTEGER,           INTENT(OUT)   :: i
+     249             :     SUBROUTINE PLUMED_F_GLOBAL(p)
+     250             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     251             :     SUBROUTINE PLUMED_F_GINITIALIZED(i)
+     252             :       INTEGER,           INTENT(OUT)   :: i
+     253             :     SUBROUTINE PLUMED_F_GCREATE()
+     254             :     SUBROUTINE PLUMED_F_GCMD(key,val)
+     255             :       CHARACTER(LEN=*), INTENT(IN)     :: key
+     256             :       UNSPECIFIED_TYPE, INTENT(INOUT)  :: val(*)
+     257             :     SUBROUTINE PLUMED_F_GFINALIZE()
+     258             :     SUBROUTINE PLUMED_F_GVALID(i)
+     259             :       INTEGER,           INTENT(OUT)   :: i
+     260             : \endverbatim
+     261             : 
+     262             :   Almost all C functions have a corresponding FORTRAN function.
+     263             :   As a simple mnemonic, if you know the name of the C function you can obtain the
+     264             :   corresponding FORTRAN subroutine by adding `F_` after the `PLUMED_` prefix.
+     265             :   In addition, all `plumed` objects are replaced by `CHARACTER(LEN=32)` objects
+     266             :   holding the same information. These pointers basically contain a text representation
+     267             :   of the stored pointer, that is suitable to be contained in a string.
+     268             :   Finally, whenever a C function returns a value,
+     269             :   the corresponding FORTRAN subroutine will have an additional `INTENT(OUT)` parameter
+     270             :   passed as the its last argument.
+     271             : 
+     272             :   When you compile the FORTRAN interface, wrapper functions are added with several possible
+     273             :   name manglings, so you should not experience problems linking the plumed library with a FORTRAN file.
+     274             : 
+     275             : \section ReferencePlumedH-exceptions Error handling
+     276             : 
+     277             :   In case an error is detected by PLUMED, either because of some user error, some internal bug,
+     278             :   or some mistake in using the library, an exception will be thrown. The behavior is different depending if you use
+     279             :   PLUMED from C/FORTRAN or from C++.
+     280             : 
+     281             :   First of all, notice that access to PLUMED goes through three functions:
+     282             :   - plumed_create: this, as of PLUMED 2.5, is guaranteed not to throw any exception. If there is a problem, it will
+     283             :     just return a plumed object containing a NULL pointer
+     284             :   - plumed_cmd: this function might throw exceptions.
+     285             :   - plumed_finalize: this is a destructor and is guaranteed not to throw any exception.
+     286             : 
+     287             :   The following discussion concerns all the exceptions thrown by plumed_cmd.
+     288             : 
+     289             :   If you use C/FORTRAN, you will basically have no way to intercept the exception and the program will just terminate.
+     290             : 
+     291             :   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
+     292             :   remapping of the exceptions thrown by PLUMED.  This solves both the problems mentioned above. In particular:
+     293             :   - Instead of throwing an exception, PLUMED will return (using a \ref plumed_nothrow_handler) the details about the occurred error.
+     294             :   - An equivalent exception will be thrown within the inline PLUMED interface compiled with your MD code.
+     295             : 
+     296             :   As a consequence, you will be able to combine different compilers and avoid stack unwinding in the C layer.
+     297             : 
+     298             :   If you use C++ but you are calling the C interface (e.g. \ref plumed_cmd), then you might be
+     299             :   able to catch the exceptions thrown by PLUMED. Notice that all the exceptions thrown by PLUMED inherit from std::exception,
+     300             :   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
+     301             :   the \ref Plumed::cmd interface, and thus behaves in an equivalent manner. With previous versions of this header
+     302             :   one could have encountered problems with stack unwinding performed during exception handling in the C layer.
+     303             : 
+     304             :   Notice that, even if you use \ref Plumed::cmd, if you are loading a kernel <=2.4 any exception generated by PLUMED will
+     305             :   leak through the C layer. This might lead to undefined behavior. If you are lucky (with some compiler it works!) and
+     306             :   the exception arrives to C, PLUMED will catch it and rethrow it as it would do if you were using a kernel >=2.5.
+     307             : 
+     308             :   The remapping of exceptions takes care of all the standard C++ exceptions plus all the exceptions raised within
+     309             :   PLUMED. Unexpected exceptions that are derived from std::exception will be rethrown as std::exception.
+     310             :   Notice that this implies some loss of information, since the original exception might have been of a different type.
+     311             :   However, it also implies that the virtual table of the original exception won't be needed anymore. This allows to
+     312             :   completely decouple the MD code from the PLUMED library.
+     313             : 
+     314             : \section ReferencePlumedH-typesafe Typesafe interface
+     315             : 
+     316             :   Starting with PLUMED 2.8, the `cmd` function of the C++ interface, and the similar function `gcmd`, can be called
+     317             :   with several interfaces and can perform a typechecking on the passed argument. In particular, the following
+     318             :   forms are now possible:
+     319             : \verbatim
+     320             :   cmd("string",value);        // by value
+     321             :   cmd("string",&value);       // by pointer
+     322             :   cmd("string",&value,nelem); // by pointer, specifying the number of elements of the passed array
+     323             :   cmd("string",&value,shape); // by pointer, specifying the shape of the passed array
+     324             : \endverbati
+     325             :   The `nelem` and `shape` arguments are used by PLUMED to check that the user
+     326             :   provided enough elements. If nelem is provided, the check is done on the flatten array, whereas if shape
+     327             :   is passed a more thorough check is performed controlling each of the dimensions of the array.
+     328             :   In addition to this, the type of the pointer (or of the value) is checked at runtime.
+     329             : 
+     330             :   All these checks are only implemented if the PLUMED library is recent (>=2.8). However, it will still be
+     331             :   possible to load at runtime an older PLUMED library (<=2.7). For this reason, it is still compulsory
+     332             :   to pass the correct types to the `cmd` function, also when the argument is passed by value.
+     333             :   Type conversions are only performed between pointers and only in ways compatible with
+     334             :   what is allowed in C++ (e.g., `const void*` cannot be converted to `void*`, but `void*` can
+     335             :   be converted to `const void*`).
+     336             : 
+     337             :   Type checkes can be disabled in two ways:
+     338             :   - By compiling `Plumed.h` with `-D__PLUMED_WRAPPER_CXX_TYPESAFE=0`
+     339             :   - By setting `export PLUMED_TYPESAFE_IGNORE=yes` at runtime.
+     340             : 
+     341             :   Typechecks are also enabled in the C interface (plumed_cmd). This function is replaced with a macro by default.
+     342             :   In particular:
+     343             :   - 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`.
+     344             :   - If the C interface is used in C code and compiled with a C11 compiler, it uses _Generic to pass type information.
+     345             :     Can be disabled using `-D__PLUMED_WRAPPER_C_TYPESAFE=0`.
+     346             : 
+     347             : \section ReferencePlumedH-2-5 New in PLUMED 2.5
+     348             : 
+     349             :   The wrappers in PLUMED 2.5 have been completely rewritten with several improvements.
+     350             :   The interface is almost perfectly backward compatible, although the behavior of C++ constructors
+     351             :   has been modified slightly.
+     352             :   In addition, a few new functions are introduced (explicitly marked in the documentation).
+     353             :   As a consequence, if your code uses some of the new functions, you will not be able
+     354             :   to link it directly with an older PLUMED library (though you will still be able to load
+     355             :   an older PLUMED library at runtime). In addition, the reference counter changes slightly
+     356             :   the behavior of the C++ methods used to interoperate with C and FORTRAN.
+     357             : 
+     358             :   An important novelty is in the way the runtime loader is implemented.
+     359             :   In particular, the loader works also if the symbols of the main executable are not exported.
+     360             :   The proper functions from the kernel are indeed searched explicitly now using `dlsym`.
+     361             : 
+     362             :   Some additional features can be enabled using suitable environment variables. In particular:
+     363             :   - `PLUMED_LOAD_DEBUG` can be set to report more information about the loading process.
+     364             :   - `PLUMED_LOAD_NAMESPACE` can be set to `LOCAL` to load the PLUMED kernel in a separate
+     365             :     namespace. The default is global namespace, which is the same behavior of PLUMED <=2.4,
+     366             :     and is consistent with what happens when linking PLUMED as a shared library.
+     367             :   - `PLUMED_LOAD_NODEEPBIND` can be set to load the PLUMED kernel in not-deepbind mode. Deepbind
+     368             :     mode implies that the symbols defined in the library are preferred to other symbols with the same name.
+     369             :     Only works on systems supporting `RTLD_DEEPBIND` and is mostly for debugging purposes.
+     370             : 
+     371             :   Another difference is that the implementation of the wrappers is now completely contained in the `Plumed.h`
+     372             :   file. You can see that the `Plumed.c` is much simpler now and just includes `Plumed.h`. With a similar
+     373             :   procedure you could compile the wrappers directly into your code making it unnecessary to link
+     374             :   the libplumedWrapper.a library. The corresponding macros are still subject to change and are not documented here.
+     375             : 
+     376             :   As written above, the plumed object now implements a reference counter.  Consider the following example
+     377             : \verbatim
+     378             :   plumed p=plumed_create();
+     379             :   plumed_cmd(p,"init",NULL);
+     380             :   plumed q=plumed_create_reference(p);
+     381             :   plumed_finalize(p);
+     382             : // at this stage, object q still exists
+     383             :   plumed_cmd(q,"whatever",NULL);
+     384             :   plumed_finalize(q);
+     385             : // now plumed has been really finalized
+     386             : \endverbatim
+     387             : 
+     388             :   In other words, every \ref plumed_create, \ref plumed_create_dlopen, \ref plumed_create_reference,
+     389             :   \ref plumed_create_reference_f, and \ref plumed_create_reference_v call must be matched by a \ref plumed_finalize.
+     390             :   Notice that in C++ whenever an object goes out of scope the reference counter
+     391             :   will be decreased. In addition, consider that conversion from C/FORTRAN/void* to C++ implies calling a C++ constructor, that
+     392             :   is increases the number of references by one. Converting from C++ to C/FORTRAN/void* instead does not call any constructor,
+     393             :   that is the number of references is unchanged.
+     394             : 
+     395             :   The change in the behavior of C++ constructors means that the following code will behave in a backward incompatible manner:
+     396             : \verbatim
+     397             :   plumed p=plumed_create();
+     398             :   plumed_cmd(p,"init",NULL);
+     399             :   Plumed q(p);
+     400             :   plumed_finalize(p);
+     401             : // at this stage, object q still exists with PLUMED 2.5
+     402             : // on the other hand, with PLUMED 2.4 object q refers to an
+     403             : // already finalized object
+     404             :   q.cmd("whatever",NULL);
+     405             : \endverbatim
+     406             : 
+     407             :   Another difference is that the value of the variable `PLUMED_KERNEL` is read every time a new
+     408             :   plumed object is instantiated. So, you might even use it to load different plumed versions
+     409             :   simultaneously, although the preferred way to do this is using the function \ref plumed_create_dlopen.
+     410             :   Notice that if you want to load multiple versions simultaneously you should load them in a local namespace.
+     411             :   \ref plumed_create_dlopen does it automatically, whereas loading through env var `PLUMED_KERNEL` only does it if
+     412             :   you also set env var `PLUMED_NAMESPACE=LOCAL`.
+     413             : 
+     414             :   Finally, a few functions have been added, namely:
+     415             :   - Functions to find if a plumed object is valid
+     416             :     (\ref plumed_valid(), \ref plumed_gvalid(), \ref PLMD::Plumed::valid(), and \ref PLMD::Plumed::gvalid()).
+     417             :   - Functions to create a plumed object based on the path of a specific kernel
+     418             :     (\ref plumed_create_dlopen() and \ref PLMD::Plumed::dlopen()).
+     419             :   - Functions to create a plumed object referencing to another one, implementing a reference counter
+     420             :     (\ref plumed_create_reference(), \ref plumed_create_reference_v(), \ref plumed_create_reference_f().
+     421             : 
+     422             : */
+     423             : 
+     424             : /* BEGINNING OF DECLARATIONS */
+     425             : 
+     426             : /* SETTING DEFAULT VALUES FOR CONTROL MACROS */
+     427             : 
+     428             : /*
+     429             :   1: make the C wrapper functions extern (default)
+     430             :   0: make the C wrapper functions static (C) or inline (C++)
+     431             : 
+     432             :   If set to zero, it disables all functions that only make sense as extern, such as
+     433             :   Fortran wrappers, global objects, and plumed_kernel_register.
+     434             : 
+     435             :   It can be set to zero to include multiple copies of the wrapper implementation without worrying
+     436             :   about duplicated symbols.
+     437             : 
+     438             :   Notice that C++ wrappers are always inline. What this function controls is if the C wrappers
+     439             :   (called by the C++ wrappers) is inline or not. Also consider that if this header is compiled
+     440             :   with C++ and inline C wrappers, the C wrappers will be actually compiled with C++ linkage
+     441             :   in the root namespace.
+     442             : 
+     443             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     444             : */
+     445             : 
+     446             : #ifndef __PLUMED_WRAPPER_EXTERN
+     447             : #define __PLUMED_WRAPPER_EXTERN 1
+     448             : #endif
+     449             : 
+     450             : /*
+     451             :   1: emit global plumed object and related functions (default)
+     452             :   0: do not emit global plumed object and related functions
+     453             : 
+     454             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     455             : */
+     456             : 
+     457             : #ifndef __PLUMED_WRAPPER_GLOBAL
+     458             : #define __PLUMED_WRAPPER_GLOBAL 1
+     459             : #endif
+     460             : 
+     461             : /*
+     462             :   1: Enable typesafe C interface (default)
+     463             :   0: Disable typesafe C interface
+     464             : 
+     465             :   Only used in declarations. Requires C11 _Generic and variadic macros, and so it is
+     466             :   disabled by default with C++ and pre C11 compilers.
+     467             : 
+     468             :   https://mort.coffee/home/c-compiler-quirks/
+     469             : */
+     470             : 
+     471             : #ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     472             : #  if defined(__STDC_VERSION__)
+     473             : #    if ! defined(__cplusplus) && __STDC_VERSION__ >= 201112L
+     474             : #      if defined(__GNUC__) && !defined(__clang__)
+     475             : #        if (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
+     476             : #          define __PLUMED_WRAPPER_C_TYPESAFE 1
+     477             : #        endif
+     478             : #      else
+     479             : #        define __PLUMED_WRAPPER_C_TYPESAFE 1
+     480             : #      endif
+     481             : #    endif
+     482             : #  endif
+     483             : #  ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     484             : #    define __PLUMED_WRAPPER_C_TYPESAFE 0
+     485             : #  endif
+     486             : #endif
+     487             : 
+     488             : /*
+     489             :   1: Enable RTLD_DEEPBIND when possible (default)
+     490             :   0: Disable RTLD_DEEPBIND
+     491             : */
+     492             : 
+     493             : #ifndef __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+     494             : #define __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND 1
+     495             : #endif
+     496             : 
+     497             : /*
+     498             :   1: enable C++ wrapper (default)
+     499             :   0: disable C++ wrapper
+     500             : 
+     501             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     502             : */
+     503             : 
+     504             : #ifndef __PLUMED_WRAPPER_CXX
+     505             : #define __PLUMED_WRAPPER_CXX 1
+     506             : #endif
+     507             : 
+     508             : /*
+     509             :   1: new headers such as cstdlib are included in C++ (default)
+     510             :   0: old headers such as stdlib.h are included in C++
+     511             : 
+     512             :   Should only be set to zero when including the Plumed.h file in a file using the
+     513             :   old (stdlib.h) convention.
+     514             : 
+     515             :   Used both in declarations and definitions.
+     516             : */
+     517             : 
+     518             : #ifndef __PLUMED_WRAPPER_CXX_STD
+     519             : #define __PLUMED_WRAPPER_CXX_STD 1
+     520             : #endif
+     521             : 
+     522             : /*
+     523             :   1: place C++ wrappers in an anonymous namespace
+     524             :   0: place C++ wrappers in the PLMD namespace (default)
+     525             : 
+     526             :   It will make PLMD::Plumed a different class (though with the same name)
+     527             :   in each of the translation units in which `Plumed.h` is included.
+     528             : 
+     529             :   Can be used to completey separate C++ implementations. However, it will make
+     530             :   it impossible to transfer Plumed objects between different translation units
+     531             :   without converting to a void* or plumed object.
+     532             : 
+     533             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     534             : */
+     535             : 
+     536             : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE
+     537             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 0
+     538             : #endif
+     539             : 
+     540             : /*
+     541             :   1: make PLMD::Plumed class polymorphic (default)
+     542             :   0: make PLMD::Plumed class non-polymorphic
+     543             : 
+     544             :   Only used in declarations.
+     545             : */
+     546             : 
+     547             : #ifndef __PLUMED_WRAPPER_CXX_POLYMORPHIC
+     548             : #define __PLUMED_WRAPPER_CXX_POLYMORPHIC 1
+     549             : #endif
+     550             : 
+     551             : /*
+     552             :   1: Enable typesafe interface (default)
+     553             :   0: Disable typesafe interface
+     554             : 
+     555             :   Only used in declarations.
+     556             : */
+     557             : 
+     558             : #ifndef __PLUMED_WRAPPER_CXX_TYPESAFE
+     559             : #define __PLUMED_WRAPPER_CXX_TYPESAFE 1
+     560             : #endif
+     561             : 
+     562             : /*
+     563             :   1: Define macros plumed_cmd and plumed_gcmd to use the C++ interface (default).
+     564             :   0: Don't define macros plumed_cmd and plumed_gcmd.
+     565             : 
+     566             :   Only used in declarations.
+     567             : */
+     568             : 
+     569             : #ifndef __PLUMED_WRAPPER_CXX_BIND_C
+     570             : #define __PLUMED_WRAPPER_CXX_BIND_C 1
+     571             : #endif
+     572             : 
+     573             : /*
+     574             :   1: Enable passing long long int
+     575             :   0: Disable passing long long int
+     576             : 
+     577             :   Only used in declarations. Default is 0 in C++<11 and 1 in C++>=11
+     578             : */
+     579             : 
+     580             : #ifndef __PLUMED_WRAPPER_CXX_LONGLONG
+     581             : #if __cplusplus > 199711L
+     582             : #define __PLUMED_WRAPPER_CXX_LONGLONG 1
+     583             : #else
+     584             : #define __PLUMED_WRAPPER_CXX_LONGLONG 0
+     585             : #endif
+     586             : #endif
+     587             : 
+     588             : /*
+     589             :   1: make the default constructor create an invalid object
+     590             :   0: make the default constructor create a valid object
+     591             : 
+     592             :   Only for internal usage.
+     593             : */
+     594             : #ifndef __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+     595             : #define __PLUMED_WRAPPER_CXX_DEFAULT_INVALID 0
+     596             : #endif
+     597             : 
+     598             : /*
+     599             :   Size of a buffer used to store message for exceptions with noexcept constructor.
+     600             :   Should typically hold short messages. Anyway, as long as the stack size stays within the correct
+     601             :   limits it does not seem to affect efficiency. Notice that there cannot be recursive calls of
+     602             :   PLMD::Plumed::cmd, so that it should be in practice irrelevant.
+     603             : */
+     604             : #ifndef __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER
+     605             : #define __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER 512
+     606             : #endif
+     607             : 
+     608             : /*
+     609             :  By default, assume C++11 compliant library is not available.
+     610             : */
+     611             : 
+     612             : #ifndef __PLUMED_WRAPPER_LIBCXX11
+     613             : #define __PLUMED_WRAPPER_LIBCXX11 0
+     614             : #endif
+     615             : 
+     616             : /* The following macros are just to define shortcuts */
+     617             : 
+     618             : /* Simplify addition of extern "C" blocks.  */
+     619             : #ifdef __cplusplus
+     620             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN extern "C" {
+     621             : #define __PLUMED_WRAPPER_EXTERN_C_END }
+     622             : #else
+     623             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN
+     624             : #define __PLUMED_WRAPPER_EXTERN_C_END
+     625             : #endif
+     626             : 
+     627             : /* Without C++, stdlib functions should not be prepended with ::std:: */
+     628             : #ifndef __cplusplus
+     629             : #undef __PLUMED_WRAPPER_CXX_STD
+     630             : #define __PLUMED_WRAPPER_CXX_STD 0
+     631             : #endif
+     632             : 
+     633             : /* Set prefix for stdlib functions */
+     634             : #if __PLUMED_WRAPPER_CXX_STD
+     635             : #define __PLUMED_WRAPPER_STD ::std::
+     636             : #else
+     637             : #define __PLUMED_WRAPPER_STD
+     638             : #endif
+     639             : 
+     640             : /* Allow using noexcept, explicit, and override with C++11 compilers */
+     641             : #ifdef __cplusplus /*{*/
+     642             : #if __cplusplus > 199711L
+     643             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT noexcept
+     644             : #define __PLUMED_WRAPPER_CXX_NORETURN [[ noreturn ]]
+     645             : #define __PLUMED_WRAPPER_CXX_EXPLICIT explicit
+     646             : #define __PLUMED_WRAPPER_CXX_OVERRIDE override
+     647             : #define __PLUMED_WRAPPER_CXX_NULLPTR  nullptr
+     648             : #else
+     649             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT throw()
+     650             : #define __PLUMED_WRAPPER_CXX_NORETURN
+     651             : #define __PLUMED_WRAPPER_CXX_EXPLICIT
+     652             : #define __PLUMED_WRAPPER_CXX_OVERRIDE
+     653             : #define __PLUMED_WRAPPER_CXX_NULLPTR  NULL
+     654             : #endif
+     655             : #else
+     656             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT
+     657             : #define __PLUMED_WRAPPER_CXX_NORETURN
+     658             : #define __PLUMED_WRAPPER_CXX_EXPLICIT
+     659             : #define __PLUMED_WRAPPER_CXX_OVERRIDE
+     660             : #define __PLUMED_WRAPPER_CXX_NULLPTR  NULL
+     661             : #endif /*}*/
+     662             : 
+     663             : /* static inline, for to avoid compiler warnings */
+     664             : #if defined(__cplusplus) || __STDC_VERSION__>=199901L
+     665             : #define __PLUMED_WRAPPER_STATIC_INLINE static inline
+     666             : #else
+     667             : #define __PLUMED_WRAPPER_STATIC_INLINE static
+     668             : #endif
+     669             : 
+     670             : /* Macros for anonymous namespace */
+     671             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE && defined(__cplusplus) /*{*/
+     672             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN namespace {
+     673             : #define __PLUMED_WRAPPER_ANONYMOUS_END }
+     674             : #else
+     675             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN
+     676             : #define __PLUMED_WRAPPER_ANONYMOUS_END
+     677             : #endif /*}*/
+     678             : 
+     679             : #if __PLUMED_WRAPPER_EXTERN /*{*/
+     680             : 
+     681             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN extern
+     682             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_EXTERN_C_END
+     683             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN static
+     684             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_EXTERN_C_END
+     685             : 
+     686             : #else
+     687             : 
+     688             : #ifdef __cplusplus
+     689             : #define __PLUMED_WRAPPER_C_BEGIN  __PLUMED_WRAPPER_ANONYMOUS_BEGIN inline
+     690             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_ANONYMOUS_END
+     691             : #else
+     692             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_STATIC_INLINE
+     693             : #define __PLUMED_WRAPPER_C_END
+     694             : #endif
+     695             : 
+     696             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_C_BEGIN
+     697             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_C_END
+     698             : 
+     699             : /* with an not-external interface, it does not make sense to define global functions */
+     700             : #undef __PLUMED_WRAPPER_GLOBAL
+     701             : #define __PLUMED_WRAPPER_GLOBAL 0
+     702             : 
+     703             : #endif /*}*/
+     704             : 
+     705             : #if __PLUMED_WRAPPER_CXX_STD
+     706             : #include <cstddef> /* size_t */
+     707             : #include <cstring> /* memcpy */
+     708             : #include <cstdlib> /* malloc free */
+     709             : #else
+     710             : #include <stddef.h>
+     711             : #include <string.h>
+     712             : #include <stdlib.h>
+     713             : #include <stdio.h> /* FILE */
+     714             : #include <limits.h> /* CHAR_MIN */
+     715             : #endif
+     716             : 
+     717             : /**
+     718             :   \brief Main plumed object
+     719             : 
+     720             :   This is an object containing a Plumed instance, which should be used in
+     721             :   the MD engine. It should first be initialized with plumed_create(),
+     722             :   then it communicates with the MD engine using plumed_cmd(). Finally,
+     723             :   before the termination, it should be deallocated with plumed_finalize().
+     724             :   Its interface is very simple and general, and is expected
+     725             :   not to change across plumed versions. See \ref ReferencePlumedH.
+     726             : */
+     727             : typedef struct {
+     728             :   /**
+     729             :     \private
+     730             :     \brief Void pointer holding the real PlumedMain structure
+     731             : 
+     732             :     To maintain binary compatibility, we should not add members to this structure.
+     733             :     As of PLUMED 2.5, in order to add new components we do not store the pointer
+     734             :     to \ref PlumedMain here but rather a pointer to an intermediate private structure
+     735             :     that contains all the details.
+     736             :   */
+     737             :   void*p;
+     738             : } plumed;
+     739             : 
+     740             : typedef struct {
+     741             :   void* ptr;
+     742             :   void (*handler)(void*,int,const char*,const void*);
+     743             : } plumed_nothrow_handler;
+     744             : 
+     745             : /** \relates plumed
+     746             :     \brief Structure holding a typesafe pointer.
+     747             : */
+     748             : 
+     749             : typedef struct {
+     750             :   /** Pointer to data */
+     751             :   const void* ptr;
+     752             :   /** Number of elements (in case pointing to an array) */
+     753             :   __PLUMED_WRAPPER_STD size_t nelem;
+     754             :   /** Shape (scanned up to a zero value is found) */
+     755             :   const __PLUMED_WRAPPER_STD size_t* shape;
+     756             :   /**
+     757             :     sum of:
+     758             :     sizeof(pointed data), up to 0x10000 (65536). 0 means size not checked
+     759             :     0x10000    * data type, up to 0xff (255)
+     760             :                0 not typechecked
+     761             :                1 void
+     762             :                2 nullptr
+     763             :                3 integral
+     764             :                4 floating point
+     765             :                5 FILE (size will not be computed as it might be incomplete)
+     766             :                >5 not typechecked, reserved for future extensions
+     767             :     0x1000000  * 1 for unsigned (ignored)
+     768             :     0x2000000  * pointer/const type, up to 8
+     769             :                0 not typechecked
+     770             :                1 T (pass-by-value)
+     771             :                2 T       *
+     772             :                3 T const *
+     773             :                4 T       *       *
+     774             :                5 T       * const *
+     775             :                6 T const *       *
+     776             :                7 T const * const *
+     777             :     0x10000000 * 1 to forbid pointer copy (pointer copy is also forbidden for pass-by-value)
+     778             :     0x20000000 and higher bits are ignored, reserved for future extensions
+     779             :   */
+     780             :   __PLUMED_WRAPPER_STD size_t flags;
+     781             :   /** Optional information, not used yet  */
+     782             :   const void* opt;
+     783             : } plumed_safeptr;
+     784             : 
+     785             : /**
+     786             :   Small structure that is only defined locally to retrieve errors.
+     787             : 
+     788             :   It is supposed to be used in the C11/C++ plumed_cmd interface as follows:
+     789             : \verbatim
+     790             :   plumed p;
+     791             :   plumed_error error;
+     792             : 
+     793             :   p=plumed_create();
+     794             : 
+     795             :   plumed_cmd(p,"setNatoms",10,&error);
+     796             :   if(error.code) {
+     797             :     fprintf(errors,"%d\n",error.code);
+     798             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     799             :   }
+     800             :   // if no error was raised (error.code==0), it is not necessary to call plumed_error_finalize.
+     801             :   // but doing it is harmless
+     802             : 
+     803             :   // no need to initialize error, it is written in the plumed_cmd function
+     804             :   plumed_cmd(p,"init",&error);
+     805             :   if(error.code) {
+     806             :     fprintf(errors,"%d\n",error.code);
+     807             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     808             :   }
+     809             : \endverbatim
+     810             : 
+     811             :   The layout of this structure is subject to change, and functions manipulating it
+     812             :   are defined as inline/static functions.
+     813             : */
+     814             : typedef struct {
+     815             :   /** code used for translating messages */
+     816             :   int code;
+     817             :   /** message */
+     818             :   const char* what;
+     819             :   /** error code for system_error */
+     820             :   int error_code;
+     821             :   /** the buffer containing the message to be deallocated */
+     822             :   char* what_buffer;
+     823             : } plumed_error;
+     824             : 
+     825             : /** Initialize error (for internal usage) */
+     826             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_init(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     827             :   if(!error) return;
+     828           0 :   error->code=0;
+     829           0 :   error->what=__PLUMED_WRAPPER_CXX_NULLPTR;
+     830           0 :   error->error_code=0;
+     831           0 :   error->what_buffer=__PLUMED_WRAPPER_CXX_NULLPTR;
+     832             : }
+     833             : 
+     834             : /** Finalize error - should be called when an error is raised to avoid leaks */
+     835             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_finalize(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     836             :   if(error.what_buffer) {
+     837             :     __PLUMED_WRAPPER_STD free(error.what_buffer);
+     838             :   }
+     839             : }
+     840             : 
+     841             : /** Callback (for internal usage) */
+     842           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set(void*ptr,int code,const char*what,const void* opt) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     843             :   plumed_error* error;
+     844             :   __PLUMED_WRAPPER_STD size_t len;
+     845             :   const void*const* options;
+     846             : 
+     847             :   error=(plumed_error*) ptr;
+     848             : 
+     849           0 :   error->code=code;
+     850           0 :   error->error_code=0;
+     851           0 :   len=__PLUMED_WRAPPER_STD strlen(what);
+     852           0 :   error->what_buffer=(char*) __PLUMED_WRAPPER_STD malloc(len+1);
+     853           0 :   if(!error->what_buffer) {
+     854           0 :     error->what="cannot allocate error object";
+     855           0 :     error->code=11400;
+     856           0 :     return;
+     857             :   }
+     858             :   __PLUMED_WRAPPER_STD strncpy(error->what_buffer,what,len+1);
+     859             : 
+     860           0 :   error->what=error->what_buffer;
+     861             : 
+     862             :   /* interpret optional arguments */
+     863             :   options=(const void*const*)opt;
+     864           0 :   if(options) while(*options) {
+     865           0 :       if(*((const char*)*options)=='c') error->error_code=*((const int*)*(options+1));
+     866           0 :       options+=2;
+     867             :     }
+     868             : }
+     869             : 
+     870             : /** \relates plumed
+     871             :     \brief Constructor
+     872             : 
+     873             :     Constructs a plumed object.
+     874             : 
+     875             :     Notice that if you are linking against libplumedWrapper.a, if you are
+     876             :     using a code patched in runtime mode, or if you are including the `Plumed.c`
+     877             :     file directly in your code, this constructor might return an invalid plumed
+     878             :     object. In particular, this could happen if the `PLUMED_KERNEL` environment
+     879             :     variable is not set or set incorrectly. In order to detect an incorrect
+     880             :     plumed object you might use \ref plumed_valid() on the resulting object.
+     881             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+     882             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+     883             :     to finalize a plumed object even if it is invalid:
+     884             : \verbatim
+     885             :   plumed p=plumed_create();
+     886             :   if(!plumed_valid(p)) {
+     887             : // this will happen if the PLUMED_KERNEL variable is not set correctly
+     888             :     plumed_finalize(p);
+     889             :     return whatever;
+     890             :   }
+     891             : \endverbatim
+     892             : 
+     893             :     \return The constructed plumed object
+     894             : */
+     895             : __PLUMED_WRAPPER_C_BEGIN
+     896             : plumed plumed_create(void);
+     897             : __PLUMED_WRAPPER_C_END
+     898             : 
+     899             : /** \relates plumed
+     900             :     \brief Constructor from path. Available as of PLUMED 2.5
+     901             : 
+     902             :     It tries to construct a plumed object loading the kernel located at path.
+     903             :     Notice that it could leave the resulting object in an invalid state.
+     904             :     In order to detect an invalid
+     905             :     plumed object you might use \ref plumed_valid() on the resulting object.
+     906             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+     907             : 
+     908             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+     909             :     to finalize a plumed object even if it is invalid.
+     910             : \verbatim
+     911             :   plumed p=plumed_create(path);
+     912             :   if(!plumed_valid(p)) {
+     913             : // this will happen if the path argument is not set correctly
+     914             :     plumed_finalize(p);
+     915             :     return whatever;
+     916             :   }
+     917             : \endverbatim
+     918             : 
+     919             :     \return The constructed plumed object
+     920             : */
+     921             : __PLUMED_WRAPPER_C_BEGIN
+     922             : plumed plumed_create_dlopen(const char*path);
+     923             : __PLUMED_WRAPPER_C_END
+     924             : 
+     925             : 
+     926             : /**
+     927             :   \brief Constructor from path. Available as of PLUMED 2.5
+     928             : 
+     929             :   Same as \ref plumed_create_dlopen, but also allows to specify the mode for dlopen.
+     930             : 
+     931             :   \warning
+     932             :   Use with care, since not all the possible modes work correctly with PLUMED.
+     933             : */
+     934             : __PLUMED_WRAPPER_C_BEGIN
+     935             : plumed plumed_create_dlopen2(const char*path,int mode);
+     936             : __PLUMED_WRAPPER_C_END
+     937             : 
+     938             : /**
+     939             :   \brief Constructor from dlopen handle. Available as of PLUMED 2.8
+     940             : 
+     941             :   Same as  \ref plumed_create_dlopen, but it acts on an already loaded library.
+     942             :   This allows to separate the library loading from the construction of the
+     943             :   plumed object. By using this function, the caller takes the responsibility
+     944             :   to later use dlclose on this handle.
+     945             : */
+     946             : __PLUMED_WRAPPER_C_BEGIN
+     947             : plumed plumed_create_dlsym(void* dlhandle);
+     948             : __PLUMED_WRAPPER_C_END
+     949             : 
+     950             : /** \relates plumed
+     951             :     Create a new reference to an existing object, increasing its reference count. Available as of PLUMED 2.5
+     952             : 
+     953             :     Use it to increase by one the reference count of a plumed object.
+     954             :     The resulting pointer might be identical to the one passed as an
+     955             :     argument, but the reference count will be incremented by one.
+     956             :     Notice that you should finalize the resulting object.
+     957             : \verbatim
+     958             :   plumed p1;
+     959             :   plumed p2;
+     960             :   p1=plumed_create();
+     961             :   p2=plumed_create_reference(p1);
+     962             :   plumed_finalize(p1);
+     963             : // now you can still use p2
+     964             :   plumed_cmd(p2,"init",NULL);
+     965             :   plumed_finalize(p2);
+     966             : // now the underlying object is destroyed.
+     967             : \endverbatim
+     968             : 
+     969             :     If the `p` object is invalid, also the returned object will be invalid.
+     970             : 
+     971             :     \param p The plumed object that will be referenced to.
+     972             :     \return The constructed plumed object
+     973             : */
+     974             : 
+     975             : __PLUMED_WRAPPER_C_BEGIN
+     976             : plumed plumed_create_reference(plumed p);
+     977             : __PLUMED_WRAPPER_C_END
+     978             : 
+     979             : /** \relates plumed
+     980             :     \brief Create a new reference to an existing object passed as a void pointer, increasing its reference count. Available as of PLUMED 2.5
+     981             : 
+     982             :   \return The constructed plumed object
+     983             : */
+     984             : 
+     985             : __PLUMED_WRAPPER_C_BEGIN
+     986             : plumed plumed_create_reference_v(void*v);
+     987             : __PLUMED_WRAPPER_C_END
+     988             : 
+     989             : /** \relates plumed
+     990             :     \brief Create a new reference to an existing object passed as a fortran string, increasing its reference count. Available as of PLUMED 2.5
+     991             : 
+     992             :   \return The constructed plumed object
+     993             : */
+     994             : 
+     995             : __PLUMED_WRAPPER_C_BEGIN
+     996             : plumed plumed_create_reference_f(const char*f);
+     997             : __PLUMED_WRAPPER_C_END
+     998             : 
+     999             : /** \relates plumed
+    1000             :     \brief Constructor as invalid. Available as of PLUMED 2.5
+    1001             : 
+    1002             :    Can be used to create an object in the same state as if it was returned by
+    1003             :    plumed_create_dlopen with an incorrect path (or plumed_create using runtime binding
+    1004             :    and an incorrect PLUMED_KERNEL).
+    1005             : 
+    1006             :    Can be used to initialize a plumed object to a well-defined state without explicitly
+    1007             :    creating it. The resulting object can be checked later with \ref plumed_valid.
+    1008             :    Consider the following example
+    1009             : \verbatim
+    1010             :     plumed p;
+    1011             :     p=plumed_create_invalid();
+    1012             : // at this point p is initialized to a well-defined (invalid) state.
+    1013             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    1014             :     plumed_finalize(p);
+    1015             :     p=plumed_create();
+    1016             : \endverbatim
+    1017             : 
+    1018             :     \return The constructed plumed object
+    1019             : */
+    1020             : 
+    1021             : __PLUMED_WRAPPER_C_BEGIN
+    1022             : plumed plumed_create_invalid();
+    1023             : __PLUMED_WRAPPER_C_END
+    1024             : 
+    1025             : /** \relates plumed
+    1026             :     \brief Tells p to execute a command.
+    1027             : 
+    1028             :     If the object is not valid (see \ref plumed_valid), this command will exit.
+    1029             : 
+    1030             :     \param p The plumed object on which command is acting
+    1031             :     \param key The name of the command to be executed
+    1032             :     \param val The argument. It is declared as const to allow calls like plumed_cmd(p,"A","B"),
+    1033             :                but for some choice of key it can change the content.
+    1034             : 
+    1035             :     Notice that within PLUMED we use a const_cast to remove any const qualifier from the second
+    1036             :     argument of \ref plumed_cmd.
+    1037             : 
+    1038             :     In some cases val can be omitted: just pass a NULL pointer (in C++, val is optional and can be omitted,
+    1039             :     or you can equivalently pass NULL or nullptr).
+    1040             :     The set of possible keys is the real API of the plumed library, and will be expanded with time.
+    1041             :     New commands will be added, but backward compatibility will be retained as long as possible.
+    1042             : */
+    1043             : 
+    1044             : __PLUMED_WRAPPER_C_BEGIN
+    1045             : void plumed_cmd(plumed p,const char*key,const void*val);
+    1046             : __PLUMED_WRAPPER_C_END
+    1047             : 
+    1048             : /**
+    1049             :   \relates plumed
+    1050             :   \brief Same as \ref plumed_cmd, but does not throw exceptions.
+    1051             : 
+    1052             :   This function is meant to be used when errors should be handled explicitly.
+    1053             :   if an exception is raised within PLUMED, the function nothrow.handler() will
+    1054             :   be called with arguments (nothrow.ptr,code,message,opt). This allows the C++ interface
+    1055             :   to correctly rethrow exceptions, but might be used from C as well. opt can be used
+    1056             :   to pass further information (not used yet).
+    1057             : */
+    1058             : 
+    1059             : __PLUMED_WRAPPER_C_BEGIN
+    1060             : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow);
+    1061             : __PLUMED_WRAPPER_C_END
+    1062             : 
+    1063             : __PLUMED_WRAPPER_C_BEGIN
+    1064             : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr,plumed_nothrow_handler nothrow);
+    1065             : __PLUMED_WRAPPER_C_END
+    1066             : 
+    1067             : __PLUMED_WRAPPER_C_BEGIN
+    1068             : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr);
+    1069             : __PLUMED_WRAPPER_C_END
+    1070             : 
+    1071             : /** \relates plumed
+    1072             :     \brief Destructor.
+    1073             : 
+    1074             :     It must be used for any object created using \ref plumed_create(),
+    1075             :     even if the created object is not valid.
+    1076             : 
+    1077             :     \param p The plumed object to be deallocated
+    1078             : */
+    1079             : 
+    1080             : __PLUMED_WRAPPER_C_BEGIN
+    1081             : void plumed_finalize(plumed p);
+    1082             : __PLUMED_WRAPPER_C_END
+    1083             : 
+    1084             : /** \relates plumed
+    1085             :     \brief Check if plumed is installed (for runtime binding).
+    1086             : 
+    1087             :     Notice that this is equivalent to creating a dummy object and checking if it is valid.
+    1088             : 
+    1089             : \verbatim
+    1090             :   // this:
+    1091             :   //int a=plumed_installed();
+    1092             :   // is equivalent to this:
+    1093             : 
+    1094             :   plumed p=plumed_create();
+    1095             :   int a=plumed_valid(p);
+    1096             :   plumed_finalize(p);
+    1097             : 
+    1098             : \endverbatim
+    1099             : 
+    1100             :     This function is mostly provided for compatibility with PLUMED 2.4, where \ref plumed_valid()
+    1101             :     was not available. Using \ref plumed_valid() is now preferred since it creates a single object
+    1102             :     instead of creating a dummy object that is then discarded.
+    1103             : 
+    1104             :     \return 1 if plumed is installed, 0 otherwise
+    1105             : */
+    1106             : 
+    1107             : __PLUMED_WRAPPER_C_BEGIN
+    1108             : int plumed_installed(void);
+    1109             : __PLUMED_WRAPPER_C_END
+    1110             : 
+    1111             : /** \relates plumed
+    1112             :     \brief Check if plumed object is valid. Available as of PLUMED 2.5
+    1113             : 
+    1114             :     It might return false if plumed is not available at runtime.
+    1115             : 
+    1116             :     \return 1 if plumed is valid, 0 otherwise
+    1117             : */
+    1118             : 
+    1119             : __PLUMED_WRAPPER_C_BEGIN
+    1120             : int plumed_valid(plumed p);
+    1121             : __PLUMED_WRAPPER_C_END
+    1122             : 
+    1123             : /** \relates plumed
+    1124             :     \brief Returns the number of references to the underlying object. Available as of PLUMED 2.5.
+    1125             : */
+    1126             : 
+    1127             : __PLUMED_WRAPPER_C_BEGIN
+    1128             : int plumed_use_count(plumed p);
+    1129             : __PLUMED_WRAPPER_C_END
+    1130             : 
+    1131             : 
+    1132             : /* routines to convert char handler from/to plumed objects */
+    1133             : 
+    1134             : /** \related plumed
+    1135             :     \brief Converts a C handler to a FORTRAN handler
+    1136             : 
+    1137             :     \param p The C handler
+    1138             :     \param c The FORTRAN handler (a char[32])
+    1139             : 
+    1140             :     This function can be used to convert a plumed object created in C to
+    1141             :     a plumed handler that can be used in FORTRAN. Notice that the reference counter
+    1142             :     is not incremented. In other words, the FORTRAN object will be a weak reference.
+    1143             :     If you later finalize the C handler, the FORTRAN handler will be invalid.
+    1144             : \verbatim
+    1145             : #include <plumed/wrapper/Plumed.h>
+    1146             : int main(int argc,char*argv[]){
+    1147             :   plumed p;
+    1148             :   p=plumed_create();
+    1149             :   char fortran_handler[32];
+    1150             :   plumed_c2f(p,fortran_handler);
+    1151             :   printf("DEBUG: this is a string representation for the plumed handler: %s\n",fortran_handler);
+    1152             :   fortran_routine(fortran_handler);
+    1153             :   plumed_finalize(p);
+    1154             :   return 0;
+    1155             : }
+    1156             : \endverbatim
+    1157             :   Here `fortran_routine` is a routine implemented in FORTRAN that manipulates the
+    1158             :   fortran_handler.
+    1159             : */
+    1160             : 
+    1161             : __PLUMED_WRAPPER_C_BEGIN
+    1162             : void   plumed_c2f(plumed p,char* c);
+    1163             : __PLUMED_WRAPPER_C_END
+    1164             : 
+    1165             : /** \related plumed
+    1166             :     \brief Converts a FORTRAN handler to a C handler
+    1167             :     \param c The FORTRAN handler (a char[32])
+    1168             :     \return The C handler
+    1169             : 
+    1170             :     This function can be used to convert a plumed object created in FORTRAN
+    1171             :     to a plumed handler that can be used in C.  Notice that the reference counter
+    1172             :     is not incremented. In other words, the C object will be a weak reference.
+    1173             :     If you later finalize the FORTRAN handler, the C handler will be invalid.
+    1174             : \verbatim
+    1175             : void c_routine(char handler[32]){
+    1176             :   plumed p;
+    1177             :   p=plumed_f2c(handler);
+    1178             :   plumed_cmd(p,"init",NULL);
+    1179             : }
+    1180             : \endverbatim
+    1181             :   Here `c_routine` is a C function that can be called from FORTRAN
+    1182             :   and interact with the provided plumed handler.
+    1183             : */
+    1184             : 
+    1185             : __PLUMED_WRAPPER_C_BEGIN
+    1186             : plumed plumed_f2c(const char* c);
+    1187             : __PLUMED_WRAPPER_C_END
+    1188             : 
+    1189             : /** \related plumed
+    1190             :     \brief Converts a plumed object to a void pointer. Available as of PLUMED 2.5.
+    1191             : 
+    1192             :     It returns a void pointer that can be converted back to a plumed object using \ref plumed_v2c.
+    1193             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1194             :     Notice that an invalid object (see \ref plumed_valid) can be converted to void* and back.
+    1195             : 
+    1196             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1197             : */
+    1198             : 
+    1199             : __PLUMED_WRAPPER_C_BEGIN
+    1200             : void* plumed_c2v(plumed p);
+    1201             : __PLUMED_WRAPPER_C_END
+    1202             : 
+    1203             : 
+    1204             : /** \related plumed
+    1205             :     \brief Converts a void pointer to a plumed object. Available as of PLUMED 2.5.
+    1206             : 
+    1207             :     It returns a plumed object from a void pointer obtained with \ref plumed_c2v.
+    1208             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1209             : 
+    1210             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1211             : */
+    1212             : 
+    1213             : __PLUMED_WRAPPER_C_BEGIN
+    1214             : plumed plumed_v2c(void*);
+    1215             : __PLUMED_WRAPPER_C_END
+    1216             : 
+    1217             : #if ! defined( __cplusplus) /*{*/
+    1218             : 
+    1219             : #if __PLUMED_WRAPPER_C_TYPESAFE /*{*/
+    1220             : 
+    1221             : #define __PLUMED_WRAPPER_C_TYPESAFE_INNER(type_,typen_,flags_) \
+    1222             :   static inline void plumed_cmdnse_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, const size_t* shape,plumed_error* error) { \
+    1223             :     plumed_safeptr safe; \
+    1224             :     plumed_nothrow_handler nothrow; \
+    1225             :     safe.ptr=ptr; \
+    1226             :     safe.nelem=nelem; \
+    1227             :     safe.shape=(const size_t*)shape; \
+    1228             :     safe.flags=flags_; \
+    1229             :     safe.opt=NULL; \
+    1230             :     if(error) { \
+    1231             :       plumed_error_init(error); \
+    1232             :       nothrow.ptr=error; \
+    1233             :       nothrow.handler=plumed_error_set; \
+    1234             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1235             :     } else { \
+    1236             :       plumed_cmd_safe(p,key,safe); \
+    1237             :     } \
+    1238             :   } \
+    1239             :   static inline void plumed_cmdne_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, plumed_error* error) { \
+    1240             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,error); \
+    1241             :   } \
+    1242             :   static inline void plumed_cmdse_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape, plumed_error* error) { \
+    1243             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,error); \
+    1244             :   } \
+    1245             :   static inline void plumed_cmdn_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem) { \
+    1246             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,NULL); \
+    1247             :   } \
+    1248             :   static inline void plumed_cmds_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape) { \
+    1249             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,NULL); \
+    1250             :   } \
+    1251             :   static inline void plumed_cmde_ ## typen_(plumed p,const char*key,type_*ptr, plumed_error* error) { \
+    1252             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,NULL,error); \
+    1253             :   }
+    1254             : 
+    1255             : #define __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,size) \
+    1256             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type,             type_ ## _p,  size | (0x10000*(code)) | (0x2000000*2)) \
+    1257             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const,       type_ ## _c,  size | (0x10000*(code)) | (0x2000000*3)) \
+    1258             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*,            type_ ## _pp, size | (0x10000*(code)) | (0x2000000*4)) \
+    1259             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*const,       type_ ## _pc, size | (0x10000*(code)) | (0x2000000*5)) \
+    1260             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*,      type_ ## _cp, size | (0x10000*(code)) | (0x2000000*6)) \
+    1261             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*const, type_ ## _cc, size | (0x10000*(code)) | (0x2000000*7))
+    1262             : 
+    1263             : #define __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(type,type_,code) __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,0)
+    1264             : 
+    1265             : #define __PLUMED_WRAPPER_C_TYPESAFE_SIZED(type,type_,code) \
+    1266             :   __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,sizeof(type)) \
+    1267             :   static inline void plumed_cmdnse_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, const size_t* shape, plumed_error* error) { \
+    1268             :     plumed_safeptr safe; \
+    1269             :     plumed_nothrow_handler nothrow; \
+    1270             :     (void) nelem; \
+    1271             :     (void) shape; \
+    1272             :     safe.ptr=&val; \
+    1273             :     safe.nelem=1; \
+    1274             :     safe.shape=NULL; \
+    1275             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    1276             :     safe.opt=NULL; \
+    1277             :     if(error) { \
+    1278             :       plumed_error_init(error); \
+    1279             :       nothrow.ptr=error; \
+    1280             :       nothrow.handler=plumed_error_set; \
+    1281             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1282             :     } else { \
+    1283             :       plumed_cmd_safe(p,key,safe); \
+    1284             :     } \
+    1285             :   } \
+    1286             :   static inline void plumed_cmdne_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, plumed_error* error) {  \
+    1287             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,error); \
+    1288             :   } \
+    1289             :   static inline void plumed_cmdse_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape, plumed_error* error) {  \
+    1290             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,error); \
+    1291             :   } \
+    1292             :   static inline void plumed_cmdn_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem) {  \
+    1293             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,NULL); \
+    1294             :   } \
+    1295             :   static inline void plumed_cmds_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape) {  \
+    1296             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,NULL); \
+    1297             :   } \
+    1298             :   static inline void plumed_cmde_ ## type_ ## _v(plumed p,const char*key,type val, plumed_error* error) {  \
+    1299             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,NULL,error); \
+    1300             :   }
+    1301             : 
+    1302             : #define __PLUMED_WRAPPER_C_GENERIC1(flavor,type,typen_) \
+    1303             :     type: plumed_ ## flavor ## _ ## typen_,
+    1304             : 
+    1305             : #define __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1306             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*,             type_ ## _p) \
+    1307             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*,       type_ ## _c) \
+    1308             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type**,            type_ ## _pp) \
+    1309             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*const*,       type_ ## _pc) \
+    1310             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const**,      type_ ## _cp) \
+    1311             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*const*, type_ ## _cc)
+    1312             : 
+    1313             : #define __PLUMED_WRAPPER_C_GENERIC2(flavor,type,type_) \
+    1314             :   __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1315             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type,             type_ ## _v)
+    1316             : 
+    1317             : /// Here we create all the required instances
+    1318             : /// 1: void
+    1319             : /// 3: integral
+    1320             : /// 4: floating
+    1321             : /// 5: FILE
+    1322             : /// 0x100: unsigned
+    1323             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(void,void,1)
+    1324             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(char,char,(CHAR_MIN==0)*0x100+3)
+    1325             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned char,unsigned_char,0x100+3)
+    1326             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(signed char,signed_char,0x100+3)
+    1327             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(short,short,3)
+    1328             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned short,unsigned_short,0x100+3)
+    1329             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(int,int,3)
+    1330             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned int,unsigned_int,0x100+3)
+    1331             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long,long,3)
+    1332             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long,unsigned_long,0x100+3)
+    1333             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long long,long_long,3)
+    1334             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long long,unsigned_long_long,0x100+3)
+    1335             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(float,float,4)
+    1336             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(double,double,4)
+    1337             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long double,long_double,4)
+    1338             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(FILE,FILE,5)
+    1339             : 
+    1340             : static inline void plumed_cmd_null_e(plumed p,const char*key,plumed_error* error,int ignore) {
+    1341             :   (void) ignore;
+    1342             :   plumed_cmde_void_p(p,key,NULL,error);
+    1343             : }
+    1344             : 
+    1345             : #define plumed_cmdnse_inner(flavor,val) _Generic((val), \
+    1346             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,void,void) \
+    1347             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,char,char) \
+    1348             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned char,unsigned_char) \
+    1349             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,signed char,signed_char) \
+    1350             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,short,short) \
+    1351             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned short,unsigned_short) \
+    1352             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,int,int) \
+    1353             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned int,unsigned_int) \
+    1354             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long,long) \
+    1355             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long,unsigned_long) \
+    1356             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long long,long_long) \
+    1357             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long long,unsigned_long_long) \
+    1358             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,float,float) \
+    1359             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,double,double) \
+    1360             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long double,long_double) \
+    1361             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,FILE,FILE) \
+    1362             :     default: plumed_ ## flavor ## _void_c)
+    1363             : 
+    1364             : #define plumed_cmd_2args(p,key) plumed_cmdnse_inner(cmdn,NULL) (p,key,NULL,0)
+    1365             : 
+    1366             : #define plumed_cmd_3args(p,key,X) _Generic((X), \
+    1367             :     plumed_error*: plumed_cmd_null_e, \
+    1368             :     default:       plumed_cmdnse_inner(cmdn,X)) (p,key,X,0)
+    1369             : 
+    1370             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1371             : #define plumed_cmd_4args(p,key,val,X) _Generic(((X)+(size_t)0), \
+    1372             :     const size_t *: plumed_cmdnse_inner(cmds,val), \
+    1373             :     size_t *: plumed_cmdnse_inner(cmds,val), \
+    1374             :     size_t: plumed_cmdnse_inner(cmdn,val), \
+    1375             :     plumed_error*: plumed_cmdnse_inner(cmde,val) \
+    1376             :     ) (p,key,val,X)
+    1377             : 
+    1378             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1379             : #define plumed_cmd_5args(p,key,val,X,error) _Generic(((X)+(size_t)0), \
+    1380             :     const size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1381             :     size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1382             :     size_t: plumed_cmdnse_inner(cmdne,val) \
+    1383             :     ) (p,key,val,X,error)
+    1384             : 
+    1385             : #define __PLUMED_WRAPPER_C_GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
+    1386             : #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__)
+    1387             : 
+    1388             : #define plumed_gcmd_c11(...) plumed_cmd(plumed_global(),__VA_ARGS__)
+    1389             : 
+    1390             : #define __PLUMED_WRAPPER_REDEFINE_CMD plumed_cmd_c11
+    1391             : #define __PLUMED_WRAPPER_REDEFINE_GCMD plumed_gcmd_c11
+    1392             : 
+    1393             : #endif /*}*/
+    1394             : 
+    1395             : #endif /*}*/
+    1396             : 
+    1397             : 
+    1398             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    1399             : 
+    1400             : /* Global C functions are always extern */
+    1401             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    1402             : 
+    1403             : /** \relates plumed
+    1404             :     \brief Retrieves an handler to the global structure.
+    1405             : 
+    1406             :   You can use this if you work on a code that uses the global structure and you want to
+    1407             :   pass to a generic routine an handler to the same structure. E.g.
+    1408             : 
+    1409             : \verbatim
+    1410             :   plumed p=plumed_global();
+    1411             :   some_routine(p);
+    1412             : \endverbatim
+    1413             : */
+    1414             : extern
+    1415             : plumed plumed_global(void);
+    1416             : 
+    1417             : /** \relates plumed
+    1418             :     \brief Check if the global interface has been initialized.
+    1419             : 
+    1420             :     \return 1 if plumed has been initialized, 0 otherwise
+    1421             : */
+    1422             : extern
+    1423             : int plumed_ginitialized(void);
+    1424             : 
+    1425             : /** \relates plumed
+    1426             :     \brief Constructor for the global interface.
+    1427             : 
+    1428             :     \note Equivalent to plumed_create(), but initialize the static global plumed object
+    1429             : */
+    1430             : extern
+    1431             : void plumed_gcreate(void);
+    1432             : 
+    1433             : /** \relates plumed
+    1434             :     \brief Tells to the global interface to execute a command.
+    1435             : 
+    1436             :     \param key The name of the command to be executed
+    1437             :     \param val The argument. It is declared as const to allow calls like plumed_gcmd("A","B"),
+    1438             :                but for some choice of key it can change the content
+    1439             : 
+    1440             :     `plumed_gcmd(a,b);` is equivalent to `plumed_cmd(plumed_global(),a,b);`.
+    1441             : */
+    1442             : extern
+    1443             : void plumed_gcmd(const char* key,const void* val);
+    1444             : 
+    1445             : /** \relates plumed
+    1446             :     \brief Tells to the global interface to execute a command.
+    1447             : 
+    1448             :     \param key The name of the command to be executed
+    1449             :     \param safe A safe pointer
+    1450             : 
+    1451             :     `plumed_gcmd_safe(a,b);` is equivalent to `plumed_cmd_safe(plumed_global(),a,b);`.
+    1452             : */
+    1453             : extern
+    1454             : void plumed_gcmd_safe(const char* key,plumed_safeptr);
+    1455             : 
+    1456             : /** \relates plumed
+    1457             :     \brief Destructor for the global interface.
+    1458             : 
+    1459             :     `plumed_gfinalize(a,b);` is similar to `plumed_finalize(plumed_global(),a,b);`, but not completely
+    1460             :     equivalent. In particular, plumed_gfinalize() also makes sure that the global object
+    1461             :     is reset to its initial status. After calling it, \ref plumed_ginitialized() will thus return 0.
+    1462             : */
+    1463             : extern
+    1464             : void plumed_gfinalize(void);
+    1465             : 
+    1466             : /** \relates plumed
+    1467             :     \brief Check if global plumed object is valid. Available as of PLUMED 2.5
+    1468             : 
+    1469             :     It might return zero if plumed is not available at runtime.
+    1470             : 
+    1471             :     \return 1 if plumed is valid, 0 otherwise.
+    1472             : */
+    1473             : extern
+    1474             : int plumed_gvalid();
+    1475             : 
+    1476             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    1477             : 
+    1478             : #endif /*}*/
+    1479             : 
+    1480             : #if defined( __cplusplus) && __PLUMED_WRAPPER_CXX /*{*/
+    1481             : 
+    1482             : #if __PLUMED_WRAPPER_CXX_STD
+    1483             : #include <cstdlib> /* NULL getenv */
+    1484             : #include <cstddef> /* nullptr_t */
+    1485             : #include <cstring> /* strncat strlen */
+    1486             : #include <cstdio> /* fprintf */
+    1487             : #include <cassert> /* assert */
+    1488             : #include <climits> /* CHAR_MIN */
+    1489             : #else
+    1490             : #include <stddef.h>
+    1491             : #include <stdlib.h>
+    1492             : #include <string.h>
+    1493             : #include <stdio.h>
+    1494             : #include <assert.h>
+    1495             : #include <limits.h>
+    1496             : #endif
+    1497             : 
+    1498             : #include <exception> /* exception bad_exception */
+    1499             : #include <stdexcept> /* runtime_error logic_error invalid_argument domain_error length_error out_of_range range_error overflow_error underflow_error */
+    1500             : #include <string> /* string */
+    1501             : #include <ios> /* iostream_category (C++11) ios_base::failure (C++11 and C++<11) */
+    1502             : #include <new> /* bad_alloc bad_array_new_length (C++11) */
+    1503             : #include <typeinfo> /* bad_typeid bad_cast */
+    1504             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1505             : #include <system_error> /* system_error generic_category system_category */
+    1506             : #include <future> /* future_category */
+    1507             : #include <memory> /* bad_weak_ptr */
+    1508             : #include <functional> /* bad_function_call */
+    1509             : #endif
+    1510             : 
+    1511             : #if __cplusplus > 199711L
+    1512             : #include <array> /* array */
+    1513             : #include <initializer_list> /* initializer_list */
+    1514             : #endif
+    1515             : 
+    1516             : /* C++ interface is hidden in PLMD namespace (same as plumed library) */
+    1517             : namespace PLMD {
+    1518             : 
+    1519             : /* Optionally, it is further hidden in an anonymous namespace */
+    1520             : 
+    1521             : __PLUMED_WRAPPER_ANONYMOUS_BEGIN /*{*/
+    1522             : 
+    1523             : /**
+    1524             :   Retrieve PLUMED_EXCEPTIONS_DEBUG (internal utility).
+    1525             : 
+    1526             :   This function should not be used by external programs. It is defined
+    1527             :   as inline static so that it can store a static variable (for quicker access)
+    1528             :   without adding a unique global symbol to a library including this header file.
+    1529             : */
+    1530           0 : inline static bool PlumedGetenvExceptionsDebug() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1531           0 :   static const char* res=__PLUMED_WRAPPER_STD getenv("PLUMED_EXCEPTIONS_DEBUG");
+    1532           0 :   return res;
+    1533             : }
+    1534             : 
+    1535             : /**
+    1536             :   C++ wrapper for \ref plumed.
+    1537             : 
+    1538             :   This class provides a C++ interface to PLUMED.
+    1539             :   It only containts a \ref plumed object, but wraps it with a number of useful methods.
+    1540             :   All methods are inlined so as to avoid the compilation of an extra c++ file.
+    1541             : 
+    1542             : */
+    1543             : 
+    1544             : class Plumed {
+    1545             :   /**
+    1546             :     C structure.
+    1547             :   */
+    1548             :   plumed main;
+    1549             : 
+    1550             :   /**
+    1551             :     Error handler used to rethrow exceptions.
+    1552             :   */
+    1553             : 
+    1554             :   struct NothrowHandler {
+    1555             :     /** code used for translating messages */
+    1556             :     int code;
+    1557             :     /** short message buffer for non-throwing exceptions */
+    1558             :     char exception_buffer[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER];
+    1559             :     /** if exception_buffer='\0', message stored as an allocatable string */
+    1560             :     ::std::string what;
+    1561             :     /** error code for system_error */
+    1562             :     int error_code;
+    1563             :   };
+    1564             : 
+    1565             :   /**
+    1566             :     Callback function that sets the error handler.
+    1567             : 
+    1568             :     opt argument is interpreted as the pointer to a null terminated array of void*.
+    1569             :     The number of non-null element is expected to be even, and there should be a null element
+    1570             :     that follows. Every pair of pointers should point
+    1571             :     to a char, identifying the type of argument passed, and an arbitrary object.
+    1572             :     Currently used to (optionally) pass error_code.
+    1573             :   */
+    1574           0 :   static void nothrow_handler(void*ptr,int code,const char*what,const void* opt) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1575             :     NothrowHandler* h=static_cast<NothrowHandler*>(ptr);
+    1576           0 :     h->code=code;
+    1577           0 :     h->exception_buffer[0]='\0';
+    1578           0 :     h->what.clear();
+    1579           0 :     h->error_code=0;
+    1580             :     /*
+    1581             :        These codes correspond to exceptions that should not allocate a separate buffer but use the fixed one.
+    1582             :        Notice that a mismatch between the exceptions using the stack buffer here and those implementing
+    1583             :        the stack buffer would be in practice harmless. However, it makes sense to be consistent.
+    1584             :     */
+    1585           0 :     if(code==10000 || (code>=11000 && code<12000)) {
+    1586           0 :       __PLUMED_WRAPPER_STD strncat(h->exception_buffer,what,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1);
+    1587             :     } else {
+    1588             :       try {
+    1589             :         h->what=what; // could throw
+    1590           0 :       } catch(...) {
+    1591           0 :         __PLUMED_WRAPPER_STD strncat(h->exception_buffer,"cannot allocate error object",__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1);
+    1592           0 :         h->code=11400; // bad_alloc
+    1593           0 :       }
+    1594             :     }
+    1595             : 
+    1596             :     /* interpret optional arguments */
+    1597             :     const void*const* options=(const void*const*)opt;
+    1598           0 :     if(options) while(*options) {
+    1599           0 :         if(*((const char*)*options)=='c') h->error_code=*((const int*)*(options+1));
+    1600           0 :         options+=2;
+    1601             :       }
+    1602             : 
+    1603           0 :     if(PlumedGetenvExceptionsDebug()) {
+    1604           0 :       __PLUMED_WRAPPER_STD fprintf(stderr,"+++ PLUMED_EXCEPTIONS_DEBUG\n");
+    1605           0 :       __PLUMED_WRAPPER_STD fprintf(stderr,"+++ code: %d error_code: %d message:\n%s\n",h->code,h->error_code,what);
+    1606           0 :       if(__PLUMED_WRAPPER_STD strlen(what) > __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1) __PLUMED_WRAPPER_STD fprintf(stderr,"+++ WARNING: message will be truncated\n");
+    1607           0 :       __PLUMED_WRAPPER_STD fprintf(stderr,"+++ END PLUMED_EXCEPTIONS_DEBUG\n");
+    1608             :     }
+    1609             : 
+    1610           0 :   }
+    1611             : 
+    1612             :   /**
+    1613             :     Rethrow the exception based on the information saved in the NothrowHandler.
+    1614             :   */
+    1615             : 
+    1616           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow(const NothrowHandler&h) {
+    1617             :     /* The interpretation of the codes should be kept in sync with core/PlumedMainInitializer.cpp */
+    1618             :     /* check if we are using a full string or a fixes size buffer */
+    1619           0 :     const char* msg=(h.exception_buffer[0]?h.exception_buffer:h.what.c_str());
+    1620           0 :     if(h.code==1) throw Plumed::Invalid(msg);
+    1621             :     /* logic errors */
+    1622           0 :     if(h.code>=10100 && h.code<10200) {
+    1623           0 :       if(h.code>=10105 && h.code<10110) throw ::std::invalid_argument(msg);
+    1624           0 :       if(h.code>=10110 && h.code<10115) throw ::std::domain_error(msg);
+    1625           0 :       if(h.code>=10115 && h.code<10120) throw ::std::length_error(msg);
+    1626           0 :       if(h.code>=10120 && h.code<10125) throw ::std::out_of_range(msg);
+    1627           0 :       throw ::std::logic_error(msg);
+    1628             :     }
+    1629             :     /* runtime errors */
+    1630           0 :     if(h.code>=10200 && h.code<10300) {
+    1631           0 :       if(h.code>=10205 && h.code<10210) throw ::std::range_error(msg);
+    1632           0 :       if(h.code>=10210 && h.code<10215) throw ::std::overflow_error(msg);
+    1633           0 :       if(h.code>=10215 && h.code<10220) throw ::std::underflow_error(msg);
+    1634             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1635             :       if(h.code==10220) throw ::std::system_error(h.error_code,::std::generic_category(),msg);
+    1636             :       if(h.code==10221) throw ::std::system_error(h.error_code,::std::system_category(),msg);
+    1637             :       if(h.code==10222) throw ::std::system_error(h.error_code,::std::iostream_category(),msg);
+    1638             :       if(h.code==10223) throw ::std::system_error(h.error_code,::std::future_category(),msg);
+    1639             : #endif
+    1640           0 :       if(h.code>=10230 && h.code<10240) {
+    1641             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1642             : // These cases are probably useless as it looks like this should always be std::iostream_category
+    1643             :         if(h.code==10230) throw ::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::generic_category()));
+    1644             :         if(h.code==10231) throw ::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::system_category()));
+    1645             :         if(h.code==10232) throw ::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::iostream_category()));
+    1646             :         if(h.code==10233) throw ::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::future_category()));
+    1647             : #endif
+    1648           0 :         throw ::std::ios_base::failure(msg);
+    1649             :       }
+    1650           0 :       throw ::std::runtime_error(msg);
+    1651             :     }
+    1652             :     /* "bad" errors */
+    1653           0 :     if(h.code>=11000 && h.code<11100) throw Plumed::std_bad_typeid(msg);
+    1654           0 :     if(h.code>=11100 && h.code<11200) throw Plumed::std_bad_cast(msg);
+    1655             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1656             :     if(h.code>=11200 && h.code<11300) throw Plumed::std_bad_weak_ptr(msg);
+    1657             :     if(h.code>=11300 && h.code<11400) throw Plumed::std_bad_function_call(msg);
+    1658             : #endif
+    1659           0 :     if(h.code>=11400 && h.code<11500) {
+    1660             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1661             :       if(h.code>=11410 && h.code<11420) throw Plumed::std_bad_array_new_length(msg);
+    1662             : #endif
+    1663           0 :       throw Plumed::std_bad_alloc(msg);
+    1664             :     }
+    1665           0 :     if(h.code>=11500 && h.code<11600) throw Plumed::std_bad_exception(msg);
+    1666             :     /* lepton error */
+    1667           0 :     if(h.code>=19900 && h.code<20000) throw Plumed::LeptonException(msg);
+    1668             :     /* plumed exceptions */
+    1669           0 :     if(h.code>=20000 && h.code<30000) {
+    1670             :       /* debug - only raised with debug options */
+    1671           0 :       if(h.code>=20100 && h.code<20200) throw Plumed::ExceptionDebug(msg);
+    1672             :       /* error - runtime check */
+    1673           0 :       if(h.code>=20200 && h.code<20300) throw Plumed::ExceptionError(msg);
+    1674             :       /* error - type error */
+    1675           0 :       if(h.code>=20300 && h.code<20400) throw Plumed::ExceptionTypeError(msg);
+    1676           0 :       throw Plumed::Exception(msg);
+    1677             :     }
+    1678             :     /* fallback for any other exception */
+    1679           0 :     throw Plumed::std_exception(msg);
+    1680             :   }
+    1681             : 
+    1682             :   /**
+    1683             :     Rethrow the current exception.
+    1684             : 
+    1685             :     This is useful in order to handle an exception thrown by a kernel <=2.4.
+    1686             :     Only std exceptions are handled, though some of them are thrown as special
+    1687             :     Plumed exceptions in order to be attached a message.
+    1688             :   */
+    1689           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow() {
+    1690             :     try {
+    1691           0 :       throw;
+    1692           0 :     } catch(const ::std::bad_exception & e) {
+    1693           0 :       throw Plumed::std_bad_exception(e.what());
+    1694             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1695             :     } catch(const ::std::bad_array_new_length & e) {
+    1696             :       throw Plumed::std_bad_array_new_length(e.what());
+    1697             : #endif
+    1698           0 :     } catch(const ::std::bad_alloc & e) {
+    1699           0 :       throw Plumed::std_bad_alloc(e.what());
+    1700             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1701             :     } catch(const ::std::bad_function_call & e) {
+    1702             :       throw Plumed::std_bad_function_call(e.what());
+    1703             :     } catch(const ::std::bad_weak_ptr & e) {
+    1704             :       throw Plumed::std_bad_weak_ptr(e.what());
+    1705             : #endif
+    1706           0 :     } catch(const ::std::bad_cast & e) {
+    1707           0 :       throw Plumed::std_bad_cast(e.what());
+    1708           0 :     } catch(const ::std::bad_typeid & e) {
+    1709           0 :       throw Plumed::std_bad_typeid(e.what());
+    1710             :       // not implemented yet: std::regex_error
+    1711             :       // we do not allow regex yet due to portability problems with gcc 4.8
+    1712             :       // as soon as we transition to using <regex> it should be straightforward to add
+    1713           0 :     } catch(const ::std::ios_base::failure & e) {
+    1714             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1715             :       throw ::std::ios_base::failure(e.what(),e.code());
+    1716             : #else
+    1717           0 :       throw ::std::ios_base::failure(e.what());
+    1718             : #endif
+    1719             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1720             :     } catch(const ::std::system_error & e) {
+    1721             :       throw ::std::system_error(e.code(),e.what());
+    1722             : #endif
+    1723           0 :     } catch(const ::std::underflow_error &e) {
+    1724           0 :       throw ::std::underflow_error(e.what());
+    1725           0 :     } catch(const ::std::overflow_error &e) {
+    1726           0 :       throw ::std::overflow_error(e.what());
+    1727           0 :     } catch(const ::std::range_error &e) {
+    1728           0 :       throw ::std::range_error(e.what());
+    1729           0 :     } catch(const ::std::runtime_error & e) {
+    1730           0 :       throw ::std::runtime_error(e.what());
+    1731             :       // not implemented yet: std::future_error
+    1732             :       // not clear how useful it would be.
+    1733           0 :     } catch(const ::std::out_of_range & e) {
+    1734           0 :       throw ::std::out_of_range(e.what());
+    1735           0 :     } catch(const ::std::length_error & e) {
+    1736           0 :       throw ::std::length_error(e.what());
+    1737           0 :     } catch(const ::std::domain_error & e) {
+    1738           0 :       throw ::std::domain_error(e.what());
+    1739           0 :     } catch(const ::std::invalid_argument & e) {
+    1740           0 :       throw ::std::invalid_argument(e.what());
+    1741           0 :     } catch(const ::std::logic_error & e) {
+    1742           0 :       throw ::std::logic_error(e.what());
+    1743           0 :     } catch(const ::std::exception & e) {
+    1744           0 :       throw Plumed::std_exception(e.what());
+    1745           0 :     } catch(...) {
+    1746           0 :       throw Plumed::std_bad_exception("plumed could not translate exception");
+    1747           0 :     }
+    1748             :   }
+    1749             : 
+    1750             : public:
+    1751             : 
+    1752             :   /**
+    1753             :     Base class used to rethrow PLUMED exceptions.
+    1754             :   */
+    1755             : 
+    1756             :   class Exception :
+    1757             :     public ::std::exception
+    1758             :   {
+    1759             :     ::std::string msg;
+    1760             :   public:
+    1761           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Exception(const char* msg): msg(msg) {}
+    1762           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    1763             : #if ! (__cplusplus > 199711L)
+    1764             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    1765             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    1766             :     ~Exception() throw() {}
+    1767             : #endif
+    1768             :   };
+    1769             : 
+    1770             :   /**
+    1771             :     Used to rethrow a PLMD::ExceptionError
+    1772             :   */
+    1773             : 
+    1774             :   class ExceptionError :
+    1775             :     public Exception {
+    1776             :   public:
+    1777           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionError(const char* msg): Exception(msg) {}
+    1778             : #if ! (__cplusplus > 199711L)
+    1779             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    1780             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    1781             :     ~ExceptionError() throw() {}
+    1782             : #endif
+    1783             :   };
+    1784             : 
+    1785             :   /**
+    1786             :     Used to rethrow a PLMD::ExceptionDebug
+    1787             :   */
+    1788             : 
+    1789             :   class ExceptionDebug :
+    1790             :     public Exception {
+    1791             :   public:
+    1792           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionDebug(const char* msg): Exception(msg) {}
+    1793             : #if ! (__cplusplus > 199711L)
+    1794             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    1795             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    1796             :     ~ExceptionDebug() throw() {}
+    1797             : #endif
+    1798             :   };
+    1799             : 
+    1800             :   /**
+    1801             :     Thrown when trying to access an invalid plumed object
+    1802             :   */
+    1803             : 
+    1804             :   class Invalid :
+    1805             :     public Exception {
+    1806             :   public:
+    1807           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Invalid(const char* msg): Exception(msg) {}
+    1808             : #if ! (__cplusplus > 199711L)
+    1809             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    1810             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    1811             :     ~Invalid() throw() {}
+    1812             : #endif
+    1813             :   };
+    1814             : 
+    1815             :   /**
+    1816             :     Thrown when a wrong pointer is passed to the PLUMED interface.
+    1817             :   */
+    1818             :   class ExceptionTypeError:
+    1819             :     public Exception {
+    1820             :   public:
+    1821           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionTypeError(const char* msg): Exception(msg) {}
+    1822             : #if ! (__cplusplus > 199711L)
+    1823             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    1824             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    1825             :     ~ExceptionTypeError() throw() {}
+    1826             : #endif
+    1827             :   };
+    1828             : 
+    1829             :   /**
+    1830             :     Class used to rethrow Lepton exceptions.
+    1831             :   */
+    1832             : 
+    1833             :   class LeptonException :
+    1834             :     public ::std::exception
+    1835             :   {
+    1836             :     ::std::string msg;
+    1837             :   public:
+    1838           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT LeptonException(const char* msg): msg(msg) {}
+    1839           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    1840             : #if ! (__cplusplus > 199711L)
+    1841             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    1842             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    1843             :     ~LeptonException() throw() {}
+    1844             : #endif
+    1845             :   };
+    1846             : 
+    1847             : private:
+    1848             :   /*
+    1849             :     These exceptions are declared as private as they are not supposed to be
+    1850             :     catched by value. they only exist to allow a buffer to be attached to
+    1851             :     the std::exceptions that do not contain it already.
+    1852             :     Notice that these exceptions are those whose constructor should never throw, and as
+    1853             :     such they use a fixed size buffer.
+    1854             :   */
+    1855             : 
+    1856             : #define __PLUMED_WRAPPER_NOSTRING_EXCEPTION(name) \
+    1857             :   class std_ ## name : \
+    1858             :     public ::std::name \
+    1859             :   { \
+    1860             :     char msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER]; \
+    1861             :   public: \
+    1862             :     __PLUMED_WRAPPER_CXX_EXPLICIT std_ ## name(const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    1863             :       this->msg[0]='\0'; \
+    1864             :       __PLUMED_WRAPPER_STD strncat(this->msg,msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1); \
+    1865             :       if(PlumedGetenvExceptionsDebug() && __PLUMED_WRAPPER_STD strlen(msg) > __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1) __PLUMED_WRAPPER_STD fprintf(stderr,"+++ WARNING: message will be truncated\n"); \
+    1866             :     } \
+    1867             :     std_ ## name(const std_ ## name & other) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    1868             :       msg[0]='\0'; \
+    1869             :       __PLUMED_WRAPPER_STD strncat(msg,other.msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1); \
+    1870             :     } \
+    1871             :     std_ ## name & operator=(const std_ ## name & other) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    1872             :       if(this==&other) return *this;\
+    1873             :       msg[0]='\0'; \
+    1874             :       __PLUMED_WRAPPER_STD strncat(msg,other.msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1); \
+    1875             :       return *this; \
+    1876             :     } \
+    1877             :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg;} \
+    1878             :     ~std_ ## name() __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {} \
+    1879             :   };
+    1880             : 
+    1881           0 :   __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_typeid)
+    1882           0 :   __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_cast)
+    1883             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1884             :   __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_weak_ptr)
+    1885             :   __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_function_call)
+    1886             : #endif
+    1887           0 :   __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_alloc)
+    1888             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1889             :   __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_array_new_length)
+    1890             : #endif
+    1891           0 :   __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_exception)
+    1892           0 :   __PLUMED_WRAPPER_NOSTRING_EXCEPTION(exception)
+    1893             : 
+    1894             : private:
+    1895             :   /// Small class that wraps plumed_safeptr in order to make its initialization easier
+    1896             :   class SafePtr {
+    1897             :     /// non copyable (copy would require managing buffer, could be added in the future if needed)
+    1898             :     SafePtr(const SafePtr&);
+    1899             :     /// non assignable (assignment would require managing buffer, could be added in the future if needed)
+    1900             :     SafePtr& operator=(SafePtr const&);
+    1901             :   public:
+    1902             :     plumed_safeptr safe;
+    1903             :     /// This buffer holds a copy of the data when they are passed by value.
+    1904             :     /// The size is sufficient to hold any primitive type.
+    1905             :     char buffer[32];
+    1906             :     /// Default constructor, nullptr
+    1907             :     SafePtr() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1908             :       safe.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    1909             :       safe.nelem=0;
+    1910             :       safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    1911             :       safe.flags=0x10000*2;
+    1912             :       safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    1913             :       buffer[0]='\0';
+    1914             :     }
+    1915             : 
+    1916         222 :     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 {
+    1917         222 :       this->safe=safe;
+    1918         222 :       buffer[0]='\0';
+    1919             :       if(nelem>0) this->safe.nelem=nelem;
+    1920             :       if(shape) this->safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape);
+    1921             :     }
+    1922             : 
+    1923             : #if __cplusplus > 199711L
+    1924             :     /// Construct from null
+    1925             :     SafePtr(__PLUMED_WRAPPER_STD nullptr_t,__PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) noexcept {
+    1926             :       safe.ptr=nullptr;
+    1927             :       safe.nelem=0;
+    1928             :       safe.shape=nullptr;
+    1929             :       safe.flags=0x10000*2;
+    1930             :       safe.opt=nullptr;
+    1931             :       buffer[0]='\0';
+    1932             :       (void) nelem;
+    1933             :       (void) shape;
+    1934             :     }
+    1935             : #endif
+    1936             : 
+    1937             : /// Macro that generate a constructor with given type and flags
+    1938             : #define __PLUMED_WRAPPER_SAFEPTR_INNER(type_,flags_) \
+    1939             :   SafePtr(type_*ptr, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    1940             :     safe.ptr=ptr; \
+    1941             :     safe.nelem=nelem; \
+    1942             :     safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape); \
+    1943             :     safe.flags=flags_; \
+    1944             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    1945             :     buffer[0]='\0'; \
+    1946             :   }
+    1947             : 
+    1948             : /// Macro that uses __PLUMED_WRAPPER_SAFEPTR_INNER to generate constructors with
+    1949             : /// all possible pointer-const combinations
+    1950             : #define __PLUMED_WRAPPER_SAFEPTR(type,code,size) \
+    1951             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type,             size | (0x10000*(code)) | (0x2000000*2)) \
+    1952             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const,       size | (0x10000*(code)) | (0x2000000*3)) \
+    1953             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*,            size | (0x10000*(code)) | (0x2000000*4)) \
+    1954             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*const,       size | (0x10000*(code)) | (0x2000000*5)) \
+    1955             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*,      size | (0x10000*(code)) | (0x2000000*6)) \
+    1956             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*const, size | (0x10000*(code)) | (0x2000000*7))
+    1957             : 
+    1958             : /// Macro that generates the constructors from empy types (those of which sizeof cannot be computed)
+    1959             : #define __PLUMED_WRAPPER_SAFEPTR_EMPTY(type,code) __PLUMED_WRAPPER_SAFEPTR(type,code,0)
+    1960             : 
+    1961             : /// Macro that generates the constructors from sized types (those of which sizeof can be computed).
+    1962             : /// In addition to generating constructors with all pointer types, it generates a constructor to
+    1963             : /// allow pass-by-value
+    1964             : #define __PLUMED_WRAPPER_SAFEPTR_SIZED(type,code) \
+    1965             :   __PLUMED_WRAPPER_SAFEPTR(type,code,sizeof(type)) \
+    1966             :   SafePtr(type val, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    1967             :     assert(sizeof(type)<=32); \
+    1968             :     (void) nelem; \
+    1969             :     (void) shape; \
+    1970             :     safe.ptr=buffer; \
+    1971             :     safe.nelem=1; \
+    1972             :     safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    1973             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    1974             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    1975             :     __PLUMED_WRAPPER_STD memcpy(buffer,&val,sizeof(type)); \
+    1976             :   }
+    1977             : 
+    1978             : /// Here we create all the required instances
+    1979             : /// 1: void
+    1980             : /// 3: integral
+    1981             : /// 4: floating
+    1982             : /// 5: FILE
+    1983             : /// 0x100: unsigned
+    1984         336 :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(void,1)
+    1985        3441 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(char,(CHAR_MIN==0)*0x100+3)
+    1986             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned char,3)
+    1987             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(signed char,0x100+3)
+    1988             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(short,3)
+    1989             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned short,0x100+3)
+    1990        6882 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(int,3)
+    1991             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned int,0x100+3)
+    1992             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long,3)
+    1993             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long,0x100+3)
+    1994             : #if __PLUMED_WRAPPER_CXX_LONGLONG
+    1995             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long long,3)
+    1996             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long long,0x100+3)
+    1997             : #endif
+    1998             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(float,4)
+    1999             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(double,4)
+    2000             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long double,4)
+    2001             :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(FILE,5)
+    2002             : 
+    2003             :     /// Return the contained plumed_safeptr
+    2004             :     plumed_safeptr get_safeptr() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2005       10881 :       return safe;
+    2006             :     }
+    2007             : 
+    2008             :   };
+    2009             : 
+    2010             : public:
+    2011             : 
+    2012             :   /**
+    2013             :      Check if plumed is installed (for runtime binding)
+    2014             :      \return true if plumed is installed, false otherwise
+    2015             :      \note Equivalent to plumed_installed() but returns a bool
+    2016             :   */
+    2017             :   static bool installed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2018             :     return plumed_installed();
+    2019             :   }
+    2020             :   /**
+    2021             :      Check if Plumed object is valid. Available as of PLUMED 2.5
+    2022             :      \return true if plumed is valid, false otherwise
+    2023             :      \note Equivalent to plumed_valid() but returns a bool
+    2024             :   */
+    2025             :   bool valid() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2026             :     return plumed_valid(main);
+    2027             :   }
+    2028             : #if __cplusplus > 199711L
+    2029             :   /**
+    2030             :      Same as \ref valid(). Available as of PLUMED 2.5.
+    2031             : 
+    2032             :   Allow code such as
+    2033             :   \verbatim
+    2034             :   Plumed p;
+    2035             :   if(!p) raise_error();
+    2036             :   p.cmd("init");
+    2037             :   \endverbatim
+    2038             : 
+    2039             :   In order to avoid ambiguous conversions, this is only allowed when compiling with C++11
+    2040             :   where it is marked as explicit.
+    2041             :   */
+    2042             :   explicit
+    2043             :   operator bool() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2044             :     return plumed_valid(main);
+    2045             :   }
+    2046             : #endif
+    2047             : 
+    2048             :   /**
+    2049             :      Returns the number of references to this object. Available as of PLUMED 2.5.
+    2050             :     \note Equivalent to plumed_use_count()
+    2051             :   */
+    2052             :   int useCount() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2053             :     return plumed_use_count(main);
+    2054             :   }
+    2055             : 
+    2056             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    2057             :   /**
+    2058             :      Check if global-plumed has been initialized
+    2059             :      \return true if global plumed object (see global()) is initialized (i.e. if gcreate() has been
+    2060             :              called), false otherwise.
+    2061             :      \note Equivalent to plumed_ginitialized() but returns a bool
+    2062             :   */
+    2063             :   static bool ginitialized() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2064             :     return plumed_ginitialized();
+    2065             :   }
+    2066             :   /**
+    2067             :      Check if global-plumed is valid
+    2068             :      \return true if global plumed object (see global()) is valid.
+    2069             :      \note Equivalent to plumed_gvalid() but returns a bool
+    2070             :   */
+    2071             :   static bool gvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2072             :     return plumed_gvalid();
+    2073             :   }
+    2074             :   /**
+    2075             :      Initialize global-plumed.
+    2076             :      \warning Using the global objects in C++ is not recommended since they are difficult to use in
+    2077             :               an exception safe manner. In particular, one should explicitly catch exceptions to
+    2078             :               properly call gfinalize()
+    2079             :      \note Equivalent to plumed_gcreate()
+    2080             :   */
+    2081             :   static void gcreate() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2082             :     plumed_gcreate();
+    2083             :   }
+    2084             :   /**
+    2085             :      Send a command to global-plumed
+    2086             :       \param key The name of the command to be executed
+    2087             :      \note Equivalent to plumed_gcmd()
+    2088             :   */
+    2089             :   static void gcmd(const char*key) {
+    2090             :     global().cmd(key);
+    2091             :   }
+    2092             :   /**
+    2093             :      Send a command to global-plumed
+    2094             :       \param key The name of the command to be executed
+    2095             :       \param val The argument.
+    2096             :      \note Equivalent to plumed_gcmd()
+    2097             :   */
+    2098             :   template<typename T>
+    2099             :   static void gcmd(const char*key,T val) {
+    2100             :     global().cmd(key,val);
+    2101             :   }
+    2102             :   /**
+    2103             :      Send a command to global-plumed
+    2104             :       \param key The name of the command to be executed
+    2105             :       \param val The argument.
+    2106             :       \param nelem Number of elements in the passed array, for typechecking.
+    2107             :      \note Equivalent to plumed_gcmd()
+    2108             :   */
+    2109             :   template<typename T>
+    2110             :   static void gcmd(const char*key,T* val,__PLUMED_WRAPPER_STD size_t nelem) {
+    2111             :     global().cmd(key,val,nelem);
+    2112             :   }
+    2113             : 
+    2114             :   /**
+    2115             :      Send a command to global-plumed
+    2116             :       \param key The name of the command to be executed
+    2117             :       \param val The argument.
+    2118             :       \param shape The shape of the argument.
+    2119             :      \note Equivalent to plumed_gcmd()
+    2120             :   */
+    2121             :   template<typename T>
+    2122             :   static void gcmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    2123             :     global().cmd(key,val,shape);
+    2124             :   }
+    2125             : 
+    2126             : #if __cplusplus > 199711L
+    2127             :   /**
+    2128             :      Send a command to global-plumed
+    2129             :       \param key The name of the command to be executed
+    2130             :       \param val The argument.
+    2131             :       \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
+    2132             :      \note Equivalent to plumed_gcmd()
+    2133             :   */
+    2134             :   template<typename T>
+    2135             :   static void gcmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
+    2136             :     global().cmd(key,val,shape);
+    2137             :   }
+    2138             : #endif
+    2139             : 
+    2140             :   /**
+    2141             :      Finalize global-plumed
+    2142             :   */
+    2143             :   static void gfinalize() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2144             :     plumed_gfinalize();
+    2145             :   }
+    2146             :   /**
+    2147             :      Returns the Plumed global object
+    2148             : 
+    2149             :      Notice that the object is copied, thus increasing the reference counter of the
+    2150             :      global object. In this manner, the global object will survive after a call to
+    2151             :      \ref gfinalize() if the resulting object is still in scope.
+    2152             : 
+    2153             :      \return The Plumed global object
+    2154             :   */
+    2155             :   static Plumed global() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2156             :     return Plumed(plumed_global());
+    2157             :   }
+    2158             : #endif /*}*/
+    2159             :   /**
+    2160             :      Constructor.
+    2161             : 
+    2162             :     Notice that when using runtime binding the constructed object might be
+    2163             :     invalid. One might check it using the \ref valid() method.
+    2164             : 
+    2165             :     \note Performs the same task a plumed_create()
+    2166             :   */
+    2167        3441 : Plumed()__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2168             : #if __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+    2169             :   main(plumed_create_invalid())
+    2170             : #else
+    2171        3441 :   main(plumed_create())
+    2172             : #endif
+    2173             :   {
+    2174             :   }
+    2175             : 
+    2176             :   /**
+    2177             :      Clone a Plumed object from a FORTRAN char* handler.
+    2178             : 
+    2179             :      \param c The FORTRAN handler (a char[32]).
+    2180             : 
+    2181             :      The reference counter for the corresponding object will be increased
+    2182             :      to make sure that the object will be available after plumed_f_finalize is called
+    2183             :      if the created object is still in scope.
+    2184             :   */
+    2185             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(const char*c)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2186             :   main(plumed_create_reference_f(c))
+    2187             :   {
+    2188             :   }
+    2189             : 
+    2190             :   /**
+    2191             :     Create a reference from a void* pointer. Available as of PLUMED 2.5.
+    2192             :   */
+    2193         222 : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(void*v)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2194             :   main(plumed_create_reference_v(v))
+    2195             :   {
+    2196             :   }
+    2197             : 
+    2198             :   /**
+    2199             :      Clone a Plumed object from a C plumed structure
+    2200             : 
+    2201             :      \param p The C plumed structure.
+    2202             : 
+    2203             :      The reference counter for the corresponding object will be increased
+    2204             :      to make sure that the object will be available after plumed_finalize is called
+    2205             :      if the created object is still in scope.
+    2206             :   */
+    2207             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(plumed p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2208             :   main(plumed_create_reference(p))
+    2209             :   {
+    2210             :   }
+    2211             : 
+    2212             :   /** Copy constructor.
+    2213             : 
+    2214             :     Takes a reference, incrementing the reference counter of the corresponding object.
+    2215             :   */
+    2216             : Plumed(const Plumed& p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2217             :   main(plumed_create_reference(p.main))
+    2218             :   {
+    2219             :   }
+    2220             : 
+    2221             :   /** Assignment operator. Available as of PLUMED 2.5.
+    2222             : 
+    2223             :     Takes a reference,incrementing the reference counter of the corresponding object.
+    2224             :   */
+    2225             :   Plumed&operator=(const Plumed&p) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2226             :     if(this != &p) {
+    2227             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2228             :       if(main.p) decref();
+    2229             :       main=plumed_create_reference(p.main);
+    2230             :     }
+    2231             :     return *this;
+    2232             :   }
+    2233             : 
+    2234             :   /*
+    2235             :     PLUMED >= 2.4 requires a C++11 compiler.
+    2236             :     Anyway, since Plumed.h file might be redistributed with other codes
+    2237             :     and it should be possible to combine it with earlier PLUMED versions,
+    2238             :     we here explicitly check if C+11 is available before enabling move semantics.
+    2239             :   */
+    2240             : #if __cplusplus > 199711L
+    2241             :   /** Move constructor. Available as of PLUMED 2.5.
+    2242             :     Only if move semantics is enabled.
+    2243             :   */
+    2244             : Plumed(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2245             :   main(p.main)
+    2246             :   {
+    2247             :     p.main.p=nullptr;
+    2248             :   }
+    2249             :   /** Move assignment. Available as of PLUMED 2.5.
+    2250             :     Only if move semantics is enabled.
+    2251             :   */
+    2252             :   Plumed& operator=(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2253             :     if(this != &p) {
+    2254             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2255             :       if(main.p) decref();
+    2256             :       main=p.main;
+    2257             :       p.main.p=nullptr;
+    2258             :     }
+    2259             :     return *this;
+    2260             :   }
+    2261             : #endif
+    2262             :   /**
+    2263             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2264             : 
+    2265             :     It returns an object created with \ref plumed_create_dlopen. The object is owned and
+    2266             :     is then finalized in the destructor. It can be used as follows:
+    2267             :   \verbatim
+    2268             :     PLMD::Plumed p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2269             :   // or, equivalenty:
+    2270             :   //    PLMD::Plumed p(PLMD::Plumed::dlopen("/path/to/libplumedKernel.so"));
+    2271             :     p.cmd("init");
+    2272             :   \endverbatim
+    2273             :     or, equivalently, as
+    2274             :   \verbatim
+    2275             :     auto p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2276             :     p.cmd("init");
+    2277             :   \endverbatim
+    2278             :   */
+    2279             :   static Plumed dlopen(const char* path)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2280             : // use decref to remove the extra reference
+    2281             :     return Plumed(plumed_create_dlopen(path)).decref();
+    2282             :   }
+    2283             : 
+    2284             :   /**
+    2285             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2286             : 
+    2287             :     Same as \ref dlopen(const char* path), but allows a dlopen mode to be chosen explicitly.
+    2288             :   */
+    2289             :   static Plumed dlopen(const char* path,int mode)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2290             : // use decref to remove the extra reference
+    2291             :     return Plumed(plumed_create_dlopen2(path,mode)).decref();
+    2292             :   }
+    2293             :   /**
+    2294             :     Create a PLUMED object loading from an already opened shared library. Available as of PLUMED 2.8.
+    2295             : 
+    2296             :     Same as \ref dlopen(const char* path), but searches functions in an already loaded library.
+    2297             :     See \ref plumed_create_dlsym.
+    2298             :   */
+    2299             :   static Plumed dlsym(void* dlhandle)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2300             : // use decref to remove the extra reference
+    2301             :     return Plumed(plumed_create_dlsym(dlhandle)).decref();
+    2302             :   }
+    2303             : 
+    2304             :   /** Invalid constructor. Available as of PLUMED 2.5.
+    2305             : 
+    2306             :     Can be used to initialize an invalid object. It might be useful to postpone
+    2307             :     the initialization of a Plumed object. Consider the following case
+    2308             :   \verbatim
+    2309             :     Plumed p;
+    2310             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2311             :     p.cmd("init")
+    2312             :   \endverbatim
+    2313             :     Here the `p` object will be initialized *before* the `PLUMED_KERNEL` env var has been set.
+    2314             :     This can be particularly problematic if `p` is stored in some high level class.
+    2315             :     The following case would do the job
+    2316             :   \verbatim
+    2317             :     Plumed p;
+    2318             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2319             :     p=Plumed();
+    2320             :     p.cmd("init")
+    2321             :   \endverbatim
+    2322             :     However, there will be some error reported related to the attempt to load the kernel
+    2323             :     when `p` is initialized. The following solution is the optimal one:
+    2324             :   \verbatim
+    2325             :     Plumed p(Plumed::makeInvalid());
+    2326             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2327             :     p=Plumed();
+    2328             :     p.cmd("init")
+    2329             :   \endverbatim
+    2330             :   */
+    2331             :   static Plumed makeInvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2332             : // use decref to remove the extra reference
+    2333             :     return Plumed(plumed_create_invalid()).decref();
+    2334             :   }
+    2335             : 
+    2336             :   /**
+    2337             :     Create a valid PLMD::Plumed object.
+    2338             : 
+    2339             :     Can be used to create a valid object e.g. when Plumed.h was compiled with
+    2340             :     `-D__PLUMED_WRAPPER_CXX_DEFAULT_INVALID`. For internal usage.
+    2341             :   */
+    2342             : 
+    2343             :   static Plumed makeValid()__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2344             : // use decref to remove the extra reference
+    2345             :     return Plumed(plumed_create()).decref();
+    2346             :   }
+    2347             : 
+    2348             : 
+    2349             :   /**
+    2350             :      Retrieve the C plumed structure for this object.
+    2351             : 
+    2352             :      Notice that the resulting plumed structure is a weak reference and
+    2353             :      should NOT be finalized, unless a new reference is explicitly added
+    2354             :   \verbatim
+    2355             :   Plumed p;
+    2356             :   plumed c=p;
+    2357             :   plumed_finalize(c); // <- this is wrong
+    2358             :   \endverbatim
+    2359             :   \verbatim
+    2360             :   Plumed p;
+    2361             :   plumed c=plumed_create_reference(p);
+    2362             :   plumed_finalize(c); // <- this is right
+    2363             :   \endverbatim
+    2364             :   */
+    2365             :   operator plumed()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2366             :     return main;
+    2367             :   }
+    2368             : 
+    2369             :   /**
+    2370             :      Retrieve a FORTRAN handler for this object
+    2371             :       \param c The FORTRAN handler (a char[32]).
+    2372             :     Notice that the resulting plumed structure is a weak reference and
+    2373             :     should NOT be finalized, unless a new reference is explicitly added.
+    2374             :   */
+    2375             :   void toFortran(char*c)const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2376             :     plumed_c2f(main,c);
+    2377             :   }
+    2378             : 
+    2379             :   /**
+    2380             :      Retrieve a void* handler for this object. Available as of PLUMED 2.5.
+    2381             :     Notice that the resulting plumed structure is a weak reference and
+    2382             :     should NOT be finalized, unless a new reference is explicitly added.
+    2383             :   */
+    2384             :   void* toVoid()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2385             :     return plumed_c2v(main);
+    2386             :   }
+    2387             : 
+    2388             :   /**
+    2389             :     Increase reference counter. Available as of PLUMED 2.5.
+    2390             : 
+    2391             :     Using this method improperly might interfere with correct object construction
+    2392             :     and destruction.
+    2393             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2394             : 
+    2395             :     A possible usage is to transfer the ownership of a temporary
+    2396             :     object when it is converted
+    2397             :   \verbatim
+    2398             :   plumed p=Plumed::dlopen(path).incref()
+    2399             :   // without incref(), the just constructed object will be destroyed
+    2400             :   // when the temporary object is deleted.
+    2401             :   ... do stuff ...
+    2402             :   plumed_finalize(p);
+    2403             :   \endverbatim
+    2404             : 
+    2405             :   */
+    2406             :   Plumed& incref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2407             :     plumed_create_reference(main);
+    2408             :     return *this;
+    2409             :   }
+    2410             : 
+    2411             :   /**
+    2412             :     Decrease reference counter. Available as of PLUMED 2.5.
+    2413             : 
+    2414             :     Using this method improperly might interfere with correct object construction
+    2415             :     and destruction.
+    2416             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2417             :   */
+    2418             :   Plumed& decref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2419             : // calling decref on a moved plumed object should give an error, so we do not check if main.p!=NULL here:
+    2420        3663 :     plumed_finalize(main);
+    2421        3441 :     return *this;
+    2422             :   }
+    2423             : 
+    2424             : private:
+    2425             : 
+    2426             :   /**
+    2427             :     Private version of cmd. It is used here to avoid duplication of code between typesafe and not-typesafe versions
+    2428             :   */
+    2429       10881 :   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) {
+    2430             :     NothrowHandler h;
+    2431             :     plumed_nothrow_handler nothrow;
+    2432       10881 :     if(error) {
+    2433             :       plumed_error_init(error);
+    2434           0 :       nothrow.ptr=error;
+    2435           0 :       nothrow.handler=plumed_error_set;
+    2436             :     } else {
+    2437       10881 :       h.code=0;
+    2438       10881 :       nothrow.ptr=&h;
+    2439       10881 :       nothrow.handler=nothrow_handler;
+    2440             :     }
+    2441             :     try {
+    2442       10881 :       if(safe) {
+    2443       10881 :         plumed_cmd_safe_nothrow(main,key,safe->get_safeptr(),nothrow);
+    2444             :       } else {
+    2445           0 :         plumed_cmd_nothrow(main,key,unsafe,nothrow);
+    2446             :       }
+    2447           0 :     } catch (...) {
+    2448             :       /*
+    2449             :         When loading a kernel <=2.4, plumed_cmd_nothrow could throw an exception.
+    2450             :         If the exception is transmitted through the C interface and arrives here,
+    2451             :         we translate it so as to free the virtual tables of the loaded kernel.
+    2452             :       */
+    2453           0 :       rethrow();
+    2454           0 :     }
+    2455       10881 :     if(!error && h.code!=0) rethrow(h);
+    2456       10881 :   }
+    2457             : 
+    2458             : public:
+    2459             : 
+    2460             :   /**
+    2461             :      Send a command to this plumed object
+    2462             :       \param key The name of the command to be executed
+    2463             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2464             :             rethrow any exception raised within PLUMED.
+    2465             :   */
+    2466             :   void cmd(const char*key) {
+    2467             :     plumed_cmd_cxx(main,key);
+    2468             :   }
+    2469             : 
+    2470             :   /**
+    2471             :      Send a command to this plumed object
+    2472             :       \param key The name of the command to be executed
+    2473             :       \param val The argument, passed by value.
+    2474             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2475             :             rethrow any exception raised within PLUMED.
+    2476             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2477             :              the type of the argument is checked.
+    2478             :   */
+    2479             :   template<typename T>
+    2480             :   void cmd(const char*key,T val) {
+    2481       10881 :     plumed_cmd_cxx(main,key,val);
+    2482       10881 :   }
+    2483             : 
+    2484             :   /**
+    2485             :      Send a command to this plumed object
+    2486             :       \param key The name of the command to be executed
+    2487             :       \param val The argument, passed by pointer.
+    2488             :       \param shape A zero-terminated array containing the shape of the data.
+    2489             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2490             :             rethrow any exception raised within PLUMED.
+    2491             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2492             :              the type of the argument is checked. If shape is passed, it is also
+    2493             :              checked that PLUMED access only compatible indexes.
+    2494             :   */
+    2495             :   template<typename T>
+    2496             :   void cmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    2497             :     plumed_cmd_cxx(main,key,val,shape);
+    2498             :   }
+    2499             : 
+    2500             : #if __cplusplus > 199711L
+    2501             :   /**
+    2502             :      Send a command to this plumed object
+    2503             :       \param key The name of the command to be executed
+    2504             :       \param val The argument, passed by pointer.
+    2505             :       \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
+    2506             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2507             :             rethrow any exception raised within PLUMED.
+    2508             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2509             :              the type of the argument is checked. If shape is passed, it is also
+    2510             :              checked that PLUMED access only compatible indexes.
+    2511             :   */
+    2512             :   template<typename T>
+    2513             :   void cmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
+    2514             :     if(shape.size()>4) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    2515             :     std::array<std::size_t,5> shape_;
+    2516             :     unsigned j=0;
+    2517             :     for(auto i : shape) {
+    2518             :       shape_[j]=i;
+    2519             :       j++;
+    2520             :     }
+    2521             :     shape_[j]=0;
+    2522             :     plumed_cmd_cxx(main,key,val,&shape_[0]);
+    2523             :   }
+    2524             : #endif
+    2525             :   /**
+    2526             :      Send a command to this plumed object
+    2527             :       \param key The name of the command to be executed
+    2528             :       \param val The argument, passed by pointer.
+    2529             :       \param nelem The number of elements passed.
+    2530             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2531             :             rethrow any exception raised within PLUMED.
+    2532             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2533             :              the type of the argument is checked.  nelem is used to check
+    2534             :              the maximum index interpreting the array as flattened.
+    2535             :   */
+    2536             :   template<typename T>
+    2537             :   void cmd(const char*key,T* val, __PLUMED_WRAPPER_STD size_t nelem) {
+    2538             :     plumed_cmd_cxx(main,key,val,nelem);
+    2539             :   }
+    2540             : 
+    2541             :   /**
+    2542             :      Destructor
+    2543             : 
+    2544             :      It calls \ref plumed_finalize(). Notice that this is done also if the
+    2545             :      constructor failed (that is, if it returned an invalid object). This allows
+    2546             :      declaring Plumed objects also if PLUMED is actually not available, provided
+    2547             :      one does not use the \ref cmd method.
+    2548             : 
+    2549             :      Destructor is virtual so as to allow correct inheritance from Plumed object.
+    2550             :   */
+    2551             : #if __PLUMED_WRAPPER_CXX_POLYMORPHIC
+    2552             :   virtual
+    2553             : #endif
+    2554             :   ~Plumed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2555             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2556        3441 :     if(main.p) decref();
+    2557        3663 :   }
+    2558             : 
+    2559             :   /**
+    2560             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2561             :     namely implement typechecks and rethrowing exception.
+    2562             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2563             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2564             :     Available as of PLUMED 2.8.
+    2565             :   */
+    2566             :   static void plumed_cmd_cxx(plumed p,const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2567             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2568             :     SafePtr s;
+    2569             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2570             : #else
+    2571             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2572             : #endif
+    2573             :   }
+    2574             : 
+    2575             :   /**
+    2576             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2577             :     namely implement typechecks and rethrowing exception.
+    2578             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2579             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2580             :     Available as of PLUMED 2.8.
+    2581             :   */
+    2582             :   template<typename T>
+    2583         222 :   static void plumed_cmd_cxx(plumed p,const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2584             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2585             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    2586         222 :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2587             : #else
+    2588             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,&val,error);
+    2589             : #endif
+    2590         222 :   }
+    2591             : 
+    2592             :   /**
+    2593             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2594             :     namely implement typechecks and rethrowing exception.
+    2595             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2596             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2597             :     Available as of PLUMED 2.8.
+    2598             :   */
+    2599             :   template<typename T>
+    2600       10659 :   static void plumed_cmd_cxx(plumed p,const char*key,T* val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2601             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2602             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    2603       10659 :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2604             : #else
+    2605             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    2606             : #endif
+    2607       10659 :   }
+    2608             : 
+    2609             :   /**
+    2610             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2611             :     namely implement typechecks and rethrowing exception.
+    2612             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2613             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2614             :     Available as of PLUMED 2.8.
+    2615             :   */
+    2616             :   template<typename T>
+    2617             :   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) {
+    2618             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2619             :     SafePtr s(val,nelem,__PLUMED_WRAPPER_CXX_NULLPTR);
+    2620             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2621             : #else
+    2622             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    2623             : #endif
+    2624             :   }
+    2625             : 
+    2626             :   /**
+    2627             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2628             :     namely implement typechecks and rethrowing exception.
+    2629             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2630             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2631             :     Available as of PLUMED 2.8.
+    2632             :   */
+    2633             :   template<typename T>
+    2634             :   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) {
+    2635             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2636             :     SafePtr s(val,0,shape);
+    2637             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2638             : #else
+    2639             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    2640             : #endif
+    2641             :   }
+    2642             : 
+    2643             : 
+    2644             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    2645             :   /**
+    2646             :     \related Plumed
+    2647             :     This function can be used to make plumed_gcmd behave as the C++ wrapper PLMD::Plumed::gcmd,
+    2648             :     namely implement typechecks and rethrowing exception.
+    2649             :     To be used through the macro plumed_gcmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2650             :     Available as of PLUMED 2.8.
+    2651             :   */
+    2652             : 
+    2653             :   /**
+    2654             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2655             :     namely implement typechecks and rethrowing exception.
+    2656             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2657             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2658             :     Available as of PLUMED 2.8.
+    2659             :   */
+    2660             :   static void plumed_gcmd_cxx(const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2661             :     plumed_cmd_cxx(plumed_global(),key,error);
+    2662             :   }
+    2663             : 
+    2664             :   /**
+    2665             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2666             :     namely implement typechecks and rethrowing exception.
+    2667             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2668             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2669             :     Available as of PLUMED 2.8.
+    2670             :   */
+    2671             :   template<typename T>
+    2672             :   static void plumed_gcmd_cxx(const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2673             :     plumed_cmd_cxx(plumed_global(),key,val,error);
+    2674             :   }
+    2675             : 
+    2676             :   /**
+    2677             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2678             :     namely implement typechecks and rethrowing exception.
+    2679             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2680             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2681             :     Available as of PLUMED 2.8.
+    2682             :   */
+    2683             :   template<typename T>
+    2684             :   static void plumed_gcmd_cxx(const char*key,T val, __PLUMED_WRAPPER_STD size_t nelem,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2685             :     plumed_cmd_cxx(plumed_global(),key,val,nelem,error);
+    2686             :   }
+    2687             : 
+    2688             :   /**
+    2689             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2690             :     namely implement typechecks and rethrowing exception.
+    2691             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2692             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2693             :     Available as of PLUMED 2.8.
+    2694             :   */
+    2695             :   template<typename T>
+    2696             :   static void plumed_gcmd_cxx(const char*key,T val, const __PLUMED_WRAPPER_STD size_t* shape,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2697             :     plumed_cmd_cxx(plumed_global(),key,val,shape,error);
+    2698             :   }
+    2699             : 
+    2700             : #endif /*}*/
+    2701             : 
+    2702             : #if __PLUMED_WRAPPER_CXX_BIND_C /*{*/
+    2703             : 
+    2704             : #define __PLUMED_WRAPPER_REDEFINE_CMD ::PLMD::Plumed::plumed_cmd_cxx
+    2705             : 
+    2706             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    2707             : #define __PLUMED_WRAPPER_REDEFINE_GCMD ::PLMD::Plumed::plumed_gcmd_cxx
+    2708             : #endif /*}*/
+    2709             : 
+    2710             : #endif /*}*/
+    2711             : 
+    2712             : };
+    2713             : 
+    2714             : /**
+    2715             :   \related Plumed
+    2716             :   Comparison operator. Available as of PLUMED 2.5.
+    2717             : */
+    2718             : inline
+    2719             : bool operator==(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2720             :   return a.toVoid()==b.toVoid();
+    2721             : }
+    2722             : 
+    2723             : /**
+    2724             :   \related Plumed
+    2725             :   Comparison operator. Available as of PLUMED 2.5.
+    2726             : */
+    2727             : inline
+    2728             : bool operator!=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2729             :   return a.toVoid()!=b.toVoid();
+    2730             : }
+    2731             : 
+    2732             : /**
+    2733             :   \related Plumed
+    2734             :   Comparison operator. Available as of PLUMED 2.5.
+    2735             : */
+    2736             : inline
+    2737             : bool operator<=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2738             :   return a.toVoid()<=b.toVoid();
+    2739             : }
+    2740             : 
+    2741             : /**
+    2742             :   \related Plumed
+    2743             :   Comparison operator. Available as of PLUMED 2.5.
+    2744             : */
+    2745             : inline
+    2746             : bool operator<(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2747             :   return a.toVoid()<b.toVoid();
+    2748             : }
+    2749             : 
+    2750             : /**
+    2751             :   \related Plumed
+    2752             :   Comparison operator. Available as of PLUMED 2.5.
+    2753             : */
+    2754             : inline
+    2755             : bool operator>=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2756             :   return a.toVoid()>=b.toVoid();
+    2757             : }
+    2758             : 
+    2759             : /**
+    2760             :   \related Plumed
+    2761             :   Comparison operator. Available as of PLUMED 2.5.
+    2762             : */
+    2763             : inline
+    2764             : bool operator>(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2765             :   return a.toVoid()>b.toVoid();
+    2766             : }
+    2767             : 
+    2768             : __PLUMED_WRAPPER_ANONYMOUS_END /*}*/
+    2769             : 
+    2770             : }
+    2771             : 
+    2772             : #endif /*}*/
+    2773             : 
+    2774             : #endif /*}*/
+    2775             : 
+    2776             : /* END OF DECLARATIONS */
+    2777             : 
+    2778             : /*
+    2779             : 
+    2780             :   1: emit implementation
+    2781             :   0: do not emit implementation
+    2782             : 
+    2783             :   Allows an implementation to be emitted together with the declarations.
+    2784             : 
+    2785             :   Used to decide if definitions should be emitted. This macro could have a different
+    2786             :   value when Plumed.h is reincluded. As a consequence, we map it to a local
+    2787             :   macro (__PLUMED_WRAPPER_IMPLEMENTATION_) that is reset at the end of this file.
+    2788             : */
+    2789             : 
+    2790             : #ifdef __PLUMED_WRAPPER_IMPLEMENTATION
+    2791             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ __PLUMED_WRAPPER_IMPLEMENTATION
+    2792             : #else
+    2793             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ 0
+    2794             : #endif
+    2795             : 
+    2796             : /* BEGINNING OF DEFINITIONS */
+    2797             : 
+    2798             : #if __PLUMED_WRAPPER_IMPLEMENTATION_  /*{*/
+    2799             : #ifndef __PLUMED_wrapper_Plumed_implementation /*{*/
+    2800             : #define __PLUMED_wrapper_Plumed_implementation
+    2801             : 
+    2802             : /*
+    2803             :   the following macros only control the implementation
+    2804             : */
+    2805             : 
+    2806             : /*
+    2807             :   1: enable the definition of plumed_symbol_table_reexport
+    2808             :   0: does not enable the definition of plumed_symbol_table_reexport
+    2809             : 
+    2810             :   This is only needed in the official plumed library to make
+    2811             :   the symbol table available. This is a hack to reexport the function table
+    2812             :   and is only needed when creating the library libplumed.so.
+    2813             : */
+    2814             : 
+    2815             : #ifndef __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    2816             : #define __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE 0
+    2817             : #endif
+    2818             : 
+    2819             : /*
+    2820             :   1: write on stderr changes in reference counters
+    2821             :   0: do not write changes in reference counters
+    2822             : 
+    2823             :   Used for debugging.
+    2824             : 
+    2825             :   Only used in definitions.
+    2826             : */
+    2827             : 
+    2828             : #ifndef __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    2829             : #define __PLUMED_WRAPPER_DEBUG_REFCOUNT 0
+    2830             : #endif
+    2831             : 
+    2832             : /*
+    2833             :   1: emit plumed_kernel_register function (default)
+    2834             :   0: do not emit plumed_kernel_register function
+    2835             : 
+    2836             :   This function is only needed to avoid an extra warning when loading old (<=2.4) kernels.
+    2837             :   We might change its default in the future.
+    2838             : 
+    2839             :   Used only in definitions.
+    2840             : */
+    2841             : 
+    2842             : #ifndef __PLUMED_WRAPPER_KERNEL_REGISTER
+    2843             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 1
+    2844             : #endif
+    2845             : 
+    2846             : /*
+    2847             :   1: emit Fortran wrappers
+    2848             :   0: do not emit Fortran wrappers (default)
+    2849             : 
+    2850             :   Used only in definitions.
+    2851             : */
+    2852             : 
+    2853             : #ifndef __PLUMED_WRAPPER_FORTRAN
+    2854             : #define __PLUMED_WRAPPER_FORTRAN 0
+    2855             : #endif
+    2856             : 
+    2857             : /*
+    2858             :   With internal interface, it does not make sense to emit kernel register or fortran interfaces
+    2859             : */
+    2860             : 
+    2861             : #if ! __PLUMED_WRAPPER_EXTERN /*{*/
+    2862             : #undef __PLUMED_WRAPPER_KERNEL_REGISTER
+    2863             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 0
+    2864             : #undef __PLUMED_WRAPPER_FORTRAN
+    2865             : #define __PLUMED_WRAPPER_FORTRAN 0
+    2866             : #endif /*}*/
+    2867             : 
+    2868             : #ifdef __PLUMED_HAS_DLOPEN
+    2869             : #include <dlfcn.h> /* dlopen dlerror dlsym */
+    2870             : #endif
+    2871             : 
+    2872             : #if __PLUMED_WRAPPER_CXX_STD
+    2873             : #include <cstdio>  /* fprintf */
+    2874             : #include <cstring> /* memcpy strlen strncpy memcmp memmove strcmp memcpy */
+    2875             : #include <cassert> /* assert */
+    2876             : #include <cstdlib> /* getenv malloc free abort exit */
+    2877             : #include <climits> /* CHAR_BIT */
+    2878             : #else
+    2879             : #include <stdio.h>
+    2880             : #include <string.h>
+    2881             : #include <assert.h>
+    2882             : #include <stdlib.h>
+    2883             : #include <limits.h>
+    2884             : #endif
+    2885             : 
+    2886             : /**
+    2887             :   Function pointer to plumed_create
+    2888             : */
+    2889             : 
+    2890             : typedef void*(*plumed_create_pointer)(void);
+    2891             : /**
+    2892             :   Function pointer to plumed_cmd
+    2893             : */
+    2894             : typedef void(*plumed_cmd_pointer)(void*,const char*,const void*);
+    2895             : 
+    2896             : /**
+    2897             :   Function pointer to plumed_finalize
+    2898             : */
+    2899             : typedef void(*plumed_finalize_pointer)(void*);
+    2900             : 
+    2901             : /**
+    2902             :    Holder for plumedmain function pointers.
+    2903             : */
+    2904             : typedef struct {
+    2905             :   plumed_create_pointer create;
+    2906             :   plumed_cmd_pointer cmd;
+    2907             :   plumed_finalize_pointer finalize;
+    2908             : } plumed_plumedmain_function_holder;
+    2909             : 
+    2910             : /**
+    2911             :   Holder for plumed symbol table.
+    2912             : 
+    2913             :   The table contains pointers to function exported from plumed. Functions can be added increasing the version number.
+    2914             :   Notice that the default way to extend functionalities is by adding cmd strings. This is a last resort, and all new
+    2915             :   functions should be explicitly motivated. Here's the addition:
+    2916             : 
+    2917             :   version=2, cmd_nothrow.
+    2918             : 
+    2919             :   This function accepts an extra argument `plumed_nothrow_handler*handler`.
+    2920             :   In case an exception is thrown within plumed, it just calls `handler->handler(handler->ptr,code,message,opt)` and return.
+    2921             :   An alternative would have been to install an error handler (with a call to cmd("setErrorHandler")). However, the cost
+    2922             :   of doing it everytime Plumed::cmd is called is too high. On the other hand, installing it only at object construction
+    2923             :   is very risky since and object created in that way would not report any error if manipulated from the C interface.
+    2924             :   So, it looks like this is the only possibility.
+    2925             : 
+    2926             :   version=3, cmd_safe and cmd_safe_nothrow
+    2927             : 
+    2928             :   These are functions that accept a plumed_safeptr object, which can carry information about the passed type and size.
+    2929             :   Since new information should be passed at every cmd call, this can only be obtained by adding new cmd calls.
+    2930             : 
+    2931             : */
+    2932             : typedef struct {
+    2933             :   /**
+    2934             :     Version number.
+    2935             : 
+    2936             :     Minimum value is 1.
+    2937             :   */
+    2938             :   int version;
+    2939             :   /**
+    2940             :     Pointers to standard plumed functions (create/cmd/finalize).
+    2941             : 
+    2942             :     Always available.
+    2943             :   */
+    2944             :   plumed_plumedmain_function_holder functions;
+    2945             :   /**
+    2946             :     Pointer to a cmd function guaranteed not to throw exceptions.
+    2947             : 
+    2948             :     Available with version>=2.
+    2949             :   */
+    2950             :   void (*cmd_nothrow)(void*plumed,const char*key,const void*val,plumed_nothrow_handler);
+    2951             :   /**
+    2952             :     Pointer to a cmd function that accepts typeinfos.
+    2953             : 
+    2954             :     Available with version>=3.
+    2955             :   */
+    2956             :   void (*cmd_safe)(void*plumed,const char*key,plumed_safeptr);
+    2957             : 
+    2958             :   /**
+    2959             :     Pointer to a cmd function guaranteed not to throw exceptions and that accepts typeinfos.
+    2960             : 
+    2961             :     Available with version>=3.
+    2962             :   */
+    2963             :   void (*cmd_safe_nothrow)(void*plumed,const char*key,plumed_safeptr,plumed_nothrow_handler);
+    2964             : 
+    2965             : } plumed_symbol_table_type;
+    2966             : 
+    2967             : /* Utility to convert function pointers to pointers, just for the sake of printing them */
+    2968             : #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))); }
+    2969             : 
+    2970             : #define __PLUMED_GETENV __PLUMED_WRAPPER_STD getenv
+    2971             : #define __PLUMED_FPRINTF __PLUMED_WRAPPER_STD fprintf
+    2972             : #define __PLUMED_MALLOC __PLUMED_WRAPPER_STD malloc
+    2973             : #define __PLUMED_FREE __PLUMED_WRAPPER_STD free
+    2974             : 
+    2975             : /**
+    2976             :   Historically (PLUMED<=2.4) register for plumedmain function pointers.
+    2977             :   As of PLUMED>=2.5, this function does not do anything except for reporting the attempt to register
+    2978             :   something. It always returns NULL. The function should be here anyway to allow an incomplete
+    2979             :   libplumedKernel (<=2.4), expecting this function to be present, to be loaded correctly.
+    2980             : */
+    2981             : #if __PLUMED_WRAPPER_KERNEL_REGISTER
+    2982             : /* Since it is only called from outside, it must be hardcoded to be extern */
+    2983             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    2984             : extern plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder*);
+    2985          12 : plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder* f) {
+    2986             :   void* tmpptr;
+    2987          12 :   if(f) {
+    2988          12 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) {
+    2989           0 :       __PLUMED_FPRINTF(stderr,"+++ Ignoring registration at %p (",(const void*)f);
+    2990             :       __PLUMED_CONVERT_FPTR(tmpptr,f->create);
+    2991           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    2992             :       __PLUMED_CONVERT_FPTR(tmpptr,f->cmd);
+    2993           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    2994             :       __PLUMED_CONVERT_FPTR(tmpptr,f->finalize);
+    2995           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    2996             :     }
+    2997             :   }
+    2998          12 :   return __PLUMED_WRAPPER_CXX_NULLPTR;
+    2999             : }
+    3000             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    3001             : #endif
+    3002             : 
+    3003             : #if defined( __PLUMED_HAS_DLOPEN) /*{*/
+    3004             : /**
+    3005             : Try to dlopen a path with a given mode.
+    3006             : If the dlopen command fails, it tries to strip the `Kernel` part of the name.
+    3007             : 
+    3008             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3009             : It is first declared then defined to make sure it is a regular C static function.
+    3010             : */
+    3011             : 
+    3012             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3013           9 : void* plumed_attempt_dlopen(const char*path,int mode) {
+    3014             :   char* pathcopy;
+    3015             :   void* p;
+    3016             :   char* pc;
+    3017             :   __PLUMED_WRAPPER_STD size_t strlenpath;
+    3018             :   FILE* fp;
+    3019             :   pathcopy=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3020             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3021             :   pc=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3022             :   strlenpath=0;
+    3023           9 :   fp=__PLUMED_WRAPPER_STD fopen(path,"r");
+    3024           9 :   if(!fp) {
+    3025           0 :     __PLUMED_FPRINTF(stderr,"+++ File %s does not exist or cannot be read\n",path);
+    3026           0 :     return __PLUMED_WRAPPER_CXX_NULLPTR;
+    3027             :   }
+    3028           9 :   __PLUMED_WRAPPER_STD fclose(fp);
+    3029           9 :   dlerror();
+    3030           9 :   p=dlopen(path,mode);
+    3031           9 :   if(!p) {
+    3032             :     /*
+    3033             :       Something went wrong. We try to remove "Kernel" string from the PLUMED_KERNEL variable
+    3034             :       and load directly the shared library. Notice that this particular path is only expected
+    3035             :       to be necessary when using PLUMED<=2.4 and the symbols in the main executable are
+    3036             :       not visible. All the other cases (either PLUMED>=2.5 or symbols in the main executable visible)
+    3037             :       should work correctly without entering here.
+    3038             :     */
+    3039           0 :     __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3040           0 :     strlenpath=__PLUMED_WRAPPER_STD strlen(path);
+    3041           0 :     pathcopy=(char*) __PLUMED_MALLOC(strlenpath+1);
+    3042           0 :     if(!pathcopy) {
+    3043           0 :       __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    3044           0 :       __PLUMED_WRAPPER_STD abort();
+    3045             :     }
+    3046             :     __PLUMED_WRAPPER_STD strncpy(pathcopy,path,strlenpath+1);
+    3047           0 :     pc=pathcopy+strlenpath-6;
+    3048           0 :     while(pc>=pathcopy && __PLUMED_WRAPPER_STD memcmp(pc,"Kernel",6)) pc--;
+    3049           0 :     if(pc>=pathcopy) {
+    3050           0 :       __PLUMED_WRAPPER_STD memmove(pc, pc+6, __PLUMED_WRAPPER_STD strlen(pc)-5);
+    3051           0 :       __PLUMED_FPRINTF(stderr,"+++ This error is expected if you are trying to load a kernel <=2.4\n");
+    3052           0 :       __PLUMED_FPRINTF(stderr,"+++ Trying %s +++\n",pathcopy);
+    3053           0 :       fp=__PLUMED_WRAPPER_STD fopen(path,"r");
+    3054           0 :       if(!fp) {
+    3055           0 :         __PLUMED_FPRINTF(stderr,"+++ File %s does not exist or cannot be read\n",pathcopy);
+    3056           0 :         __PLUMED_FREE(pathcopy);
+    3057           0 :         return __PLUMED_WRAPPER_CXX_NULLPTR;
+    3058             :       }
+    3059           0 :       __PLUMED_WRAPPER_STD fclose(fp);
+    3060           0 :       dlerror();
+    3061           0 :       p=dlopen(pathcopy,mode);
+    3062           0 :       if(!p) __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3063             :     }
+    3064           0 :     __PLUMED_FREE(pathcopy);
+    3065             :   }
+    3066             :   return p;
+    3067             : }
+    3068             : __PLUMED_WRAPPER_INTERNALS_END
+    3069             : 
+    3070             : /**
+    3071             :   Utility to search for a function.
+    3072             : */
+    3073             : #define __PLUMED_SEARCH_FUNCTION(tmpptr,handle,func,name,debug) \
+    3074             :   if(!func) { \
+    3075             :     tmpptr=dlsym(handle,name); \
+    3076             :     if(tmpptr) { \
+    3077             :       *(void **)(&func)=tmpptr; \
+    3078             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ %s found at %p +++\n",name,tmpptr); \
+    3079             :     } else { \
+    3080             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ Function %s not found\n",name); \
+    3081             :     } \
+    3082             :   }
+    3083             : 
+    3084             : /**
+    3085             : Search symbols in a dlopened library.
+    3086             : 
+    3087             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3088             : */
+    3089             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3090           9 : void plumed_search_symbols(void* handle, plumed_plumedmain_function_holder* f,plumed_symbol_table_type** table) {
+    3091             :   plumed_plumedmain_function_holder functions;
+    3092             :   plumed_symbol_table_type* table_ptr;
+    3093             :   void* tmpptr;
+    3094             :   char* debug;
+    3095             :   functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3096             :   functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3097             :   functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3098             :   table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3099           9 :   tmpptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3100             :   /*
+    3101             :     Notice that as of PLUMED 2.5 we ignore self registrations.
+    3102             :     Pointers are searched in the form of a single pointer to a structure, which
+    3103             :     is the standard way in PLUMED 2.5, as well as using alternative names used in
+    3104             :     PLUMED 2.0 to 2.4 (e.g. plumedmain_create) and in some intermediate versions between
+    3105             :     PLUMED 2.4 and 2.5 (e.g. plumed_plumedmain_create). The last chance is probably
+    3106             :     unnecessary and might be removed at some point.
+    3107             :   */
+    3108           9 :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    3109           9 :   table_ptr=(plumed_symbol_table_type*) dlsym(handle,"plumed_symbol_table");
+    3110           9 :   if(table_ptr) functions=table_ptr->functions;
+    3111           9 :   if(debug) {
+    3112           0 :     if(table_ptr) {
+    3113           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table version %i found at %p +++\n",table_ptr->version,(void*)table_ptr);
+    3114           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_function_pointers found at %p (",(void*)&table_ptr->functions);
+    3115             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.create);
+    3116           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3117             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.cmd);
+    3118           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3119             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.finalize);
+    3120           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    3121             :     } else {
+    3122           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table (available in PLUMED>=2.5) not found, perhaps kernel is older +++\n");
+    3123             :     }
+    3124             :   }
+    3125             :   /* only searches if they were not found already */
+    3126           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumedmain_create",debug);
+    3127           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumed_plumedmain_create",debug);
+    3128           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumedmain_cmd",debug);
+    3129           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumed_plumedmain_cmd",debug);
+    3130           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumedmain_finalize",debug);
+    3131           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumed_plumedmain_finalize",debug);
+    3132           9 :   if(functions.create && functions.cmd && functions.finalize) {
+    3133           9 :     if(debug) __PLUMED_FPRINTF(stderr,"+++ PLUMED was loaded correctly +++\n");
+    3134           9 :     *f=functions;
+    3135           9 :     if(table) *table=table_ptr;
+    3136             :   } else {
+    3137           0 :     if(!functions.create) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_create not found +++\n");
+    3138           0 :     if(!functions.cmd) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_cmd not found +++\n");
+    3139           0 :     if(!functions.finalize) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_finalize not found +++\n");
+    3140           0 :     f->create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3141           0 :     f->cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3142           0 :     f->finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3143           0 :     if(table) *table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3144             :   }
+    3145           9 : }
+    3146             : __PLUMED_WRAPPER_INTERNALS_END
+    3147             : 
+    3148             : #endif /*}*/
+    3149             : 
+    3150             : 
+    3151             : #if __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    3152             : 
+    3153             : /*
+    3154             :   Here is the case where plumed_symbol_table is
+    3155             :   visible as extern. We first declare it (together with plumed_symbol_table_init) ...
+    3156             : */
+    3157             : 
+    3158             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3159             : extern
+    3160             : plumed_symbol_table_type plumed_symbol_table;
+    3161             : __PLUMED_WRAPPER_EXTERN_C_END
+    3162             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3163             : extern
+    3164             : void plumed_symbol_table_init(void);
+    3165             : __PLUMED_WRAPPER_EXTERN_C_END
+    3166             : 
+    3167             : /*
+    3168             :   ... and then make available a function that returns the address
+    3169             :   of the symbol table.
+    3170             : */
+    3171             : __PLUMED_WRAPPER_C_BEGIN
+    3172      364781 : plumed_symbol_table_type* plumed_symbol_table_reexport() {
+    3173             :   /* make sure the table is initialized */
+    3174      364781 :   plumed_symbol_table_init();
+    3175      378352 :   return &plumed_symbol_table;
+    3176             : }
+    3177             : __PLUMED_WRAPPER_C_END
+    3178             : 
+    3179             : #else
+    3180             : 
+    3181             : /*
+    3182             :   Here is the case where plumed_symbol_table is not
+    3183             :   visible as extern. We thus assume that plumed_symbol_table_reexport is
+    3184             :   available.
+    3185             : */
+    3186             : 
+    3187             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3188             : extern plumed_symbol_table_type* plumed_symbol_table_reexport();
+    3189             : __PLUMED_WRAPPER_EXTERN_C_END
+    3190             : #endif
+    3191             : 
+    3192             : 
+    3193             : /*
+    3194             :   Returns the global pointers, either those available at link time or those
+    3195             :   found in the library loaded at PLUMED_KERNEL env var.
+    3196             :   If plumed_symbol_table_ptr is not NULL, it is used to return a pointer to the symbol table
+    3197             :   (if available).
+    3198             :   Notice that problems can be detected checking if the functions have a NULL ptr.
+    3199             :   On the other hand, the symbol table pointer might be NULL just because the plumed version is <=2.4.
+    3200             :   If handle is not NULL, it is used to return a dlopen handle that could be subsequently dlclosed.
+    3201             : */
+    3202             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3203      364791 : void plumed_retrieve_functions(plumed_plumedmain_function_holder* functions, plumed_symbol_table_type** plumed_symbol_table_ptr,void** handle) {
+    3204             : #if ! __PLUMED_WRAPPER_LINK_RUNTIME
+    3205             :   /*
+    3206             :     Real interface, constructed using the symbol table obtained with plumed_symbol_table_reexport.
+    3207             :     This makes the symbols hardcoded and independent of a mis-set PLUMED_KERNEL variable.
+    3208             :   */
+    3209      364791 :   plumed_symbol_table_type* ptr=plumed_symbol_table_reexport();
+    3210      378688 :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=ptr;
+    3211      378688 :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3212      378688 :   if(functions) *functions=ptr->functions;
+    3213             : #elif ! defined(__PLUMED_HAS_DLOPEN)
+    3214             :   /*
+    3215             :     When dlopen is not available, we hard code them to NULL
+    3216             :   */
+    3217             :   __PLUMED_FPRINTF(stderr,"+++ PLUMED has been compiled without dlopen and without a static kernel +++\n");
+    3218             :   plumed_plumedmain_function_holder g= {__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR};
+    3219             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3220             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3221             :   if(functions) *functions=g;
+    3222             : #else
+    3223             :   /*
+    3224             :     On the other hand, for runtime binding, we use dlsym to find the relevant functions.
+    3225             :   */
+    3226             :   plumed_plumedmain_function_holder g;
+    3227             :   /* search is done once and only once */
+    3228             :   const char* path;
+    3229             :   void* p;
+    3230             :   char* debug;
+    3231             :   int dlopenmode;
+    3232             :   g.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3233             :   g.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3234             :   g.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3235             :   path=__PLUMED_GETENV("PLUMED_KERNEL");
+    3236             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3237             :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    3238             :   dlopenmode=0;
+    3239             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3240             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3241             : #ifdef __PLUMED_DEFAULT_KERNEL
+    3242             :   /*
+    3243             :     This variable allows a default path for the kernel to be hardcoded.
+    3244             :     Can be useful for hardcoding the predefined plumed location
+    3245             :     still allowing the user to override this choice setting PLUMED_KERNEL.
+    3246             :     The path should be chosen at compile time adding e.g.
+    3247             :     -D__PLUMED_DEFAULT_KERNEL=/opt/local/lib/libplumed.dylib
+    3248             :   */
+    3249             :   /* This is required to add quotes */
+    3250             : #define PLUMED_QUOTE_DIRECT(name) #name
+    3251             : #define PLUMED_QUOTE(macro) PLUMED_QUOTE_DIRECT(macro)
+    3252             :   if(! (path && (*path) )) path=PLUMED_QUOTE(__PLUMED_DEFAULT_KERNEL);
+    3253             : #endif
+    3254             :   if(path && (*path)) {
+    3255             :     __PLUMED_FPRINTF(stderr,"+++ Loading the PLUMED kernel runtime +++\n");
+    3256             :     __PLUMED_FPRINTF(stderr,"+++ PLUMED_KERNEL=\"%s\" +++\n",path);
+    3257             :     if(debug) __PLUMED_FPRINTF(stderr,"+++ Loading with mode RTLD_NOW");
+    3258             :     dlopenmode=RTLD_NOW;
+    3259             :     if(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE"),"LOCAL")) {
+    3260             :       dlopenmode=dlopenmode|RTLD_LOCAL;
+    3261             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_LOCAL");
+    3262             :     } else {
+    3263             :       dlopenmode=dlopenmode|RTLD_GLOBAL;
+    3264             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_GLOBAL");
+    3265             :     }
+    3266             : #ifdef RTLD_DEEPBIND
+    3267             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    3268             :     if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) {
+    3269             :       dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    3270             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_DEEPBIND");
+    3271             :     }
+    3272             : #endif
+    3273             : #endif
+    3274             :     if(debug) __PLUMED_FPRINTF(stderr," +++\n");
+    3275             :     p=plumed_attempt_dlopen(path,dlopenmode);
+    3276             :     if(p) plumed_search_symbols(p,&g,plumed_symbol_table_ptr);
+    3277             :   }
+    3278             :   if(handle) *handle=p;
+    3279             :   if(functions) *functions=g;
+    3280             : #endif
+    3281      378688 : }
+    3282             : __PLUMED_WRAPPER_INTERNALS_END
+    3283             : 
+    3284             : /**
+    3285             :   Implementation.
+    3286             :   Small object used to store pointers directly into the plumed object defined in Plumed.h.
+    3287             :   This allows avoiding the extra function call to plumed_retrieve_functions at every cmd,
+    3288             :   at the cost of an extra indirection.
+    3289             : */
+    3290             : typedef struct {
+    3291             :   /* allows errors with pointers to be found when debugging */
+    3292             :   char magic[6];
+    3293             :   /* reference count */
+    3294             :   int refcount;
+    3295             :   /* handler to dlopened library. NULL if there was no library opened */
+    3296             :   void* dlhandle;
+    3297             :   /* non zero if, upon destruction, the library should be dlclosed */
+    3298             :   int dlclose;
+    3299             :   /* 1 if path to kernel was taken from PLUMED_KERNEL var, 0 otherwise */
+    3300             :   int used_plumed_kernel;
+    3301             :   /* function pointers */
+    3302             :   plumed_plumedmain_function_holder functions;
+    3303             :   /* pointer to the symbol table. NULL if kernel <=2.4 */
+    3304             :   plumed_symbol_table_type* table;
+    3305             :   /* pointer to plumed object */
+    3306             :   void* p;
+    3307             : } plumed_implementation;
+    3308             : 
+    3309             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3310      390273 : plumed_implementation* plumed_malloc_pimpl() {
+    3311             :   plumed_implementation* pimpl;
+    3312             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3313      390273 :   pimpl=(plumed_implementation*) __PLUMED_MALLOC(sizeof(plumed_implementation));
+    3314      390273 :   if(!pimpl) {
+    3315           0 :     __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    3316           0 :     __PLUMED_WRAPPER_STD abort();
+    3317             :   }
+    3318      390273 :   __PLUMED_WRAPPER_STD memcpy(pimpl->magic,"pLuMEd",6);
+    3319      390273 :   pimpl->refcount=1;
+    3320             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3321             :   __PLUMED_FPRINTF(stderr,"refcount: new at %p\n",(void*)pimpl);
+    3322             : #endif
+    3323      390273 :   pimpl->dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3324      390273 :   pimpl->dlclose=0;
+    3325      390273 :   pimpl->used_plumed_kernel=0;
+    3326      390273 :   pimpl->functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3327      390273 :   pimpl->functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3328      390273 :   pimpl->functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3329      390273 :   pimpl->table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3330      390273 :   pimpl->p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3331      390273 :   return pimpl;
+    3332             : }
+    3333             : __PLUMED_WRAPPER_INTERNALS_END
+    3334             : 
+    3335             : #ifndef NDEBUG
+    3336             : 
+    3337             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3338             : int plumed_check_pimpl(plumed_implementation*pimpl) {
+    3339             :   if(!pimpl) return 0;
+    3340             :   if(__PLUMED_WRAPPER_STD memcmp(pimpl->magic,"pLuMEd",6)) return 0;
+    3341             :   return 1;
+    3342             : }
+    3343             : __PLUMED_WRAPPER_INTERNALS_END
+    3344             : #endif
+    3345             : 
+    3346             : /* C wrappers: */
+    3347             : 
+    3348             : __PLUMED_WRAPPER_C_BEGIN
+    3349      389155 : plumed plumed_create(void) {
+    3350             :   /* returned object */
+    3351             :   plumed p;
+    3352             :   /* pointer to implementation */
+    3353             :   plumed_implementation* pimpl;
+    3354             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3355      389155 :   pimpl=plumed_malloc_pimpl();
+    3356             :   /* store pointers in pimpl */
+    3357      374134 :   plumed_retrieve_functions(&pimpl->functions,&pimpl->table,&pimpl->dlhandle);
+    3358             : #if __PLUMED_WRAPPER_LINK_RUNTIME
+    3359             :   /* note if PLUMED_KERNEL variable was used */
+    3360             :   pimpl->used_plumed_kernel=1;
+    3361             : #endif
+    3362             :   /* note if handle should not be dlclosed */
+    3363      368133 :   pimpl->dlclose=1;
+    3364      368133 :   if(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE"),"no")) pimpl->dlclose=0;
+    3365             :   /* in case of failure, return */
+    3366             :   /* the resulting object should be plumed_finalized, though you cannot use plumed_cmd */
+    3367      400168 :   if(!pimpl->functions.create) {
+    3368             :     /* store pimpl in returned object */
+    3369             :     p.p=pimpl;
+    3370           0 :     return p;
+    3371             :   }
+    3372             :   assert(pimpl->functions.cmd);
+    3373             :   assert(pimpl->functions.finalize);
+    3374             :   /* obtain object */
+    3375      400168 :   pimpl->p=(*(pimpl->functions.create))();
+    3376             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    3377             :   /* user might identify this using plumed_valid() */
+    3378             :   /* store pimpl in returned object */
+    3379             :   p.p=pimpl;
+    3380      393257 :   return p;
+    3381             : }
+    3382             : __PLUMED_WRAPPER_C_END
+    3383             : 
+    3384             : __PLUMED_WRAPPER_C_BEGIN
+    3385           9 : plumed plumed_create_dlopen(const char*path) {
+    3386             :   int dlopenmode;
+    3387             :   /* plumed_create_dlopen always uses RTLD_LOCAL and, when possible, RTLD_DEEPBIND to allow multiple versions */
+    3388             : #ifdef __PLUMED_HAS_DLOPEN
+    3389             :   dlopenmode=RTLD_NOW|RTLD_LOCAL;
+    3390             : #ifdef RTLD_DEEPBIND
+    3391             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    3392           9 :   if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    3393             : #endif
+    3394             : #endif
+    3395             : #else
+    3396             :   dlopenmode=0;
+    3397             : #endif
+    3398           9 :   return plumed_create_dlopen2(path,dlopenmode);
+    3399             : }
+    3400             : __PLUMED_WRAPPER_C_END
+    3401             : 
+    3402             : __PLUMED_WRAPPER_C_BEGIN
+    3403           9 : plumed plumed_create_dlsym(void* dlhandle) {
+    3404             :   /* returned object */
+    3405             :   plumed p;
+    3406             :   /* pointer to implementation */
+    3407             :   plumed_implementation* pimpl;
+    3408             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3409           9 :   pimpl=plumed_malloc_pimpl();
+    3410             : #ifdef __PLUMED_HAS_DLOPEN
+    3411           9 :   pimpl->dlhandle=dlhandle;
+    3412           9 :   plumed_search_symbols(pimpl->dlhandle,&pimpl->functions,&pimpl->table);
+    3413             : #endif
+    3414           9 :   if(!pimpl->functions.create) {
+    3415             :     p.p=pimpl;
+    3416           0 :     return p;
+    3417             :   }
+    3418             :   assert(pimpl->functions.cmd);
+    3419             :   assert(pimpl->functions.finalize);
+    3420             :   /* obtain object */
+    3421           9 :   pimpl->p=(*(pimpl->functions.create))();
+    3422             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    3423             :   /* user might identify this using plumed_valid() */
+    3424             :   /* store pimpl in returned object */
+    3425             :   p.p=pimpl;
+    3426           9 :   return p;
+    3427             : }
+    3428             : __PLUMED_WRAPPER_C_END
+    3429             : 
+    3430             : __PLUMED_WRAPPER_C_BEGIN
+    3431           9 : plumed plumed_create_dlopen2(const char*path,int mode) {
+    3432             : #ifdef __PLUMED_HAS_DLOPEN
+    3433             :   /* returned object */
+    3434             :   plumed p;
+    3435             :   /* pointer to implementation */
+    3436             :   plumed_implementation* pimpl;
+    3437             :   /* handler */
+    3438             :   void* dlhandle;
+    3439             :   dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3440           9 :   if(path) dlhandle=plumed_attempt_dlopen(path,mode);
+    3441             :   /* a NULL handle implies the file could not be loaded */
+    3442           9 :   if(dlhandle) {
+    3443           9 :     p=plumed_create_dlsym(dlhandle);
+    3444             :     /* obtain pimpl */
+    3445           9 :     pimpl=(plumed_implementation*) p.p;
+    3446             :     /* make sure the handler is closed when plumed is finalized */
+    3447           9 :     pimpl->dlclose=1;
+    3448           9 :     return p;
+    3449             :   }
+    3450             : #else
+    3451             :   (void) path;
+    3452             :   (void) mode;
+    3453             : #endif
+    3454           0 :   return plumed_create_invalid();
+    3455             : }
+    3456             : __PLUMED_WRAPPER_C_END
+    3457             : 
+    3458             : __PLUMED_WRAPPER_C_BEGIN
+    3459          78 : plumed plumed_create_reference(plumed p) {
+    3460             :   plumed_implementation* pimpl;
+    3461             :   /* obtain pimpl */
+    3462          78 :   pimpl=(plumed_implementation*) p.p;
+    3463             :   assert(plumed_check_pimpl(pimpl));
+    3464             :   /* increase reference count */
+    3465         300 :   pimpl->refcount++;
+    3466             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3467             :   __PLUMED_FPRINTF(stderr,"refcount: increase at %p\n",(void*)pimpl);
+    3468             : #endif
+    3469          78 :   return p;
+    3470             : }
+    3471             : __PLUMED_WRAPPER_C_END
+    3472             : 
+    3473             : __PLUMED_WRAPPER_C_BEGIN
+    3474           2 : plumed plumed_create_reference_v(void*v) {
+    3475           2 :   return plumed_create_reference(plumed_v2c(v));
+    3476             : }
+    3477             : __PLUMED_WRAPPER_C_END
+    3478             : 
+    3479             : __PLUMED_WRAPPER_C_BEGIN
+    3480           8 : plumed plumed_create_reference_f(const char*f) {
+    3481           8 :   return plumed_create_reference(plumed_f2c(f));
+    3482             : }
+    3483             : __PLUMED_WRAPPER_C_END
+    3484             : 
+    3485             : __PLUMED_WRAPPER_C_BEGIN
+    3486           2 : plumed plumed_create_invalid() {
+    3487             :   plumed p;
+    3488             :   plumed_implementation* pimpl;
+    3489           2 :   pimpl=plumed_malloc_pimpl();
+    3490             :   p.p=pimpl;
+    3491           2 :   return p;
+    3492             : }
+    3493             : __PLUMED_WRAPPER_C_END
+    3494             : 
+    3495             : __PLUMED_WRAPPER_C_BEGIN
+    3496         357 : void plumed_cmd(plumed p,const char*key,const void*val) {
+    3497             :   plumed_implementation* pimpl;
+    3498             :   /* obtain pimpl */
+    3499         357 :   pimpl=(plumed_implementation*) p.p;
+    3500             :   assert(plumed_check_pimpl(pimpl));
+    3501         357 :   if(!pimpl->p) {
+    3502           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    3503           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    3504           0 :     __PLUMED_WRAPPER_STD exit(1);
+    3505             :   }
+    3506             :   assert(pimpl->functions.create);
+    3507             :   assert(pimpl->functions.cmd);
+    3508             :   assert(pimpl->functions.finalize);
+    3509             :   /* execute */
+    3510         357 :   (*(pimpl->functions.cmd))(pimpl->p,key,val);
+    3511         357 : }
+    3512             : __PLUMED_WRAPPER_C_END
+    3513             : 
+    3514             : __PLUMED_WRAPPER_C_BEGIN
+    3515       12003 : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr safe,plumed_nothrow_handler nothrow) {
+    3516             :   plumed_implementation* pimpl;
+    3517             :   /* This is to allow caller to use a null handler to imply that handling is not done */
+    3518       12003 :   if(!nothrow.handler) {
+    3519          36 :     plumed_cmd_safe(p,key,safe);
+    3520          36 :     return;
+    3521             :   }
+    3522             :   /* obtain pimpl */
+    3523       11967 :   pimpl=(plumed_implementation*) p.p;
+    3524             :   assert(plumed_check_pimpl(pimpl));
+    3525       11967 :   if(!pimpl->p) {
+    3526           0 :     if(pimpl->used_plumed_kernel) {
+    3527           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);
+    3528             :     } else {
+    3529           0 :       nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.",__PLUMED_WRAPPER_CXX_NULLPTR);
+    3530             :     }
+    3531           0 :     return;
+    3532             :   }
+    3533             :   assert(pimpl->functions.create);
+    3534             :   assert(pimpl->functions.cmd);
+    3535             :   assert(pimpl->functions.finalize);
+    3536             :   /* execute */
+    3537       11967 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe_nothrow))(pimpl->p,key,safe,nothrow);
+    3538           0 :   else if(pimpl->table && pimpl->table->version>1) (*(pimpl->table->cmd_nothrow))(pimpl->p,key,safe.ptr,nothrow);
+    3539           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    3540             : }
+    3541             : __PLUMED_WRAPPER_C_END
+    3542             : 
+    3543             : __PLUMED_WRAPPER_C_BEGIN
+    3544           0 : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow) {
+    3545             :   plumed_safeptr safe;
+    3546           0 :   safe.ptr=val;
+    3547           0 :   safe.flags=0;
+    3548           0 :   safe.nelem=0;
+    3549           0 :   safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3550           0 :   safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3551           0 :   plumed_cmd_safe_nothrow(p,key,safe,nothrow);
+    3552           0 : }
+    3553             : __PLUMED_WRAPPER_C_END
+    3554             : 
+    3555             : __PLUMED_WRAPPER_C_BEGIN
+    3556          93 : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr safe) {
+    3557             :   plumed_implementation* pimpl;
+    3558             :   /* obtain pimpl */
+    3559          93 :   pimpl=(plumed_implementation*) p.p;
+    3560             :   assert(plumed_check_pimpl(pimpl));
+    3561          93 :   if(!pimpl->p) {
+    3562           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    3563           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    3564           0 :     __PLUMED_WRAPPER_STD exit(1);
+    3565             :   }
+    3566             :   assert(pimpl->functions.create);
+    3567             :   assert(pimpl->functions.cmd);
+    3568             :   assert(pimpl->functions.finalize);
+    3569             :   /* execute */
+    3570          93 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe))(pimpl->p,key,safe);
+    3571           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    3572          93 : }
+    3573             : __PLUMED_WRAPPER_C_END
+    3574             : 
+    3575             : 
+    3576             : __PLUMED_WRAPPER_C_BEGIN
+    3577      388525 : void plumed_finalize(plumed p) {
+    3578             :   plumed_implementation* pimpl;
+    3579             :   /* obtain pimpl */
+    3580      388525 :   pimpl=(plumed_implementation*) p.p;
+    3581             :   assert(plumed_check_pimpl(pimpl));
+    3582             :   /* decrease reference count */
+    3583      388525 :   pimpl->refcount--;
+    3584             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3585             :   __PLUMED_FPRINTF(stderr,"refcount: decrease at %p\n",(void*)pimpl);
+    3586             : #endif
+    3587      388525 :   if(pimpl->refcount>0) return;
+    3588             :   /* to allow finalizing an invalid plumed object, we only call
+    3589             :      finalize if the object is valid */
+    3590      388225 :   if(pimpl->p) {
+    3591             :     assert(pimpl->functions.create);
+    3592             :     assert(pimpl->functions.cmd);
+    3593             :     assert(pimpl->functions.finalize);
+    3594             :     /* finalize */
+    3595      388223 :     (*(pimpl->functions.finalize))(pimpl->p);
+    3596             :   }
+    3597             : #ifdef __PLUMED_HAS_DLOPEN
+    3598             :   /* dlclose library */
+    3599      394040 :   if(pimpl->dlhandle && pimpl->dlclose) {
+    3600           9 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) __PLUMED_FPRINTF(stderr,"+++ Unloading library\n");
+    3601           9 :     dlclose(pimpl->dlhandle);
+    3602             :   }
+    3603             : #endif
+    3604             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3605             :   __PLUMED_FPRINTF(stderr,"refcount: delete at %p\n",(void*)pimpl);
+    3606             : #endif
+    3607             :   /* free pimpl space */
+    3608      394040 :   __PLUMED_FREE(pimpl);
+    3609             : }
+    3610             : __PLUMED_WRAPPER_C_END
+    3611             : 
+    3612             : __PLUMED_WRAPPER_C_BEGIN
+    3613          23 : int plumed_valid(plumed p) {
+    3614             :   plumed_implementation* pimpl;
+    3615             :   /* obtain pimpl */
+    3616          23 :   pimpl=(plumed_implementation*) p.p;
+    3617             :   assert(plumed_check_pimpl(pimpl));
+    3618          24 :   if(pimpl->p) return 1;
+    3619           2 :   else return 0;
+    3620             : }
+    3621             : __PLUMED_WRAPPER_C_END
+    3622             : 
+    3623             : __PLUMED_WRAPPER_C_BEGIN
+    3624          42 : int plumed_use_count(plumed p) {
+    3625             :   plumed_implementation* pimpl;
+    3626             :   /* obtain pimpl */
+    3627          42 :   pimpl=(plumed_implementation*) p.p;
+    3628             :   assert(plumed_check_pimpl(pimpl));
+    3629          42 :   return pimpl->refcount;
+    3630             : }
+    3631             : __PLUMED_WRAPPER_C_END
+    3632             : 
+    3633             : __PLUMED_WRAPPER_C_BEGIN
+    3634           9 : int plumed_installed(void) {
+    3635             :   plumed p;
+    3636             :   int result;
+    3637           9 :   p=plumed_create();
+    3638           9 :   result=plumed_valid(p);
+    3639           9 :   plumed_finalize(p);
+    3640           9 :   return result;
+    3641             : }
+    3642             : __PLUMED_WRAPPER_C_END
+    3643             : 
+    3644             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    3645             : 
+    3646             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3647             : 
+    3648             : /* we declare a Plumed_g_main object here, in such a way that it is always available */
+    3649             : 
+    3650             : static plumed plumed_gmain= {__PLUMED_WRAPPER_CXX_NULLPTR};
+    3651             : 
+    3652          41 : plumed plumed_global(void) {
+    3653          41 :   return plumed_gmain;
+    3654             : }
+    3655             : 
+    3656          22 : void plumed_gcreate(void) {
+    3657             :   /* should be created once */
+    3658             :   assert(plumed_gmain.p==__PLUMED_WRAPPER_CXX_NULLPTR);
+    3659          22 :   plumed_gmain=plumed_create();
+    3660          22 : }
+    3661             : 
+    3662          78 : void plumed_gcmd(const char*key,const void*val) {
+    3663          78 :   plumed_cmd(plumed_gmain,key,val);
+    3664          78 : }
+    3665             : 
+    3666             : /* cppcheck-suppress passedByValue */
+    3667           0 : void plumed_gcmd_safe(const char*key,plumed_safeptr safe) {
+    3668           0 :   plumed_cmd_safe(plumed_gmain,key,safe);
+    3669           0 : }
+    3670             : 
+    3671          22 : void plumed_gfinalize(void) {
+    3672          22 :   plumed_finalize(plumed_gmain);
+    3673          22 :   plumed_gmain.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3674          22 : }
+    3675             : 
+    3676          24 : int plumed_ginitialized(void) {
+    3677          24 :   if(plumed_gmain.p) return 1;
+    3678          16 :   else        return 0;
+    3679             : }
+    3680             : 
+    3681           8 : int plumed_gvalid() {
+    3682             :   assert(plumed_gmain.p);
+    3683           8 :   return plumed_valid(plumed_gmain);
+    3684             : }
+    3685             : 
+    3686             : __PLUMED_WRAPPER_EXTERN_C_END
+    3687             : 
+    3688             : #endif /*}*/
+    3689             : 
+    3690             : __PLUMED_WRAPPER_C_BEGIN
+    3691          56 : void plumed_c2f(plumed p,char*c) {
+    3692             :   unsigned i;
+    3693             :   unsigned char* cc;
+    3694             :   /*
+    3695             :     Convert the address stored in p.p into a proper FORTRAN string
+    3696             :     made of only ASCII characters. For this to work, the two following
+    3697             :     assertions should be satisfied:
+    3698             :   */
+    3699             :   assert(CHAR_BIT<=12);
+    3700             :   assert(sizeof(p.p)<=16);
+    3701             : 
+    3702             :   assert(c);
+    3703             :   cc=(unsigned char*)&p.p;
+    3704         504 :   for(i=0; i<sizeof(p.p); i++) {
+    3705             :     /*
+    3706             :       characters will range between '0' (ASCII 48) and 'o' (ASCII 111=48+63)
+    3707             :     */
+    3708             :     /* cppcheck-suppress objectIndex */
+    3709         448 :     c[2*i]=cc[i]/64+48;
+    3710             :     /* cppcheck-suppress objectIndex */
+    3711         448 :     c[2*i+1]=cc[i]%64+48;
+    3712             :   }
+    3713         504 :   for(; i<16; i++) {
+    3714         448 :     c[2*i]=' ';
+    3715         448 :     c[2*i+1]=' ';
+    3716             :   }
+    3717          56 : }
+    3718             : __PLUMED_WRAPPER_C_END
+    3719             : 
+    3720             : __PLUMED_WRAPPER_C_BEGIN
+    3721         373 : plumed plumed_f2c(const char*c) {
+    3722             :   plumed p;
+    3723             :   unsigned i;
+    3724             :   unsigned char* cc;
+    3725             : 
+    3726             :   assert(CHAR_BIT<=12);
+    3727             :   assert(sizeof(p.p)<=16);
+    3728             : 
+    3729             :   assert(c);
+    3730             : 
+    3731             :   /*
+    3732             :      needed to avoid cppcheck warning on uninitialized p
+    3733             :   */
+    3734         373 :   p.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3735             :   cc=(unsigned char*)&p.p;
+    3736        3357 :   for(i=0; i<sizeof(p.p); i++) {
+    3737             :     assert(c[2*i]>=48 && c[2*i]<48+64);
+    3738             :     assert(c[2*i+1]>=48 && c[2*i+1]<48+64);
+    3739             :     /*
+    3740             :       perform the reversed transform
+    3741             :     */
+    3742             :     /* cppcheck-suppress objectIndex */
+    3743        2984 :     cc[i]=(c[2*i]-48)*64 + (c[2*i+1]-48);
+    3744             :   }
+    3745        3357 :   for(; i<16; i++) {
+    3746             :     assert(c[2*i]==' ');
+    3747             :     assert(c[2*i+1]==' ');
+    3748             :   }
+    3749         373 :   return p;
+    3750             : }
+    3751             : __PLUMED_WRAPPER_C_END
+    3752             : 
+    3753             : __PLUMED_WRAPPER_C_BEGIN
+    3754           2 : void* plumed_c2v(plumed p) {
+    3755             :   assert(plumed_check_pimpl((plumed_implementation*)p.p));
+    3756           2 :   return p.p;
+    3757             : }
+    3758             : __PLUMED_WRAPPER_C_END
+    3759             : 
+    3760             : __PLUMED_WRAPPER_C_BEGIN
+    3761           2 : plumed plumed_v2c(void* v) {
+    3762             :   assert(plumed_check_pimpl((plumed_implementation*)v));
+    3763             :   plumed p;
+    3764             :   p.p=v;
+    3765           2 :   return p;
+    3766             : }
+    3767             : __PLUMED_WRAPPER_C_END
+    3768             : 
+    3769             : #if __PLUMED_WRAPPER_FORTRAN /*{*/
+    3770             : 
+    3771             : /*
+    3772             :   Fortran wrappers
+    3773             :   These are just like the global C wrappers. They are
+    3774             :   just defined here and not declared since they
+    3775             :   should not be used from c/c++ anyway.
+    3776             : 
+    3777             :   We use a macro that does the following:
+    3778             :   - declare a static function named NAME_static
+    3779             :   - declare a number of functions named NAME_ etc, with all possible
+    3780             :     fortran mangling schemes (zero, one, or two underscores, lower and upper case)
+    3781             :   - define the NAME_static function.
+    3782             : 
+    3783             :   The static function is used basically as an inline function in a C-compatible manner.
+    3784             : */
+    3785             : 
+    3786             : #define __PLUMED_IMPLEMENT_FORTRAN(lower,upper,arg1,arg2) \
+    3787             :   static void lower ## _static arg1; \
+    3788             :   extern void lower      arg1 {lower ## _static arg2;} \
+    3789             :   extern void lower ##_  arg1 {lower ## _static arg2;} \
+    3790             :   extern void lower ##__ arg1 {lower ## _static arg2;} \
+    3791             :   extern void upper      arg1 {lower ## _static arg2;} \
+    3792             :   extern void upper ##_  arg1 {lower ## _static arg2;} \
+    3793             :   extern void upper ##__ arg1 {lower ## _static arg2;} \
+    3794             :   static void lower ## _static arg1
+    3795             : 
+    3796             : /* FORTRAN wrappers would only make sense as extern "C" */
+    3797             : 
+    3798             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3799             : 
+    3800          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create,PLUMED_F_CREATE,(char*c),(c)) {
+    3801          18 :   plumed_c2f(plumed_create(),c);
+    3802          18 : }
+    3803             : 
+    3804          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_dlopen,PLUMED_F_CREATE_DLOPEN,(char*path,char*c),(path,c)) {
+    3805           6 :   plumed_c2f(plumed_create_dlopen(path),c);
+    3806           6 : }
+    3807             : 
+    3808          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_reference,PLUMED_F_CREATE_REFERENCE,(char* r,char*c),(r,c)) {
+    3809           6 :   plumed_c2f(plumed_create_reference_f(r),c);
+    3810           6 : }
+    3811             : 
+    3812           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_invalid,PLUMED_F_CREATE_INVALID,(char* c),(c)) {
+    3813           0 :   plumed_c2f(plumed_create_invalid(),c);
+    3814           0 : }
+    3815             : 
+    3816         558 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_cmd,PLUMED_F_CMD,(char*c,char*key,void*val),(c,key,val)) {
+    3817         279 :   plumed_cmd(plumed_f2c(c),key,val);
+    3818         279 : }
+    3819             : 
+    3820          60 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_finalize,PLUMED_F_FINALIZE,(char*c),(c)) {
+    3821          30 :   plumed_finalize(plumed_f2c(c));
+    3822          30 : }
+    3823             : 
+    3824          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_installed,PLUMED_F_INSTALLED,(int*i),(i)) {
+    3825             :   assert(i);
+    3826           6 :   *i=plumed_installed();
+    3827           6 : }
+    3828             : 
+    3829             : /* New in PLUMED 2.5 */
+    3830           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_valid,PLUMED_F_VALID,(char*c,int*i),(c,i)) {
+    3831             :   assert(i);
+    3832           0 :   *i=plumed_valid(plumed_f2c(c));
+    3833           0 : }
+    3834             : 
+    3835          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_use_count,PLUMED_F_USE_COUNT,(char*c,int*i),(c,i)) {
+    3836             :   assert(i);
+    3837          18 :   *i=plumed_use_count(plumed_f2c(c));
+    3838          18 : }
+    3839             : 
+    3840             : /* New in PLUMED 2.8 */
+    3841             : 
+    3842             : /* note: flags & (~0x1ffffff) removes bits that are set here (code and size) */
+    3843             : 
+    3844             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,suffix) \
+    3845             : 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) {\
+    3846             :   plumed_safeptr safe; \
+    3847             :   safe.ptr=val; \
+    3848             :   safe.nelem=nelem; \
+    3849             :   safe.shape=shape; \
+    3850             :   safe.flags= (flags & (~0x1ffffff)) + 0x10000*code + size; \
+    3851             :   safe.opt=opt; \
+    3852             :   return safe; \
+    3853             : }
+    3854             : 
+    3855             : #define __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,size,code) \
+    3856             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,) \
+    3857             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,_scalar)
+    3858             : 
+    3859             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(type,type_,code) \
+    3860             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,0,code)
+    3861             : 
+    3862             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(type,type_,code) \
+    3863             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,sizeof(type),code)
+    3864             : 
+    3865          24 : __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(void,ptr,0)
+    3866           1 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(float,float,4)
+    3867          19 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(double,double,4)
+    3868           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long double,long_double,4)
+    3869          18 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(int,int,3)
+    3870           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(short,short,3)
+    3871           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long,long,3)
+    3872          18 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(char,char,3)
+    3873             : 
+    3874             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    3875             : 
+    3876          48 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_global,PLUMED_F_GLOBAL,(char*c),(c)) {
+    3877          24 :   plumed_c2f(plumed_gmain,c);
+    3878          24 : }
+    3879             : 
+    3880          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_ginitialized,PLUMED_F_GINITIALIZED,(int*i),(i)) {
+    3881             :   assert(i);
+    3882          18 :   *i=plumed_ginitialized();
+    3883          18 : }
+    3884             : 
+    3885          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcreate,PLUMED_F_GCREATE,(void),()) {
+    3886          14 :   plumed_gcreate();
+    3887          14 : }
+    3888             : 
+    3889         156 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcmd,PLUMED_F_GCMD,(char*key,void*val),(key,val)) {
+    3890          78 :   plumed_gcmd(key,val);
+    3891          78 : }
+    3892             : 
+    3893          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gfinalize,PLUMED_F_GFINALIZE,(void),()) {
+    3894          14 :   plumed_gfinalize();
+    3895          14 : }
+    3896             : 
+    3897             : /* New in PLUMED 2.5 */
+    3898          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gvalid,PLUMED_F_GVALID,(int*i),(i)) {
+    3899             :   assert(i);
+    3900           6 :   *i=plumed_gvalid();
+    3901           6 : }
+    3902             : 
+    3903             : #endif /*}*/
+    3904             : 
+    3905             : __PLUMED_WRAPPER_EXTERN_C_END
+    3906             : 
+    3907             : #endif /*}*/
+    3908             : 
+    3909             : #endif /*}*/
+    3910             : 
+    3911             : #endif /*}*/
+    3912             : 
+    3913             : /* END OF DEFINITIONS */
+    3914             : 
+    3915             : /* reset variable to allow it to be redefined upon re-inclusion */
+    3916             : 
+    3917             : #undef __PLUMED_WRAPPER_IMPLEMENTATION_
+    3918             : 
+    3919             : /* this macro is set in declarations */
+    3920             : #ifdef __PLUMED_WRAPPER_REDEFINE_CMD
+    3921             : #if defined(plumed_cmd)
+    3922             : #undef plumed_cmd
+    3923             : #endif
+    3924             : #define plumed_cmd __PLUMED_WRAPPER_REDEFINE_CMD
+    3925             : #endif
+    3926             : 
+    3927             : /* this macro is set in declarations */
+    3928             : #ifdef __PLUMED_WRAPPER_REDEFINE_GCMD
+    3929             : #if defined(plumed_gcmd)
+    3930             : #undef plumed_gcmd
+    3931             : #endif
+    3932             : #define plumed_gcmd __PLUMED_WRAPPER_REDEFINE_GCMD
+    3933             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/wrapper/index-sort-f.html b/coverage/wrapper/index-sort-f.html new file mode 100644 index 0000000000..adbeb71488 --- /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:23643853.9 %
Date:2024-06-10 08:19:14Functions:14222762.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
53.9%53.9%
+
53.9 %236 / 43862.6 %142 / 227
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/wrapper/index-sort-l.html b/coverage/wrapper/index-sort-l.html new file mode 100644 index 0000000000..cbf99cea27 --- /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:23643853.9 %
Date:2024-06-10 08:19:14Functions:14222762.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
53.9%53.9%
+
53.9 %236 / 43862.6 %142 / 227
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/coverage/wrapper/index.html b/coverage/wrapper/index.html new file mode 100644 index 0000000000..75b27eee49 --- /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:23643853.9 %
Date:2024-06-10 08:19:14Functions:14222762.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
53.9%53.9%
+
53.9 %236 / 43862.6 %142 / 227
+
+
+ + + + +
Generated by: LCOV version 1.15
+
+ + + diff --git a/index.html b/index.html new file mode 100644 index 0000000000..cc4afdd80d --- /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. + +